最近在做一个点阵屏的项目,其中用到了储存芯片20c08,当找资料时时发现全网都是24c02的读写例程然后程序下进去后发现能用,就没有在意(开始测试的时候数据用的很少不到256个)。

当程序框架基本完成时我开始进行多数测试,突然发现我的程序只能进行0-255的数据存储,当数据超过255时就会重头开始。

后来我从网上找了很多资料发现都是24c02的程序,存储数量都不能超过256。于是经过一天的研究终于解决了这个问题。记录一下,希望能帮助与到同样问题的小伙伴。

第一部分 原理说明

在读写过程中24c0x是分页写的,每页可以存256个字节,网上的驱动程序多为24c02,默认为第一页,当输入大于256时需要加一个换页,以24c08为例,一共有1K字节,每页256,一共为4页,以下为I²C的发送命令格式,前面四个1010是eeprom的固定格式不能动,对应16进制为A;后面四位的前三位数据(P0,P1,P2)就是翻页所需的地址(也可以理解为页地址),第四位R/W为读写控制位,最重要的就是图中的P0,P1,P2数据位,因为24c08只有四页所以只需要两个二进制数据即可(P2位强制为0)

P1  P2值
00 第0页
01 第1页
10 第2页
00 第3页

第二部分 程序编写

我的程序并没有从头开始写,由于我是在24c02的基础上搭好了程序框架才发现的问题,所以我的程序修改宗旨就是:以最少的修改完成读写任务,

下面是我原本的24C02程序

