有个专门做装修的网站,淄博做网站跟优化,山东省住建厅官网二建查询,做平台的网站有哪些EEPROM芯片#xff1a; 掉电不会丢失数据#xff0c;可以保存数据。 IIC串行总线的组成及工作原理#xff1a; IIC总线传输协议 IIC产生起始与终止信号#xff1a; IIC字节的传送与应答#xff1a; 应答位作用#xff1a; 数据帧格式#xff1a; 总线寻址 软件模…EEPROM芯片 掉电不会丢失数据可以保存数据。 IIC串行总线的组成及工作原理 IIC总线传输协议 IIC产生起始与终止信号 IIC字节的传送与应答 应答位作用 数据帧格式 总线寻址 软件模拟IIC通信时序
IIc通信代码示例通过数码管显示单片机通过IIC通信接收到的数据
#include reg52.h
#include intrins.h#define uint unsigned int
#define uchar unsigned char
#define At24c02ADDR 0XA0 //AT24C02硬件地址
#define I2cRead 1 //I2C读方向位
#define I2cWrite 0 //I2C写方向位sbit DU P2^6;//数码管段选
sbit WE P2^7;//数码管段选
sbit SCL P2^1;//I2C时钟总线
sbit SDA P2^0;//I2C数据总线
uchar num;//数码管显示的值
bit AckFlag;//应答标志位//共阴数码管段选表0-9
uchar code SMGduan[] {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//数码管位选码
uchar code SMGwei[] {0xfe, 0xfd, 0xfb};void delay(uint z)
{uint x,y;for(x z; x 0; x--)for(y 114; y 0 ; y--);
} void display(uchar i)
{static uchar wei; P0 0XFF;//清除断码WE 1;//打开位选锁存器P0 SMGwei[wei];WE 0;//锁存位选数据switch(wei){case 0: DU 1; P0 SMGduan[i / 100]; DU 0; break;case 1: DU 1; P0 SMGduan[i % 100 / 10]; DU 0; break; case 2: DU 1; P0 SMGduan[i % 10]; DU 0; break; }wei;if(wei 3)wei 0;
}
//定时器0初始化
void timer0Init()
{EA 1; //打开总中断ET0 1;//打开定时器0中断TR0 1; //启动定时器0TMOD | 0X01; //定时器工作模式116位定时模式TH0 0xED;TL0 0xFF; //定时5ms
}
/****************************************************
IIC通信代码
****************************************************/
//延时5us
void delay5us()
{_nop_();//执行一次是一个机器周期进入这个函数需要3个多机器周期
}
//时钟总线为高电平期间数据总线由高变低产生起始信号
void I2cStart()
{SCL 1; SDA 1;delay5us();//状态保持5usSDA 0;delay5us();//状态保持5us//这个函数根据图像来写
}
//时钟总线为高电平期间数据总线从高变低产生终止信号
void I2cStop()
{SCL 0;SDA 0;SCL 1;delay5us();//状态保持5usSDA 1;delay5us();//状态保持5us//这个函数根据图像来写
}bit ReadACK()
{SCL 0;//拉低时钟总线允许从机控制SDASCL 1;//拉高读SDAdelay5us();if(SDA)//非应答{SCL 0;return(1);//返回1}else//应答 {SCL 0;return(0);//返回0}
}void SendACK(bit i)
{SCL 0;//拉低时钟总线允许主机控制SDAif(i) //发非应答SDA 1;else //发应答SDA 0;SCL 1; //拉高总线让从机读SDAdelay5us();//保持5usSCL 0; //拉低时钟总线允许SDA释放SDA 1;//释放数据总线
}void I2cSendByte(uchar DAT)
{uchar i; for(i0; i8; i) //分别写8次每次写1位{SCL 0;//拉低时钟总线允许SDA变化if(DAT 0x80)//先写数据最高位SDA 1; //写1elseSDA 0; //写0SCL 1; //拉高时钟让从机读SDADAT 1; //为发送下一位左移1位}SCL 0; //拉低时钟总线允许SDA释放SDA 1;//释放数据总线
}void At24c02Write(uchar ADDR, DAT)
{I2cStart();//I2C起始信号I2cSendByte(At24c02ADDR I2cWrite);//发送器件地址加读写方向位if(ReadACK()) //读从机应答AckFlag 1; //NOACKelseAckFlag 0; //ACKI2cSendByte(ADDR);//发送储存单元地址字节if(ReadACK())//读从机应答AckFlag 1; //NOACKelseAckFlag 0; //ACKI2cSendByte(DAT);//发送一字节数据if(ReadACK())//读从机应答AckFlag 1; //NOACKelseAckFlag 0; //ACKI2cStop(); //I2C停止信号
}uchar I2cReadByte()
{uchar i, DAT;for(i0; i8; i)//分别读8次每次读一位{DAT 1; //数据左移1位准备接收一位SCL 0; //拉低时钟总线允许从机控制SDA变化SCL 1; //拉高时钟总线读取SDA上的数据if(SDA)DAT | 0X01;//为1则写1否则不行执行写1通过左移补0}return(DAT); //返回读出的数据
}uchar At24c02Read(uchar ADDR)
{uchar DAT;I2cStart();//I2C起始信号I2cSendByte(At24c02ADDR I2cWrite);//发送器件地址加读写方向位if(ReadACK())//读从机应答AckFlag 1; //NOACKelseAckFlag 0; //ACKI2cSendByte(ADDR);//I2C发送一个字节ReadACK();//读从机应答I2cStart();//再次产生I2C起始信号I2cSendByte(At24c02ADDR I2cRead);//发送器件地址加读写方向位 读if(ReadACK())//读从机应答AckFlag 1; //NOACKelseAckFlag 0; //ACKDAT I2cReadByte();//读一字节SendACK(1);//主机发送非应答I2cStop(); //I2C停止信号return(DAT);//返回读出数据}void main()//main函数自身会循环
{ timer0Init();//定时器0初始化EA 0;//屏蔽中断At24c02Write(3, 188);//给第3单元写入数据“188”delay(2);//延时等待AT24C02处理num At24c02Read(3);//读出第3单元内数据送给显示变量if(AckFlag)//当从机非应答P1 0;//亮P1所有灯elseP1 0XFF;//灭P1所有灯EA 1;//开中断while(1);
} //定时器0中断函数
void timer0() interrupt 1
{TH0 0xED;TL0 0xFF; //定时5msdisplay(num); //数码管显示函数
}