#include<reg52.h> #include<intrins.h> #define uchar unsigned char sbit SCL=P3^6; //I2C 時鐘 sbit SDA=P3^7; //I2C 數(shù)據(jù) sbit anjian_1=P3^4; uchar code LED[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; void delay_us() { _nop_(); /*起始條件建立時間大于4.7us,延時*/ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } delay_ms() { unsigned int i; for(i=0;i<20000;i++); } void delayms(unsigned int k) { unsigned int j,i; for(j=k;j>0;j--) for(i=110;i>0;i--); } void Start_I2c() { SDA=1; /*發(fā)送起始條件的數(shù)據(jù)信號*/ delay_us(); SCL=1; delay_us(); SDA=0; /*發(fā)送起始信號*/ delay_us(); } void Stop_I2c() { SDA=0; /*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/ delay_us(); SCL=1; delay_us(); SDA=1; /*發(fā)送I2C總線結(jié)束信號*/ delay_us(); } void Ack_I2c() //應(yīng)答函數(shù) { uchar i=0; SCL=1; delay_us(); while(SDA==1&&i<200) i++; SCL=0; delay_us(); } void No_ack() //非應(yīng)答函數(shù) { SDA=1; delay_us(); SCL=1; delay_us(); SCL=0; delay_us(); } void init() { SDA=1; SCL=1; } void wr_byte(uchar date) //寫一個字節(jié),該函數(shù)將數(shù)據(jù)寫入24C02 { uchar i; SCL=0; //IC總線在寫數(shù)據(jù)時,在時鐘低電平的時候改變數(shù)據(jù),高電平的時候傳送數(shù)據(jù) delay_us(); for(i=0;i<8;i++) /*要傳送的數(shù)據(jù)長度為8位*/ { if((date<<i)&0x80) SDA=1; /*判斷發(fā)送位*/ else SDA=0; delay_us(); SCL=1; // /*置時鐘線為高,通知被控器開始接收數(shù)據(jù)位*/ //IC總線在寫數(shù)據(jù)時,在時鐘低電平的時候改變數(shù)據(jù),高電平的時候傳送數(shù)據(jù) delay_us(); SCL=0; delay_us(); } SDA=1; /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/ delay_us(); } uchar re_byte() //讀一個字節(jié),該函數(shù)將數(shù)據(jù)讀出24C02 { uchar i,temp=0; SCL=0; delay_us(); SDA=1; delay_us(); for(i=0;i<8;i++) { temp<<=1; if(SDA) { temp|=0x01; } SCL=1; delay_us(); SCL=0; } return temp; } void write(uchar add,uchar dat) { init(); Start_I2c(); wr_byte(0xa0); Ack_I2c(); wr_byte(add); Ack_I2c(); wr_byte(dat); Ack_I2c(); Stop_I2c(); } uchar read(uchar add) { uchar value; init(); Start_I2c(); wr_byte(0xa0); //寫器件地址,前面四位是芯片24C02本身確定的,它不變,之后三位是引腳地址,因為我們都接地了,所以這三位都為0,最后一位位讀寫位,寫的話為0,讀為1 Ack_I2c(); wr_byte(add); //希望寫到哪個地址 Ack_I2c(); Start_I2c(); wr_byte(0xa1); //寫數(shù)據(jù) Ack_I2c(); value=re_byte(); No_ack(); Stop_I2c(); return value; } void main() { uchar k; delay_ms(); k=read(100); //上電后馬上讀取斷電前的數(shù)據(jù)(必須的語句) 100為地址 k為地址,范圍0-255 while(1) { if(anjian_1==0) { delayms(100); if(anjian_1==0) k++; P2=LED[k]; if(k>9) k=0; } write(100,k); //k為斷電前需要保存的數(shù)據(jù),100為地址,需要保存的數(shù)據(jù)用這條語句保存(必須的語句) P2=LED[k]; } } |
|
來自: dushikuaile > 《單片機》