1、I2c啟動
由上圖可知SDA在SCL為高電平時由高變為低表示啟動I2c,注意時間。
2、I2c關閉
由上圖可知SDA在SCL為高電平時由低變為高表示啟動I2c,注意時間。
3、數據0
由上圖可知SDA在SCL為高電平時拉低表示0,注意時間。
4、數據1
由上圖可知SDA在SCL為高電平時拉高表示0,注意時間。
5、I2c寫數據(數據由51到設備)
由上圖可以看書寫數據的步驟為:1)啟動I2c;
2)寫入設備地址(七位設備地址加一位讀寫命令,最后1為讀,0為寫);
3)等待應答(由設備發出,讀數據時由51給應答),這一步可以和第二部寫在一個函數中;
4)寫入數據要存放的地址;
5)等待應答;
6)寫入數據;
7)等待應答;
8)關閉I2c。
若將等待應答與寫數據放在一個函數中可簡化為:1)啟動I2c;
2)寫入設備地址
3)寫入數據要存放的地址;
4)寫入數據;
5)關閉I2c。
6、I2c讀數據(51從設備中讀取數據)
由上圖可以看書寫數據的步驟為:1)啟動I2c;
2)寫入設備地址;
3)寫入要讀取數據存放的地址;
4)啟動I2c;
5)寫入設備地址(第八位為1,表示讀數據);
6)讀數據;
7)給設備發送應答信號;
8)關閉I2c;
7、對應的51程序
- #include <STC12C5A60S2.H>
- #define uchar unsigned char
- #define uint unsigned int
-
- sbit SCL=P2^1;
- sbit SDA=P2^0;
- uchar code duan[]=
- {
- 0xfc,0x60,0xda,
- 0xf2,0x66,0xb6,
- 0xbe,0xe0,0xfe,0xf6
- };
- void delay(uint time)
- {
- uint i,j;
- for(i=0;i<time;i++)
- for(j=0;j<10;j++);
- }
- void I2c_start()
- {
- SDA=1;
- delay(1);
- SCL=1;
- delay(1);
- SDA=0;
- delay(1);
- SCL=0;
- delay(1);
- }
- void I2c_stop()
- {
- SDA=0;
- delay(1);
- SCL=1;
- delay(1);
- SDA=1;
- delay(1);
- }
- //·¢Ëíack
- void I2c_sendAck(bit ack)
- {
- SDA = ack;
- SCL = 1;
- delay(1);
- SCL = 0;
- delay(1);
-
- }
- //»ñè¡ack
- bit I2c_getAck(void)
- {
- bit ack;
- SDA = 1;
- SCL = 1;
- delay(1);
- ack = SDA;
- SCL = 0;
- return ack;
- }
- uchar I2c_read()
- {
- uchar i,dat=0;
- SDA=1;
- delay(1);
- for(i=0;i<8;i++)
- {
- SCL=1;
- delay(1);
- dat<<=1;
- dat|=SDA;
- delay(1);
- SCL=0;
- }
- return dat;
- }
- void I2c_write(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- SDA=dat>>7;
- dat<<=1;
- delay(1);
- SCL=1;
- delay(1);
- SCL=0;
- delay(1);
- }
- I2c_getAck();
- }
- void I2c_toDevice(uchar deviceAdd,uchar datAdd,uchar dat)
- {
- I2c_start();
- I2c_write(deviceAdd);
- I2c_write(datAdd);
- I2c_write(dat);
- I2c_stop();
- }
- uchar I2c_fromDevice(uchar deviceAdd,uchar datAdd )
- {
- uchar dat;
- I2c_start();
- I2c_write(deviceAdd);
- I2c_write(datAdd);
- I2c_start();
- I2c_write(deviceAdd+1);
- dat=I2c_read();
- I2c_sendAck(1);
- I2c_stop();
- return dat;
- }
- void main()
- {
- uchar num;
- I2c_toDevice(0xa0,3,7);
- delay(130);
- num=I2c_fromDevice(0xa0,3);
- while(1)
- {
- P0=0x00;
- P1=duan[num];
- delay(10);
- P1=0x00;
- }
- }
復制代碼
8、注意事項
1)關閉I2c和啟動I2c之間要有1ms間隔,給IO口準備時間,否則亂碼。
2)關于應答,當寫數據時由設備應答,讀數據時MCU應答。
3)讀數據時啟動兩次I2c。
|