关于AT24c02d的连续读写问题 查了很多资料 原理也弄明白了 也按照原理写了个程序 可是输出的结果一点都不靠谱 还请各位帮忙看一下 问题出在什么地方 明白的人 一看就知道 程序很简单 #include<reg52.h> #include<intrins.h> #define uchar unsigned char sbit SDA=P2^0; sbit SCL=P2^1; sbit dula = P2^6; sbit wela = P2^7; sbit key = P3^4; uchar code table[16] = { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; uchar shuju[8]; uchar num,time; void delayms(unsigned int i){ unsigned char j; for(; i > 0; i--) for(j = 110; j > 0; j--) ; } void show(){//显示time变量 分别是百十个位 dula = 1; P0 = table[time / 100]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfe; wela = 0; delayms(5); dula = 1; P0 = table[time / 10 % 10]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfd; wela = 0; delayms(5); dula = 1; P0 = table[time % 10]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfb; wela = 0; delayms(5); } void IIC_init(){//初始化 SCL = 1; _nop_(); SDA = 1; _nop_(); } void IIC_start(){//开始 SDA = 1; _nop_(); SCL = 1; _nop_(); SDA = 0; _nop_(); } void IIC_ask(){//应答 uchar i; SCL = 1; _nop_(); while((SDA == 1) && (i < 255)) i++; SCL = 0; _nop_(); } void IIC_stop(){//停止 SDA = 0; _nop_(); SCL = 1; _nop_(); SDA = 1; _nop_(); } void IIC_write(uchar date){ uchar temp,i; temp = date; for(i = 0; i < 8; i++){ temp = temp << 1; SCL = 0; _nop_(); SDA = CY; _nop_(); SCL = 1; _nop_(); } SCL = 0; _nop_(); SDA = 1; _nop_(); } unsigned char IIC_read(){ uchar i,date; SCL = 0; _nop_(); SDA = 1; _nop_(); for(i = 0; i < 8; i++){ SCL = 1; _nop_(); date = (date<<1)|SDA; SCL = 0; _nop_(); } _nop_(); return date; } void At24c02_write(uchar address){//连续写 uchar i; IIC_start(); IIC_write(0xa0); IIC_ask(); IIC_write(address); IIC_ask(); for(i = 0; i < 8; i++){ IIC_write(i); IIC_ask(); } IIC_stop(); } void At24c02_read(uchar address){//连续读 uchar i; IIC_start(); IIC_write(0xa0); IIC_ask(); IIC_write(address); IIC_ask(); delayms(100); IIC_start(); IIC_write(0xa1); IIC_ask(); for(i = 0; i < 8; i++){//从地址依次读取8个数据 shuju[i] = IIC_read(); IIC_ask(); } IIC_stop(); } void main(){ uchar i; IIC_init(); At24c02_write(2); delayms(100); At24c02_read(2); for(i = 0; i < 8; i++){ time = shuju[i]; show(); while(key)//按下按钮继续显示下一个数据 ; delayms(10); while(!key) ; } while(1) ; }
简单明了 多余的部分全部删除了 我搞不明白 shuju[i]读完数据之后分别是0,255,255,255,255,255,255,255 难道是写函数错了? 检查之后也没问题啊 1. 写操作之后,需要延时,或者启用查询总线是否空闲,空闲后,才能继续操作。
2. 速度不能太快,适当降低波特率,可以增强代码稳定性。但是牺牲了时间。
3. 查看你的硬件电路。示波器观察SCL SDA是否波形正常。 注意上拉店组不能太大,一般2K2即可。
1. 最好有一个示波器, 如果没钱, 可以在淘宝卖个逻辑分析仪, 在100~200元之间, 这样调试起来更直观和效率. 2. 我搞不明白 shuju[i]读完数据之后分别是0,255,255,255,255,255,255,255, 多半还是iic时序不满足造成的. 应该就是这个ACK的问题
IIC协议中有一个等待从机应答,你这里没有 电路有没,最好贴上电路,确定不是硬件的问题,然后再查找软件,这种IIC没有什么难度的,只要按手册上时序来写一般不会有太大问题,但是新手很容易忽略的一个问题就是24C02的读写速度,时序图上有,记得是5个NS吧,看看你用的单片机速度多快,延时合适。 如果觉得时延有问题的话,把线速成率调到很底,看能不能成功。可以的话,则逻辑没错,时延出错。
|