应用在没有集成I2C的MCU上或MPU、DSP上
void SendByte(uchar c) { uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/ { if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/ 以最高位一位一位的读 高电平SDA=1反之SDA=0 else SDA="0"; _Nop(); SCL=1; 用SCL串行时钟来控制SDA同步发送,所以这个循环里面要有SCL的高低电平(代表一个周期)
_Nop(); _Nop(); /*保证时钟高电平周期大于4μs*/ _Nop(); _Nop(); _Nop(); SCL=0; 最终的低电平也是为了后来能够读取SDA 因为只有scl低电平sda才能被读取 } _Nop(); _Nop(); SDA="1"; /*8位发送完后释放数据线,准备接收应答位*/ 记住高电平释放数据总线就行了 主机通过SDA是否被被控机置1来判断是否应答! _Nop(); _Nop(); SCL="1"; 第九个周期高电平期判断SDA的状态 _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; else ack="1"; /*判断是否接收到应答信号*/ SCL="0"; _Nop(); _Nop();
/******************************************************************* 字节数据接收函数 函数原型: uchar RcvByte(); 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号), 发完后请用应答函数应答从机。 ********************************************************************/ uchar RcvByte() { uchar retc; uchar BitCnt;
retc=0; SDA=1; /*置数据线为输入方式*/ 这是主机在释放数据线,释放后由被控机控制 for(BitCnt=0;BitCnt<8;BitCnt++) { _Nop(); SCL=0; /*置时钟线为低,准备接收数据位*/ 因为只有低电平SDA才能改变 _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); } |
|
文章评论(0条评论)
登录后参与讨论