重点:如何依照 ”Datasheet“ 写 IIC 通信函数
问题
问题1:读写元件的地址不一样,为啥传入参数一样,为啥都是写入地址。
答:xd 加1了
问题2:寄存器里都是补码形式,为什么代码不转换
答:没转换,单片机代码不需要,直接从寄存器中读出来就可以,读出来就是带符号位的数据,需要
if(x>0x7fff)x-=0xffff;
。
问题3:温度寄存器里的温度值如何转为摄氏度
答:
问题4:如何确定等待函数I2C_delay()的时长?
等待时长大于列表中最大值即可。
I2C术语
9种术语
S : (起始信号)SCL高,SDA从高到低
AD :从机地址
W :一位一位写
R :一位一位读
ACK :应答信号 SDA为低,当SCL在第九个周期为高的时候
NACK :不应答信号 SDA在第九个周期依旧为高
RA :ITG3200内部寄存器地址
DATA :发送或接收数据
P :当SCL为高时,SDA从低到高
写字节函数
Single_Write(器件地址,寄存器地址,数值);
bool Single_Write(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data) //void { if(!I2C_Start())return FALSE;//发送start I2C_SendByte(SlaveAddress); //发送器件地址(写) if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}//等待应答 I2C_SendByte(REG_Address ); //发送寄存器地址 I2C_WaitAck(); //等待应答 I2C_SendByte(REG_data); //发送寄存器数据 I2C_WaitAck(); //等待应答 I2C_Stop(); //发送停止信号 delay5ms(); return TRUE; }
读字节函数
Single_Read(器件地址,寄存器地址);
unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address) { unsigned char REG_data; if(!I2C_Start())return FALSE; //发送开始信号 I2C_SendByte(SlaveAddress); //发送从机地址(写) //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE); if(!I2C_WaitAck()){I2C_Stop();test=1; return FALSE;} //等待应答 I2C_SendByte((u8) REG_Address); //发送寄存器地址 I2C_WaitAck(); //等待应答 I2C_Start(); //发送开始信号 I2C_SendByte(SlaveAddress+1); //发送从机地址(读) I2C_WaitAck(); //等待应答信号 REG_data= I2C_RadeByte(); //读数据 I2C_NoAck(); //发送不应答信号 I2C_Stop(); //发送停止信号 return REG_data; }
1.这个开始信号(标上标1)要么是一个重新开始信号,要么是一个停止信号
2.阴影区域代表了设备正在聆听。
S : (起始信号)SCL高,SDA从高到低
bool I2C_Start(void) { SDA_H; //SDA SCL_H; I2C_delay(); if(!SDA_read)return FALSE; //SDA是否为1 SDA_L; I2C_delay(); if(SDA_read) return FALSE; //SDA SDA_L; I2C_delay(); return TRUE; }
ACK :当SCL在第九个周期为高的时候,应答信号 SDA为低。
/******************************************************************************* * Function Name : I2C_Ack * Description : Master Send Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Ack(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); }
NACK :不应答信号 SDA在第九个周期依旧为高
/******************************************************************************* * Function Name : I2C_NoAck * Description : Master Send No Acknowledge Single * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_NoAck(void) { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; I2C_delay(); }
WA :等待应答
/******************************************************************************* * Function Name : I2C_WaitAck * Description : Master Reserive Slave Acknowledge Single * Input : None * Output : None * Return : Wheather Reserive Slave Acknowledge Single ****************************************************************************** */ bool I2C_WaitAck(void) //·µ»ØΪ:=1ÓÐACK,=0ÎÞACK { SCL_L; I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { SCL_L; I2C_delay(); return FALSE; } SCL_L; I2C_delay(); return TRUE; }
P :停止信号,当SCL为高时,SDA从低到高
/******************************************************************************* * Function Name : I2C_Stop * Description : Master Stop Simulation IIC Communication * Input : None * Output : None * Return : None ****************************************************************************** */ void I2C_Stop(void) { SCL_L; I2C_delay(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SDA_H; I2C_delay(); }
仅仅是在数据传送中……
发送一字节
/******************************************************************************* * Function Name : I2C_SendByte * Description : Master Send a Byte to Slave * Input : Will Send Date * Output : None * Return : None ****************************************************************************** */ void I2C_SendByte(u8 SendByte) //发送一个字节 { u8 i=8; while(i--) { SCL_L; //SCL低 I2C_delay(); //延时不足1us if(SendByte&0x80) //若首位为1,则SDA高,否则SDA为低 SDA_H; else SDA_L; SendByte<<=1; //左移1位 I2C_delay(); //延时不足1us SCL_H; //SCL拉高 I2C_delay(); //延时不足1us } //一位数据发送结束 SCL_L; //最后再将时钟线拉低 }
接收一字节
/******************************************************************************* * Function Name : I2C_RadeByte * Description : Master Reserive a Byte From Slave * Input : None * Output : None * Return : Date From Slave ****************************************************************************** */ unsigned char I2C_RadeByte(void) //读取一个字节 { u8 i=8; u8 ReceiveByte=0; SDA_H; while(i--) { ReceiveByte<<=1; SCL_L; I2C_delay(); SCL_H; I2C_delay(); if(SDA_read) { ReceiveByte|=0x01; } } SCL_L; return ReceiveByte; }