这个字节发送函数我看得明白是符合数据位的有效性性规定,一字节数据一次一位发送,以SCL=1保证数据有效性,之后将SCL置0,当需要再发送一位时SCL=0,符合数据有效性
可是这个字节接收函数首先他就让SCL=0,不是很懂,我的初步理解结合两个函数一起看,当字节发送函数时由主机控制SCL变化,发送一位上SDA,让SCL=1,先保证他数据有效传输,然后SCL=0,同上,之后再发送一位时,SCL=0,因此SDA可以变化,对于字节接收函数,此时由从机控制SCL变化,当主机发送完数据丛机准备接收时,首先打开SCL=0,保证一位一位接收时SDA可以变化,当有一位在SDA上时,让SCL=1,保证传输到从机这的数据是有效的。请大佬指证
至于最初的字节接收函数开始的SDA=1,和最后的SCL=0不是很懂。
请大佬指教一下,不是很懂,希望大佬能详细讲解下,这里想了很久卡了很久,希望大佬可以对比着这两个函数讲讲数据传输过程。
- /*******************************************************************
- 字节数据接收函数
- 函数原型: UCHAR I2C_RcvByte();
- 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
- 发完后请用应答函数应答从机。
- ********************************************************************/
- unsigned char I2C_RcvByte()
- {
- unsigned char retc=0,i;
- sda=1; /*置数据线为输入方式*/ (不是很明白???)
- for(i=0;i<8;i++)
- {
- _nop_();
- scl=0; /*置时钟线为低,准备接收数据位*/
- _nop_();
- _nop_(); /*时钟低电平周期大于4.7μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=1; /*置时钟线为高使数据线上数据有效*/
- _nop_();
- _nop_();
- retc=retc<<1;
- if(sda==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
- _nop_();
- _nop_();
- }
- scl=0; (不是很懂???)
- _nop_();
- _nop_();
- return(retc);
- }
- /*******************************************************************
- 字节数据发送函数
- 函数原型: void I2C_SendByte(UCHAR c);
- 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
- 此状态位进行操作.(不应答或非应答都使ack=0)
- 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
- ********************************************************************/
- void I2C_SendByte(unsigned char c)
- {
- unsigned char i;
- for(i=0;i<8;i++) /*要传送的数据长度为8位*/
- {
- if((c<<i)&0x80)sda=1; /*判断发送位*/
- else sda=0;
- _nop_();
- scl=1; /*置时钟线为高,通知被控器开始接收数据位*/
- _nop_();
- _nop_(); /*保证时钟高电平周期大于4μs*/
- _nop_();
- _nop_();
- _nop_();
- scl=0;
- }
- _nop_();
- _nop_();
- sda=1; /*8位发送完后释放数据线,准备接收应答位*/
- _nop_();
- _nop_();
- scl=1;
- _nop_();
- _nop_();
- _nop_();
- if(sda==1)ack=0;
- else ack=1; /*判断是否接收到应答信号*/
- scl=0;
- _nop_();
- _nop_();
- }
复制代码
|