共2条
1/1 1 跳转至页

问
那位大侠能给小弟细讲一下I2C总线呀,
看了半天还是有点迷茫,谢谢! 答 1: 把协议好好读几遍,比在这里问更有效果。有具体的点不明白时,才拿上来问。 答 2: 谢谢协议已经读料好几遍了,但是对于SDA,SCL线的作用还是有点迷茫,在传送一个8位字节前和传送后他们的变化,不好意思,第一次用,谢谢了computer00,在给讲一下吧 答 3: SDA就是数据线,SCL就是时钟线。空闲时两个都为高。
在数据正常发送过程中,只有当SCL为低时才能改变状态。
如果SCL为高时,SDA改变状态,就会产生启始或停止条件。
具体是:如果SCL为高,SDA由高到低,则产生启始条件(或者是重复启始条件)。
如果SCL为高,SDA由低到高,则产生停止条件。
数据必须在启始条件后发送,第一个字节为设备地址。
这些在协议里面都写得很清楚,自己去看吧,晕菜~~~~~~~~~ 答 4: 多读几遍 答 5: 多谢/*****************************************uchar RcvB()*****************************************
该函数是字节数据传送函数,功能是用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后
调用应答函数
***********************************************************************************************/
uchar RcvB()
{
uchar retc;
uchar BitCnt;
retc=0;
Sda_I2C=1; /*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_NOP();
Scl_I2C=0; /*置时钟线为低准备接受数据位*/
_NOP(); /*时钟低电平周期*/
_NOP();
_NOP();
_NOP();
_NOP();
Scl_I2C=1; /*置时钟线为高使数据线上数据有效*/
_NOP();
_NOP();
retc=retc<<1;
if(Sda_I2C==1) retc=retc+1; /*读数据位,接收到数据位放入retc中*/
_NOP();
_NOP();
}
Scl_I2C=0;
_NOP();
_NOP();
return(retc);
}
这是MCU从从器件中读书据的函数,帮忙分析一下,
尤其是
Scl_I2C=1;/*置时钟线为高使数据线上数据有效*/
难道非要SCL为高MCU才能读到数据吗?
if(Sda_I2C==1) retc=retc+1;难道从器件每发送一个BIT都要把SDA置高吗?
答 6: 协议里面不是写得好清楚吗???“6.1 数据的有效性
SDA 线上的数据必须在时钟的高电平周期保持稳定数据线的高或低电平状态只有在SCL 线的时钟
信号是低电平时才能改变见图4)。”
if(Sda_I2C==1) retc=retc+1;难道从器件每发送一个BIT都要把SDA置高吗?
这句话的意思是,如果Sda_I2C为高(即Sda_I2C等于1),那么retc就加1,加1就相当于把最后一位置1。
这样就表示收到了一个1,并把它放在retc的最低位。如果Sda_I2C不等于1,即收到一个0,retc就
不加1,也就是最低位为0,表示收到一个0。如果还需要接收其它的位,则将retc往左移动一位
(即上面那句retc=retc<<1;或者写成retc<<=1;),然后又跟上面的过程一样,把接下来收到的一位放到最后。 答 7: 非常感谢非常感谢computer00,有机会请你吃饭:) 答 8: 只要把时序看明白了,按照时序写就OK了 答 9: 谢谢。
那位大侠能给小弟细讲一下I2C总线呀,
看了半天还是有点迷茫,谢谢! 答 1: 把协议好好读几遍,比在这里问更有效果。有具体的点不明白时,才拿上来问。 答 2: 谢谢协议已经读料好几遍了,但是对于SDA,SCL线的作用还是有点迷茫,在传送一个8位字节前和传送后他们的变化,不好意思,第一次用,谢谢了computer00,在给讲一下吧 答 3: SDA就是数据线,SCL就是时钟线。空闲时两个都为高。
在数据正常发送过程中,只有当SCL为低时才能改变状态。
如果SCL为高时,SDA改变状态,就会产生启始或停止条件。
具体是:如果SCL为高,SDA由高到低,则产生启始条件(或者是重复启始条件)。
如果SCL为高,SDA由低到高,则产生停止条件。
数据必须在启始条件后发送,第一个字节为设备地址。
这些在协议里面都写得很清楚,自己去看吧,晕菜~~~~~~~~~ 答 4: 多读几遍 答 5: 多谢/*****************************************uchar RcvB()*****************************************
该函数是字节数据传送函数,功能是用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后
调用应答函数
***********************************************************************************************/
uchar RcvB()
{
uchar retc;
uchar BitCnt;
retc=0;
Sda_I2C=1; /*置数据线为输入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_NOP();
Scl_I2C=0; /*置时钟线为低准备接受数据位*/
_NOP(); /*时钟低电平周期*/
_NOP();
_NOP();
_NOP();
_NOP();
Scl_I2C=1; /*置时钟线为高使数据线上数据有效*/
_NOP();
_NOP();
retc=retc<<1;
if(Sda_I2C==1) retc=retc+1; /*读数据位,接收到数据位放入retc中*/
_NOP();
_NOP();
}
Scl_I2C=0;
_NOP();
_NOP();
return(retc);
}
这是MCU从从器件中读书据的函数,帮忙分析一下,
尤其是
Scl_I2C=1;/*置时钟线为高使数据线上数据有效*/
难道非要SCL为高MCU才能读到数据吗?
if(Sda_I2C==1) retc=retc+1;难道从器件每发送一个BIT都要把SDA置高吗?
答 6: 协议里面不是写得好清楚吗???“6.1 数据的有效性
SDA 线上的数据必须在时钟的高电平周期保持稳定数据线的高或低电平状态只有在SCL 线的时钟
信号是低电平时才能改变见图4)。”
if(Sda_I2C==1) retc=retc+1;难道从器件每发送一个BIT都要把SDA置高吗?
这句话的意思是,如果Sda_I2C为高(即Sda_I2C等于1),那么retc就加1,加1就相当于把最后一位置1。
这样就表示收到了一个1,并把它放在retc的最低位。如果Sda_I2C不等于1,即收到一个0,retc就
不加1,也就是最低位为0,表示收到一个0。如果还需要接收其它的位,则将retc往左移动一位
(即上面那句retc=retc<<1;或者写成retc<<=1;),然后又跟上面的过程一样,把接下来收到的一位放到最后。 答 7: 非常感谢非常感谢computer00,有机会请你吃饭:) 答 8: 只要把时序看明白了,按照时序写就OK了 答 9: 谢谢。
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【我踩过的那些坑】结构堵孔导致的喇叭无声问题被打赏50分 | |
【我踩过的那些坑】分享一下调试一款AD芯片的遇到的“坑”被打赏50分 | |
电流检测模块MAX4080S被打赏10分 | |
【我踩过的那些坑】calloc和malloc错误使用导致跑飞问题排查被打赏50分 | |
多组DCTODC电源方案被打赏50分 | |
【我踩过的那些坑】STM32cubeMX软件的使用过程中的“坑”被打赏50分 | |
新手必看!C语言精华知识:表驱动法被打赏50分 | |
【我踩过的那些坑】杜绑线问题被打赏50分 | |
【我踩过的那些坑】STM32的硬件通讯调试过程的“坑”被打赏50分 | |
【我踩过的那些坑】晶振使用的问题被打赏100分 |