|
/********************************************** 模拟I2C程序 winavr20050214 ***********************************************/ # define F_CPU 4000000UL
#include <avr/io.h> #include <avr/delay.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))
//DDR PORT //0 0 in,high //0 1 in,r //1 0 out=0 //1 1 out=1
#define sda 0 #define scl 1 #define I2C DDRB #define I2C_read PINB #define I2C_set PORTB
#define Set_SDA cbi(I2C,sda) #define Cls_SDA sbi(I2C,sda) #define Set_SCL cbi(I2C,scl) #define Cls_SCL sbi(I2C,scl) #define SDA_High bit_is_set(I2C_read,sda)
//function declaration void I2C_Delay(void); void I2C_Start(void); void I2C_Stop(void); unsigned char I2C_Write(unsigned char wb); unsigned char I2C_Read(unsigned char bEnd);
//***************************************************** //delay 100us //***************************************************** void I2C_Delay(void) { _delay_us(100); }
//***************************************************** //i2c init //***************************************************** void I2C_init(void) {
//DDR PORT //0 0 in,high //0 1 in,r //1 0 out=0 //1 1 out=1
cbi(I2C_set,sda); //sda=1 cbi(I2C,sda); //sda in cbi(I2C_set,scl); //scl=1; cbi(I2C,scl); //scl in }
//***************************************************** //i2c start //***************************************************** void I2C_Start(void) { Cls_SCL; I2C_Delay(); Set_SDA; I2C_Delay();
Set_SCL; I2C_Delay(); Cls_SDA; I2C_Delay();
Cls_SCL; I2C_Delay(); }
//***************************************************** //i2c stop //***************************************************** void I2C_Stop(void) { Cls_SDA; I2C_Delay(); Set_SCL; I2C_Delay(); Set_SDA; I2C_Delay();
Set_SCL; I2C_Delay(); }
//***************************************************** //I2C_Write //***************************************************** unsigned char I2C_Write(unsigned char wb) { unsigned char i,ack=0; for(i=0;i<8;i++) { if( wb&0x80 ) Set_SDA; else Cls_SDA; wb=wb<<1; I2C_Delay(); Set_SCL; I2C_Delay(); Cls_SCL; if(i!=7) I2C_Delay(); } Set_SDA; //release sda line I2C_Delay(); Set_SCL; I2C_Delay(); if( SDA_High ) ack=1; //ack error
Cls_SCL; I2C_Delay(); return ack; }
//***************************************************** //I2C_Read //***************************************************** unsigned char I2C_Read(unsigned char bEnd) { unsigned char i,mb; Set_SDA; //release sda line mb=0; for(i=0;i<8;i++) { mb=mb<<1; I2C_Delay(); Set_SCL; I2C_Delay(); if( SDA_High ) mb++; I2C_Delay(); Cls_SCL; if(i!=7) I2C_Delay(); } if( bEnd ) Set_SDA; //end read else Cls_SDA; //ack I2C_Delay(); Set_SCL; I2C_Delay(); Cls_SCL; I2C_Delay(); Set_SDA; return mb;
}
|