/* 51系列單片機(jī)在使用時(shí),有時(shí)需要模擬I2C總線, */ /* 這里舉出一個(gè)實(shí)例(讀寫串行EEPROM芯片at2402) */ /************************************************************************/ /* Name:AT24C02存儲(chǔ)器的讀寫程序,用到I2C總線,含相對(duì)獨(dú)立的I2C總線讀寫函數(shù) */ /* Language: C51單片機(jī)編程語言 */ /* Platform: Win98,Intel Celeron 433 Processor,偉福仿真器,仿真8751 */ /* Author: StephenZhu javasdk@163.com */ /* Date: 2003年5月21日,5月22日,5月29日 */ /* Version: 1.1.1 */ /* Others: None */ /************************************************************************/
#include<string.h> #include<reg52.h> #include<intrins.h> #define DELAY_TIME 60 /*經(jīng)實(shí)驗(yàn),不要小于50!否則可能造成時(shí)序混亂*/ #define TRUE 1 #define FALSE 0
sbit SCL=P1^7;/*假設(shè)由P1.7和P1.6控制*/ sbit SDA=P1^6;
/********** Function Definition 函數(shù)定義 ************/
void DELAY(unsigned int t) /*延時(shí)函數(shù)*/ { while(t!=0) t--; }
void I2C_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 I2C_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) /* SEND ACK */ { /*發(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 WriteI2CByte(char b)reentrant { /*向I2C總線寫一個(gè)字節(jié)*/ char i; for(i=0;i<8;i++) if((b<<i)&0x80) SEND_1(); else SEND_0(); }
char ReadI2CByte(void)reentrant { /*從I2C總線讀一個(gè)字節(jié)*/ char 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;
|
| | | | 作者: 瘋子海 2005-7-4 21:54 回復(fù)此發(fā)言 | |
|
| 2 | 【例程】51系列單片機(jī)模擬I2C總線 | | } else b=b<<1; } return b; }
/**********以下為讀寫24c02的函數(shù)**********/ void Write_One_Byte(char addr,char thedata) { bit acktemp=1; /*write a byte to mem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); WriteI2CByte(thedata);/*thedata*/ acktemp=Check_Acknowledge(); I2C_Stop();
}
void Write_A_Page(char *buffer,char addr) { bit acktemp=1; bit wrtmp; int i; /*write a page to at24c02*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); for(i=0;i<7;i++) { WriteI2CByte(buffer[i]); if(!Check_Acknowledge()) { I2C_Stop();
} }
I2C_Stop();
}
char Read_One_Byte(char addr) { bit acktemp=1; char mydata; /*read a byte from mem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); I2C_Start(); WriteI2CByte(0xa1); acktemp=Check_Acknowledge();
mydata=ReadI2CByte(); acktemp=Check_Acknowledge();
return mydata; I2C_Stop(); }
void Read_N_Bytes(char *buffer,char n,char addr) { bit acktemp=1;
int i=0; /*read 8 bytes from mem*/ I2C_Start(); WriteI2CByte(0xa0); acktemp=Check_Acknowledge(); WriteI2CByte(addr);/*address*/ acktemp=Check_Acknowledge(); I2C_Start(); WriteI2CByte(0xa1);
acktemp=Check_Acknowledge();
for(i=0;i<n;i++) { buffer[i]=ReadI2CByte(); if(i!=n-1) SEND_0(); /*發(fā)送應(yīng)答*/ else SEND_1(); /*發(fā)送非應(yīng)答*/ }
I2C_Stop();
}
void main() { int i; char mybyte; char myarray[8]; char myarray2[8]; char rdarray[16]; for(i=0;i<8;i++) { myarray[i]=i; myarray2[i]=i+0x08;
}
Write_One_Byte(0x20,0x28);
Write_A_Page(myarray,0x10); Write_A_Page(myarray2,0x18);
mybyte=Read_One_Byte(0x20); Read_N_Bytes(rdarray,16,0x10);
}
|
|
|
|