现在手头上要用LPC9102做一个I2C的从机,只需要接收指令,由于9102没有自带的I2C功能,需要软件模拟,我写了一个基本的如下: #include <reg9102.h> #include <stdio.h> #include <intrins.h> #define uchar unsigned char
sbit SDA = P0^7; //pin6 sbit SCL = P0^5; //pin8
void delay() { _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); }
unsigned char Read_byte(void) { uchar b=0,q; for(q=0;q<8;q++) { while(SCL!=1); delay(); while(SCL!=1); delay(); while(SCL!=1); b<<=1; if(SDA==1) { delay(); if(SDA==1) b|=1; else b&=0xfe; } else { delay(); if(SDA==1) b|=1; else b&=0xfe; } while(SCL!=0); delay(); while(SCL!=0); delay(); while(SCL!=0); } return(b); SDA=0;//回应 delay(); while(SCL!=1);//第9个时钟的高电平 SDA=0;//为了确认回应 while(SCL!=1); SDA=0; while(SCL!=1); SDA=0; while(SCL!=0);//第9个时钟的低电平 delay(); while(SCL!=0); delay(); while(SCL!=0); delay(); SDA=1; }
main() { P0M1=0x00;//全部准双向 P0M2=0x00; P1M1=0x00; P1M2=0x00; delay(); SDA=0; SCL=0; delay(); while(1) { while(SCL!=1); delay(); while(SCL!=1); delay(); while(SCL!=1); delay(); while(SDA!=1); delay(); while(SDA!=1); delay(); while(SDA!=1);//双高电平 while(SDA!=0); delay(); while(SDA!=0); delay(); while(SDA!=0);//SDA下降沿 判定为起始条件 while(SCL!=0); delay(); while(SCL!=0);//时钟低,SDA改变状态中,准备开始读取数据的第一位 Read_byte(); Read_byte(); } }
简化起见,我只读两个字节数据,其中第一个是地址,但是由于这条总线上只有9102一个,所以我就不加判定是不是我的地址,直接按接收数据的方式给回应就行了。 但是在实际过程中,由示波器看到的I2C总线上的波形,是主机发出了地址,但从机始终不给回应,而如果我主机不停的循环发,那么从机有时能给回应,有时又不行,请教为何? |