| 來源:網上轉載 作者:佚名 //****************************I2C驅動程序****************************// void Set_SCL(uchar i) //定義MAX6959時鐘線為PA^7 {if(i) PORTA |=0x80; else PORTA &=0x7f; } void Set_SDA(uchar i) //定義MAX6959數據線為PA^6 {if(i) PORTA |=0x40; else PORTA &=0xbf; } void Start() //I2C總線的開始條件 {Set_SDA(1); //SDA=1; Set_SCL(1); //SCL=1; delay(100); //等待時鐘信號變高 Set_SDA(0); //SDA=0; delay(100); Set_SCL(0); // SCL=0; } void Stop() //I2C總線結束條件 {Set_SDA(0); //SDA=0; delay(100); Set_SCL(1); //SCL=1; delay(100); //等待時鐘信號變低 Set_SDA(1); //SDA=1; delay(100); Set_SCL(0); //SCL=0; } void Ack() //I2C總線應答 {Set_SDA(0); //SDA=0; delay(50); Set_SCL(1); //SCL=1; delay(100); Set_SCL(0); //SCL=0; delay(50); Set_SDA(1); //SDA=1; } void Nack() //I2C總線應答非 {Set_SDA(1); //SDA=1; delay(50); Set_SCL(1); //SCL=1; delay(100); Set_SCL(0); //SCL=0; delay(50); Set_SDA(0); //SDA=0; } void Check_Ack() //I2C總線應答檢查 {Set_SDA(1); //SDA=1; Set_SCL(1); //SCL=1; Ack_Flag=0; //清除應答標志; DDRA&=0xbf; //設置SDA為輸入 if(!((PINA & 0x40)>>6)) {delay(50); Set_SCL(0); //SCL=0; delay(100);} else {Ack_Flag=1; //收到應答; delay(50); Set_SCL(0); //SCL=0; delay(100);} DDRA |=0xff; //重新設置SDA為輸出 } void Write_Bit0() //寫1bit數據:0 {Set_SDA(0); //SDA=0; Set_SCL(1); //SCL=1; delay(100); Set_SCL(0); //SCL=0; } void Write_Bit1() //寫1bit數據:1 {Set_SDA(1); //SDA=1; Set_SCL(1); //SCL=1; delay(100); Set_SCL(0); //SCL=0; Set_SDA(0); //SDA=0; } void Write_Byte(uchar Data) //寫一字節(jié)數據Data {uchar i; for(i=0;i<8;i++) {if(Data & 0x80) Write_Bit1(); //傳輸位從高位到低位,先傳最高位 else Write_Bit0(); Data <<=1;} //數據左移 } uchar Read_Byte() //讀一字節(jié)數據:返回值即讀的數據 {uchar Read_Data=0xff; // Read_Data為讀入的數據,初始值為0xff uchar j; for (j=0;j<8;j++) {Set_SDA(1); Set_SCL(1); DDRA &=0xbf; if((PINA & 0x40)==0) {Read_Data <<=1; Read_Data=(Read_Data & 0xfe); Set_SCL(0);} else {Read_Data <<=1; Read_Data =( Read_Data | 0x01); Set_SCL(0);}} DDRA |=0x40; return(Read_Data); } //***************************寫一字節(jié)數據****************************// //向從地址為Slave的IIC器件的Address地址寫一字節(jié)數據Data void Write_1byte(uchar Slave,uchar Address,uchar Data) {Start(); //開始 Write_Byte(Slave); //寫I2C器件地址 do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Write_Byte(Address); //送寄存器地址 do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Write_Byte(Data); //寫入一字節(jié)數據 do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Stop(); //停止 } //***************************寫兩字節(jié)數據****************************// //向從地址為Slave的IIC器件的Address地址開始寫兩字節(jié)數據Data0,Data1 void Write_2byte(uchar Slave,uchar Address,uchar Data0,uchar Data1) {Start(); //開始 Write_Byte(Slave); //寫I2C器件地址 do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Write_Byte(Address); //送寄存器地址 do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Write_Byte(Data0); do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Write_Byte(Data1); do Check_Ack(); //檢查應答位 while(Ack_Flag==1); Stop(); //停止信號 } //***************************讀一字節(jié)數據****************************// //從從地址為Slave的IIC器件的Address地址處讀一字節(jié)數據 uchar Read_1byte(uchar Slave,uchar Address) {uchar data0,x; do{ Start(); //開始信號 Write_Byte(Slave); //寫I2C器件地址 Check_Ack(); //檢查應答位 }while(Ack_Flag); do{ Write_Byte(Address); //寫寄存器地址 Check_Ack(); //檢查應答位 }while(Ack_Flag); do{ Start(); //開始 Write_Byte(Slave+1); //寫I2C器件地址(+1表示為讀操作) Check_Ack(); //檢查應答位 }while(Ack_Flag); data0=Read_Byte(); //讀1字節(jié) Nack(); //讀完發(fā)送一個Not Ack應答 Stop(); //停止 return data0; //返回讀取數據 }
|