1、单片机用P20和P21和AT24C02通信;
2、比赛提供的开发包里面的代码。
头文件
c文件
提供的代码解读以及修改合适自己使用。
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
看头文件,有6个函数。
开始,停止,等待应答(有个返回值bit),发送应答,发送字节,接收字节。
函数里面的内容不用管。
知道有四个工具就可以了。
修改:
将reg52.h更改为stc15.h,不然有些寄存器会重复定义,编译出错误。
在iic.c里面,有个延时函数的时间,需要修改,不然不能正确读取数据。
把这个delaytime的5改为60,就合适了。或者60左右。因为stc15的速度是传统51单片机的10-12倍。
补充代码。
AT24C02相当于层楼,有许多房间,每个房间放一个字节的内容。
你想往哪个房间放数据?需要进行指定房间号,指定内容。
怎么放,怎么起始,怎么结束,有什么命令,需要结合24c02的数据手册。
写入一个字节数据到AT24C02的指定地址
需要阅读数据手册的地方。
图7,设备地址。
我们的是AT24C02,放的是2K字节。看第一行。
MSB是一个字节的高位,LSB是一个字节的低位。
前面固定了1010,后面A2A1A0和R、W由硬件和软件设定。
A2A1A0看AT24C02的电路图,解了GND,所以是000,
R高电平,代表是读取read有效,低电平是写write有效。
所以有个写地址,和读地址。
写地址是10100001,0xA1,
读地址是10100000,是0xA0和iic.h对应
图8 字节写的流程。
解读一下。
SDA线,
第一个是发送一个开始信号,所以要用开始函数;已经写好了;
IIC_Start()
第二个是设备地址要发出去,设备地址是先发MSB高位数据出去。函数也提供了。
是写地址,就是写地址;发0xA0.
IIC_SendByte(0xA0)
第三个是等待一个ACK,你发数据出去,肯定希望别人应答,所以这里是读取等待应答信号。
IIC_WaitAck();
第四个是写一个字节到哪个位置呢,你要先发一个地址。比如房间号,你要告诉它。
IIC_SendByte(房间号)
注意这个房间号,只能放一个字节内容;房间号范围是0x00-0xFF(好像是,忘记了)
第五个,等待应答。
IIC_WaitAck();
第六个,写数据。
IIC_SendByte(数据)
这个数据是一个字节类型。只能一个个字节发送。
第7个,等待应答。
IIC_WaitAck();
第八个,发停止位。
IIC_Stop();
具体流程,如果不懂阅读,看STCISP软件的一个函数,理解一下,这个是发送一串字节,我们看下流程就好了。
根据上面的流程,我们写出我们的代码,在头文件中,添加函数声明,在c文件中,添加函数的定义。函数有两个形参,地址和数据。
我们通过上面的过程,知道如何写一个字节数据到at24c02中,我们怎么读取at24c02里面的房间的数据呢?看下手册里面的读取数据的流程图。
第一个步骤,发送开始信号。
第二个步骤,发送设备的写地址,注意这里有个写地址。
0xA0.
第三个,等待应答信号;
第四个,发送房间号的地址,意思是,你要读取at24c02哪个房间的数据?你要发给他。
第五个,等待应答,你发出去了额,对方有没有收到,需要等待应答。
第6个,发送设备开始信号;
第7,发送读地址。注意,这里是读地址,0xA1
第8,等待应答;
第9,一位位读取数据,我们需要设置一个变量,接收这个字节的数据。
第10,NOACK,发送一个NO ACK信号给at24c02,代表读完成了。
第11,发送停止信号。
明白了流程,我们参考下,stc-isp软件的代码。参考的代码是读取一串数据,所以有个发送应答ack,我们只需要读取一个字节数据,所以少了一个步骤
再改写成自己的代码。
修改代码
。得到上面的两个代码。我们实际使用一下。
案例测试。
注意,一个个字节写,最好延时一下,这里延时了5ms时间。
在main.c中,添加代码。
往0x00房间号,写入dat0这个字节的数据。
往0x02房间号,写入dat1数据,注意,dat0和dat1是char类型的数据;
注意0x01房间号,也能放数据。
往0x03房间号,写入dat2这个字节的数据。
将0x00房间的数据,读取出来,赋值给rdat0。
可以用数码管将这个数据显示一下,看下是不是我们写入,读取的数据,判断是不是能够使用。
问题。
案例2,假如我有一个数据,1500,要写入at24c02怎么办?
注意,1500超出了一个字节范围,上面的案例代码,我们只写了一个字节的读取和写入。
怎么实现一个int类型额数据读取和写入呢?
方法很多,举一个方法把。
把一个int类型分类高8位和低8位,高8位,放到0x00房间,低八位放0x01房间。
如果读取的话,分别读取出来,再把两个字节合并。
这个思路如何实现呢,如何分离高低八8位呢。
很简单。
int numa=1500;
unsigned char numaH=numa/256;
unsigned char numaL=numa%256;
printf(“numaH=%d”,numaH);
printf(“numaL=%d”,numaL);
可以测试下,numaH=5,numaL=220.
如果我们读取出来,那么就是结果
int ReadData;
ReadData=numaH*256+numaL
注意,比赛的时候,一般存储的数据是正数,所以干脆我们就学习int类型分解成unsigned char就好了。
问题。
如果我要存放一个小数怎么办?
可以把小数点乘以100,放大100倍,然后拆分高字节和低字节,然后写入到里面,
读取的时候,读取出来,然后合并,再除以100就可以了。