#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit sda = P2 ^ 1;                          //IO口定义
sbit scl = P2 ^ 0;
//此为待写入24c02的数据。为了便于验证结果,数组的内容为周期重复的。
void UART_TX_Send(uchar i);char code music[] = {0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0,0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0
};     //由于最后还要讲这些数据通过串口发送到电脑  波特率9600
uchar data buffer[100]; //用于缓存从24c02中读取的数据。
void delay(unsigned int m)
{unsigned int n, p;for (n = m; n>0; n--)for (p = 125; p>0; p--);
}
void nop()
{_nop_();_nop_();
}
/24C02读写驱动程序
void delay1(unsigned int m)
{unsigned int n;for (n = 0; n<m; n++);
}
void init()  //24c02初始化子程序
{scl = 1;nop();sda = 1;nop();
}
void start()        //启动I2C总线
{sda = 1;nop();scl = 1;nop();sda = 0;nop();scl = 0;nop();
}
void stop()         //停止I2C总线
{sda = 0;nop();scl = 1;nop();sda = 1;nop();
}
void writebyte(unsigned char j)  //写一个字节
{unsigned char i, temp;temp = j;for (i = 0; i<8; i++){temp = temp << 1;scl = 0;nop();sda = CY;        //temp左移时,移出的值放入了CY中nop();scl = 1;        //待sda线上的数据稳定后,将scl拉高nop();}scl = 0;nop();sda = 1;nop();
}
unsigned char readbyte()   //读一个字节
{unsigned char i, j, k = 0;scl = 0; nop(); sda = 1;for (i = 0; i<8; i++){nop(); scl = 1; nop();if (sda == 1)j = 1;elsej = 0;k = (k << 1) | j;scl = 0;}nop();return(k);
}
void clock()         //I2C总线时钟
{unsigned char i = 0;scl = 1;nop();while ((sda == 1) && (i<255))i++;scl = 0;nop();
}
从24c02的地址address中读取一个字节数据/
unsigned char read24c02(unsigned char address)
{unsigned char i;start();writebyte(0xa0);clock();writebyte(address);clock();start();writebyte(0xa1);clock();i = readbyte();stop();delay1(100);return(i);
}
//向24c02的address地址中写入一字节数据info/
void write24c02(unsigned char address, unsigned char info)
{start();writebyte(0xa0);clock();writebyte(address);clock();writebyte(info);clock();stop();delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。
}
//从24c02的地址address中读取一个字节数据///串口初始化
void UARTInit()
{EA  = 1;  //打开总中断ES  = 1; //打开串口中断SM0 = 0;  SM1 = 1;//串口工作方式1,8位UART波特率可变REN = 1;//串口允许接收TR1 = 1;//启动定时器1TMOD |= 0x20;//定时器1,工作模式2 8位自动重装TH1 = 0xfd;TL1 = 0xfd;//设置比特率9600}
//串口发送程序
void UART_TX_Send(uchar i)
{SBUF=i;while(!TI);TI=0;
}
void main()
{uchar add, j;init();        //初始化24C02UARTInit();while (add != sizeof(music)){write24c02(0x05 + add, music[add]);add++;if (add % 4 == 0)P1 = ~P1;}//到此为止,向24C02中写入数据的过程均已结束。下面的程序为附加的。//将已写入的数据再读出,送到串口助手
for (j=0;j<sizeof(music);j++)
{UART_TX_Send(read24c02(0x05+j));delay(50);}
//  while (j != add)
//  {
//
//      UART_TX_Send(read24c02(0x05+j));
//      j++;
//      delay(50);
//  }while (1);
}

经过分析后我仅仅修改了读写函数  以下是修改部分

主函数测试 直接从0xf5开始读写 最后打印的数据正常

这个改法好处是其他部分的程序都不用动,直接往里面扔数据就行大于256也可以。

下面是改好的程序

#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit sda = P2 ^ 1;                          //IO口定义
sbit scl = P2 ^ 0;
//此为待写入24c02的数据。为了便于验证结果,数组的内容为周期重复的。
void UART_TX_Send(uchar i);char code music[] = {0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0,0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0, 0x55, 0xaa, 0x0f, 0xf0
};     //由于最后还要讲这些数据通过串口发送到电脑  波特率9600
uchar data buffer[100]; //用于缓存从24c02中读取的数据。
void delay(unsigned int m)
{unsigned int n, p;for (n = m; n>0; n--)for (p = 125; p>0; p--);
}
void nop()
{_nop_();_nop_();
}
/24C02读写驱动程序
void delay1(unsigned int m)
{unsigned int n;for (n = 0; n<m; n++);
}
void init()  //24c02初始化子程序
{scl = 1;nop();sda = 1;nop();
}
void start()        //启动I2C总线
{sda = 1;nop();scl = 1;nop();sda = 0;nop();scl = 0;nop();
}
void stop()         //停止I2C总线
{sda = 0;nop();scl = 1;nop();sda = 1;nop();
}
void writebyte(unsigned char j)  //写一个字节
{unsigned char i, temp;temp = j;for (i = 0; i<8; i++){temp = temp << 1;scl = 0;nop();sda = CY;        //temp左移时,移出的值放入了CY中nop();scl = 1;        //待sda线上的数据稳定后,将scl拉高nop();}scl = 0;nop();sda = 1;nop();
}
unsigned char readbyte()   //读一个字节
{unsigned char i, j, k = 0;scl = 0; nop(); sda = 1;for (i = 0; i<8; i++){nop(); scl = 1; nop();if (sda == 1)j = 1;elsej = 0;k = (k << 1) | j;scl = 0;}nop();return(k);
}
void clock()         //I2C总线时钟
{unsigned char i = 0;scl = 1;nop();while ((sda == 1) && (i<255))i++;scl = 0;nop();
}
unsigned int read24c02(unsigned int address)
{uchar i,addr;addr=(address/0xff*2); //address 0 1 2 3, addr 0 2 4 6//UART_TX_Send(addr);start();writebyte(0xa0+addr);//选页 写:第1页A0 ,2页A2 ,3页A4,4页A6 clock();writebyte(address%0xff);//写地址0-255clock();start();writebyte(0xa1+addr);///选页 读:第1页A1 ,2页A3 ,3页A4,4页A7 就是写+1clock();i = readbyte();stop();delay1(100);return(i);}
//向24c02的address地址中写入一字节数据info/
void write24c02(unsigned int address, unsigned char info)
{uchar addr;addr=address/0xff*2; //address/0xff= 0 1 2 3, addr= 0 2 4 6start();writebyte(0xa0+addr);//选页 写:第1页A0 ,2页A2 ,3页A4,4页A6 clock();writebyte(address%0xff);//写地址0-255clock();writebyte(info);clock();stop();delay1(5000); //这个延时一定要足够长,否则会出错。因为24c02在从sda上取得数据后,还需要一定时间的烧录过程。
}
//从24c02的地址address中读取一个字节数据///串口初始化
void UARTInit()
{EA  = 1;  //打开总中断ES  = 1; //打开串口中断SM0 = 0;  SM1 = 1;//串口工作方式1,8位UART波特率可变REN = 1;//串口允许接收TR1 = 1;//启动定时器1TMOD |= 0x20;//定时器1,工作模式2 8位自动重装TH1 = 0xfd;TL1 = 0xfd;//设置比特率9600}
//串口发送程序
void UART_TX_Send(uchar i)
{SBUF=i;while(!TI);TI=0;
}
void main()
{uchar add, j;init();        //初始化24C02UARTInit();while (add != sizeof(music)){write24c02(0xf5 + add, music[add]);add++;if (add % 4 == 0)P1 = ~P1;}//到此为止,向24C02中写入数据的过程均已结束。下面的程序为附加的。//将已写入的数据再读出,送到串口助手
for (j=0;j<sizeof(music);j++)
{UART_TX_Send(read24c02(0xf5+j));delay(50);}while (1);
}

24c0x读写 大于256字节读写方式,以24c08为例(24c04/08/16同理)相关推荐

  1. 最近总结了串口(COM)读写操作的三种方式

    最近总结了串口(COM)读写操作的三种方式: 第1种方式是采用微软在.NET2.0推出了一个串口控件,SerialPort类,但必须是.NET2.0才可以 第2种方式是用API写串口通信,虽然难度高, ...

  2. Python文件字节读写

    import osfilename = 'test.txt'#把文件内容以byte字节形式读写到缓冲区中. def read_into_buffer(filename):buf = bytearray ...

  3. Java入门学习第十七天——字节流读写文件、字节缓冲流拷贝文件

    字节流读写文件 字节流拷贝文件-按单个字节读写 FileInputStream:普通的字节输入流,用来读取数据的 构造方法: ​ public FileInputStream(String pathn ...

  4. Qt读写文件(2种方式)实现详解

    文件的读写是很多应用程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处 理而开发的,所以文件读写是应用程序开发的一个基本功能. 文本文件是指以纯文本格式存储的文件,例如用 Qt Creato ...

  5. SDRAM单字节读写仿真测试

    仿真测试的所有文件 modelsim仿真 初始化时序 初始化状态机 去掉多数信号可以看到初始化时序 PRE预充电经过两个周期进入AREF自刷新,自刷新需进行两次,然后进入MREF模式设置,模式设置经过 ...

  6. C++ fstream类移动读写指针和字节数形式获取该指针位置(seekp、seekg、tellg、tellp)

    参考链接 C++移动和获取文件读写指针(seekp.seekg.tellg.tellp) 1.利用seekp.seekg成员函数控制读写指针位置 在读写文件时,有时希望直接跳到文件中的某处开始读写,这 ...

  7. 更改结构体的内存字节对齐方式--经典

    结构体字节对齐 http://blog.163.com/ecy_fu/blog/static/4445126200910603739941/ http://hi.baidu.com/skyland_l ...

  8. C文件操作、读写文件 C++文件读写、文件操作

    转自  飘羽随风 基于C的文件操作  在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之. 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FI ...

  9. c语言读写nfc,Android NFC M1卡读写芯片卡读写(CPU卡读写)(RFID读写)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/sgn5200/article/deta ...

最新文章

  1. npm install出现的错误
  2. springBoot之过滤器和拦截器的使用
  3. 在ThoughtWorks工作两个多月的总结
  4. Python学习:函数
  5. mysql虚拟列(Generated Columns)及JSON字段类型的使用
  6. linux thrift 安装目录,Linux下安装Thrift
  7. iNeuOS工业互联网操作系统,顺利从NetCore3.1升级到Net6的过程汇报,发布3.7版本...
  8. android studio ignore 模板,android studio git ignore
  9. 简单文件传输TFTP服务器搭建 Linux RHEL6
  10. C语言 计算日期是当年的第几天
  11. arduino读取水位传感器的数据显示在基于i2c的1602a上_构建Arduino的LoRa远程智能空气质量监测系统...
  12. python电脑配置-Python--获取电脑配置信息--设计代码
  13. pip在多个python版本中将包安装到制定版本
  14. C语言项目-俄罗斯方块
  15. 游戏必要的清屏实现以及闪烁原因的详细解释
  16. 交换机日志删除_锐捷交换机记录日志到flash功能详解 | 19号系统
  17. 安装时遇到“已终止Autocad2006安装
  18. 店铺DRS评分这样来做|盛天海电商
  19. 苹果cms网站添加TV电视直播教程
  20. Pangu Separates Heaven and Earth(签到题)

热门文章

  1. 论文学习笔记 MUSE: Secure Inference Resilient to Malicious Clients
  2. 计算机网络access code,access code
  3. 大学生数学竞赛(高数篇)
  4. 基于C++的Huffman赫夫曼编译码器开发 课程论文+项目源码及可执行exe文件
  5. omni私链常用命令
  6. Linux如何修改SSH登录密码
  7. Solr--Solr 使用SolrJ 完成添加,删除,查询
  8. 柳岩清晨晒素颜照称拿去辟邪 网友称吓人没认出来
  9. 如何求一个关系模式的候选码
  10. 美团点评广告实时索引的设计与实现