| 来源:网上转载 作者:佚名
//****************************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) //写一字节数据Data {uchar i; for(i=0;i<8;i++) {if(Data & 0x80) Write_Bit1(); //传输位从高位到低位,先传最高位 else Write_Bit0(); Data <<=1;} //数据左移 }
uchar Read_Byte() //读一字节数据:返回值即读的数据 {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); }
//***************************写一字节数据****************************// //向从地址为Slave的IIC器件的Address地址写一字节数据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); //写入一字节数据 do Check_Ack(); //检查应答位 while(Ack_Flag==1); Stop(); //停止 }
//***************************写两字节数据****************************// //向从地址为Slave的IIC器件的Address地址开始写两字节数据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(); //停止信号 }
//***************************读一字节数据****************************// //从从地址为Slave的IIC器件的Address地址处读一字节数据 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字节 Nack(); //读完发送一个Not Ack应答 Stop(); //停止 return data0; //返回读取数据 }
|