|
下面是用普通C51實(shí)現(xiàn)的I2C基本電平模擬函數(shù)和通用函數(shù)。
/* 電平模擬函數(shù)和基本讀寫函數(shù) void IIC_Start(void); void IIC_Stop(void); void SEND_0(void); void SEND_1(void); bit Check_Acknowledge(void); void Write_Byte(uchar b)reentrant; bit Write_N_Bytes(uchar *buffer,uchar n)reentrant; bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer); uchar Read_Byte(void)reentrant; */
#include<string.h> #include<reg52.h> #include<intrins.h> #include"aiic_51.h"
sbit SCL=P1^6; sbit SDA=P1^7;
void DELAY(uint t) { while(t!=0) t--; }
void IIC_Start(void) { //啟動(dòng)I2C總線的函數(shù) , 當(dāng)SCL為高電平時(shí)使SDA產(chǎn)生一個(gè)負(fù)跳變 SDA=1; SCL=1; DELAY(DELAY_TIME); SDA=0; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void IIC_Stop(void) { //終止I2C總線,當(dāng)SCL為高電平時(shí)使SDA產(chǎn)生一個(gè)正跳變 SDA=0; SCL=1; DELAY(DELAY_TIME); SDA=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void SEND_0(void) { //發(fā)送0,在SCL為高電平時(shí)使SDA信號(hào)為低 SDA=0; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
void SEND_1(void) { //發(fā)送1,在SCL為高電平時(shí)使SDA信號(hào)為高 SDA=1; SCL=1; DELAY(DELAY_TIME); SCL=0; DELAY(DELAY_TIME); }
bit Check_Acknowledge(void) { //發(fā)送完一個(gè)字節(jié)后檢驗(yàn)設(shè)備的應(yīng)答信號(hào) SDA=1; SCL=1; DELAY(DELAY_TIME/2); F0=SDA; DELAY(DELAY_TIME/2); SCL=0; DELAY(DELAY_TIME); if(F0==1) return FALSE; return TRUE; }
void Write_Byte(uchar b)reentrant { //向IIC總線寫一個(gè)字節(jié) uchar i; for(i=0;i<8;i++) if((b<<i)&0x80) SEND_1(); else SEND_0(); }
bit Write_N_Bytes(uchar *buffer,uchar n)reentrant { //向I2C總線寫n個(gè)字節(jié) uchar i; IIC_Start();
for(i=0;i<n;i++) { Write_Byte(buffer[i]); if(!Check_Acknowledge()) { IIC_Stop(); return(i==n); } }
IIC_Stop(); return TRUE; }
uchar Read_Byte(void)reentrant { //從I2C總線讀一個(gè)字節(jié) uchar b=0,i; for(i=0;i<8;i++) { SDA=1; //釋放總線 SCL=1; //接受數(shù)據(jù) DELAY(10); F0=SDA; DELAY(10); SCL=0; if(F0==1) { b=b<<1; b=b|0x01; } else b=b<<1; } return b; }
bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer) { //從I2C總線讀n個(gè)字節(jié) uchar i; IIC_Start(); Write_Byte(SlaveAdr); //向總線發(fā)送接收器地址 if(!Check_Acknowledge()) //等待接收器應(yīng)答信號(hào) return FALSE; for(i=0;i<n;i++) { buffer[i]=Read_Byte(); if(i!=n) SEND_0(); //發(fā)送應(yīng)答 else SEND_1(); //發(fā)送非應(yīng)答 } IIC_Stop(); return TRUE; }
使用上述代碼,你可以在51上用P1口模擬I2C |