2019-07-15 14:56发布
michael_llh 发表于 2016-2-25 20:31 楼主能够说得更详细一点吗? 具体你是IIC通信双方是谁,同时应该严格安装通信双发给的同时时序进行编写
michael_llh 发表于 2016-2-28 00:08 好好看一下AT24C16的操作时序就知道为什么这么写了,从bus time那一章好好看一下就可以明白。不懂再留言
最多设置5个标签!
具体你是IIC通信双方是谁,同时应该严格安装通信双发给的同时时序进行编写
单片机STC90C51和EEPROM AT24C16通信
- #include"i2c.h"
- /*******************************************************************************
- * 函 数 名 : Delay1us()
- * 函数功能 : 延时
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void I2C_Delay10us()
- {
- uchar a, b;
- for(b=1; b>0; b--)
- {
- for(a=2; a>0; a--);
- }
- }
- /*******************************************************************************
- * 函 数 名 : I2C_Start()
- * 函数功能 : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿
- * 输 入 : 无
- * 输 出 : 无
- * 备 注 : 起始之后I2C_SDA和I2C_SCL都为0
- *******************************************************************************/
- void I2C_Start()
- {
- I2C_SDA = 1;
- I2C_Delay10us();
- I2C_SCL = 1;
- I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7us
- I2C_SDA = 0;
- I2C_Delay10us();//保持时间是>4us
- I2C_SCL = 0;
- I2C_Delay10us();
- }
- /*******************************************************************************
- * 函 数 名 : I2C_Stop()
- * 函数功能 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿
- * 输 入 : 无
- * 输 出 : 无
- * 备 注 : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲
- *******************************************************************************/
- void I2C_Stop()
- {
- I2C_SDA = 0;
- I2C_Delay10us();
- I2C_SCL = 1;
- I2C_Delay10us();//建立时间大于4.7us
- I2C_SDA = 1;
- I2C_Delay10us();
- }
- /*******************************************************************************
- * 函 数 名 : I2cSendByte(uchar num)
- * 函数功能 : 通过I2C发送一个字节。在I2C_SCL时钟信号高电平期间,
- * * 保持发送信号I2C_SDA保持稳定
- * 输 入 : num ,ack
- * 输 出 : 0或1。发送成功返回1,发送失败返回0
- * 备 注 : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
- *******************************************************************************/
- uchar I2C_SendByte(uchar dat, uchar ack)
- {
- uchar a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
-
- for(a=0; a<8; a++)//要发送8位,从最高位开始
- {
- I2C_SDA = dat >> 7; //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
- dat = dat << 1;
- I2C_Delay10us();
- I2C_SCL = 1;
- I2C_Delay10us();//建立时间>4.7us
- I2C_SCL = 0;
- I2C_Delay10us();//时间大于4us
- }
- I2C_SDA = 1;
- I2C_Delay10us();
- I2C_SCL = 1;
- while(I2C_SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
- {
- b++;
- if(b > 200) //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
- {
- I2C_SCL = 0;
- I2C_Delay10us();
- return 0;
- }
- }
- I2C_SCL = 0;
- I2C_Delay10us();
- return 1;
- }
- /*******************************************************************************
- * 函 数 名 : I2cReadByte()
- * 函数功能 : 使用I2c读取一个字节
- * 输 入 : 无
- * 输 出 : dat
- * 备 注 : 接收完一个字节I2C_SCL=0
- *******************************************************************************/
- uchar I2C_ReadByte()
- {
- uchar a = 0,dat = 0;
- I2C_SDA = 1; //为什么?????????????????????????
- I2C_Delay10us();
- for(a=0; a<8; a++)//接收8个字节
- {
- I2C_SCL = 1;
- I2C_Delay10us();
- dat <<= 1;
- dat |= I2C_SDA;
- I2C_Delay10us();
- I2C_SCL = 0;
- I2C_Delay10us();
- }
- return dat;
- }
复制代码http://a4.qpic.cn/psb?/38930a9a- ... CIMC1hhMJy1TDYZ7M61*oD9Q1eO59BSo!/b/dFcBAAAAAAAA&ek=1&kp=1&pt=0&bo=nwVXAp8FVwIFACM!&sce=0-12-12&rf=viewer_311
单片机从AT24C16接收数据时序看SDA OUT没错吧
实在看不出来为什么接收时单片机必须把SDA拉高?
(我英语昨天刚过4级)
一周热门 更多>