1.延时问题
有些教材和技术资料对IIC基本信号的脉宽和延时有一定的时间要求,在上述基本信号和数据传送子函数中加入了若干延时操作指令;另一些教材和技术资料则无此要求。经编者实验验证,80 C51单片机在fosc=12 MHz条件下,基本信号子函数和单字节读写子函数中的波形延时指令可以略去
但写N字节子函数中必须有页写缓冲延时,否则,写后若立即读AT24C02,将失败。
有关AT24Cxx页写缓冲的概念说明如下:
由于E⁹PROM的半导体工艺特性,对E²PROM的写入时间需要5~10ms,但AT24Cxx系列串行E*PROM芯片内部设置了一个具有SRAM性质的输入缓冲器,称为页写缓冲器。CPU对该芯片写操作时,AT24Cxx系列芯片先将CPU输入的数据暂存在页写缓冲器内,然后,慢慢写入E²PROM中。因此,CPU对AT24Cxx系列E’PROM一次写入的字节数,受到该芯片页写缓冲器容量的限制。页写缓冲器的容量为16B,若CPU写入字节数超过芯片页写缓冲器容量,应在一页写完后,隔5~10 ms重新启动一次写操作。
IIC操作
//delayms:
void delayms(uint xms)
{
uchar x, y;
for(x = xms; x > 0; x--)
for(y = 110; y > 0; y--);
}
//start:
void start() //启动i2c
{
sda = 1;
scl = 1;
delay();//延时必须大于4.7us,此约为五微秒
sda = 0; //在scl为高电平时,sda一个下降沿为启动信号
delay();
}
//stop:
void stop() //停止i2c
{
sda = 0;
scl = 1;
delay();
sda = 1; //在scl为高电平时,sdasda一个上升沿为停止信号
delay();
}
//ack:
void ack() //应答信号0
{
uchar i = 0; //等待变量
scl = 1;//在scl为高电平期间等待应答
delay();
while((sda == 1) && i < 250)//若为应答0即退出,从机向主机发送应答信号
i++;//等待一段时间
scl = 0; //应答之后将scl拉低
delay();
}
//nack:
void nack() //非应答
{
scl = 1;//在scl为高电平期间,由主机向从机发送一个1,非应答信号
delay();
sda = 1;
scl = 0; //应答之后将scl拉低
delay();
}
//检查应答
bit cack()
{sda = 1;
scl =1;
F0= sda;
scl= 0;
return(F0);}
//发送一字节
void WR1B(unsigned char x){
unsigned char i;
for(i=0;i<8;i++)
if((x&0x80)==0)SDA=0;
else SDA=1;
SCL=1;
SCL=0;
x<<=1;}}
(2)接收一字节数据子程序
unsigned char RD1B(){
unsigned char i,x=0;
SDA=1;
for(i=0;i<8;i++){
SCL=1;
x=(x<<1)|SDA;
SCL=0;}
return(x)}
2.读写AT24C02
写操作

void WRNB(unsigned char a[],n, sadr){/′写AT24C>cx n字节子函数//形参:写入数据数组a[],写入数据字节数n,写入单元首地址sadr
unsigned char i;//定义序号变量i
unsigned int t;//定义延时参数t
STAT();//发启动信号
WR1B(0xa0);//发送写寻址字节
CACK();//检查应答
WR1B(sadr);/发送写入AT24CXX片内子地址
CACK();//检查应答
for(i=0;i<n;i++){//循环写入n字节
WR1B(a[i]);//写入I²C一个字节
CACK();//检查应答
STOP();//n个数据写入完毕,发终止信
for(t=0;t<1000;t++);}//页写延时5ms
读操作

void RDNB(unsigned char b[],n, sadr){/读AT24Cxxn字节子函数//形参:接收数据数组b[],接收数据字节数n,读出单元首地址sadr
unsigned char i;//定义序号变量i
STAT();/发启动信号
WR1B(0xa0);//发送写寻址字节
CACK();//检查应答
WR1B(sadr);//发送读AT24CXX片内首地址
CACK();//检查应答
STAT();//再次发启动信号
WR1B(0xa1);//发送读寻址字节
CACK();//检查应答
for(i=0;i<n-1;i++)//循环读出(n-1)个字节
b[i]=RD1B();//接收1个字节
ACK();}//发送应答A
b[i]=RD1B();//接收最后一个字节
NACK();//发送应答a
STOP();}//n个数据接收完毕,发终止
3.主程序
4.程序设计
读出,存在80C51内RAM数组b[8]中。试将存于80C51内RAM数组a[8]写入 AT24C0250H ~57H单元中.。。
#include<reg51.h>//包含访问sfr库函数reg51.h。
#include<intrins.h>//包含访问sfr库函数intrins.h sbit SCL=P1^0;/定义时钟线SCL为P1.0
sbit SDA=P1^1;//定义数据线SDA为P1.1
void STAT();//启动信号子函数STAT
void STOP();//终止信号子函数STOP
void ACK();//发送应答A子函数ACK
void NACK();//发送应答A子函数NACK
bit CACK();/检查应答子函数CACK
void WR1B();/发送1字节子函数WR1B,形参x(发送数据)
unsigned char RD1B();/接收1字节子函数RD1B,有返回值(接收数据
void WRNB();/写AT24Cxxn字节子函数
void RDNB();//读AT24Cxxn字节子函数
void main(){//主函数
unsigned char
a[8]={
a//定义写入数组a[8],并赋值
0x1a,0x2b,0x3c,0x4d,0x5e,0x6f,0x79,0x80};
unsigned char b[8];//定义存入数组b[8]
WRNB(a,8,0x50);//调用写n字节子函数
RDNB(b,8,0x50);//调用读n字节子函数,存入数组b[8]
while(1);}//原地等待
4.电路图

5.总结
无聊了
买个地球仪吧
世界那么大
你不但可以看看
还可以转转
版权声明:本文为m0_46152804原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。