现在上很多传感器都支持IIC协议进行核板子的通信,除了IIC之外还有SPI,以及串口Usart通信。其中,我认为最有价值的就是IIC,首先他的通信协议十分简单,对硬件的依赖也很低,正所谓越简单越可靠,IIC的通信使得成为传感器传输数据的最佳方式,越来越多的芯片开发商会将芯片的通信方式中加上IIC。
讲完了IIC的优点,一般来讲IIC的通信格式,不过,这个地方的知识,很多都会谈到,在这里就不赘述。我要讲述的,是具体使用阶段的小细节。
如图说是,这个是温湿度传感器数据手册中的图谱,这个图大家都知道是是传送信号“1”,“0”的图,只有信号稳定时传输才有意义。然而,由于芯片不一样,虽说大家都按照IIC的通信协议写,格式虽然小童,但是在速率上却是有些许不同的。正如我这个项目里的工程,在调用IIC时,由于在这个传输起始信号,停止信号例如这样的"0","1"码上没有延时足够,导致芯片传输数据失败。
正如界面里看到的,我在使用两个传感器时,改变了延时。这种情况在主频不同的单片机的实验中时有发生。
正确情况: 错误情况:
由于我的代码在初始化阶段会有一个初始化显示,这一段是上电检查传感器是否读值正常
void Check_PowerOn(void)
{
unsigned char value = 0;
//检测SH20
I2C_ReadByte(0X40, 0XE7, &value); //读取用户寄存器
if(value)
{
UsartPrintf(USART_DEBUG, "1. SHT20 :Ok\r\n");
checkInfo.SHT20_OK = DEV_OK;
UsartPrintf(USART_DEBUG, " value:%d\r\n", value);
}
else
UsartPrintf(USART_DEBUG, " SHT20 :Error\r\n\n");
DelayXms(1);
value = 0;
//检测CJ_8118
I2C_ReadByte(0x5A,0x20, &value); //读取用户寄存器
if(value)
{
UsartPrintf(USART_DEBUG, " CJ_8118 :Ok\r\n\n");
checkInfo.CJ8118_OK = DEV_OK;
UsartPrintf(USART_DEBUG, " value:%d\r\n", value);
}
else
UsartPrintf(USART_DEBUG, " CJ_8118 :Error\r\n");
DelayXms(1);
}
void Init_8118() //CCS811初始化
{
unsigned char Information[10];
unsigned char MeasureMode=0,Status=0,Error_ID=0;
// IIC_SpeedCtl(CCS_time);
CJ_8118_Read(0x20,Information,1); //读取CCS811的信息 ID
CJ_8118_Read(0x23,&Information[1],2); //进入boot 模式,建议不要更改,延时即可
CJ_8118_Read(0x24,&Information[3],2); //进入app模式,可以开始读取数据
CJ_8118_Read(0x00,&Status,1); //判定状态
// UsartPrintf(USART_DEBUG, " Status=%x\r\n",Status); //验证CJ8118的Status寄存器的值,符合要求
if(Status&0x10) //若Status=0x10,则表明已经进入app模式,可以开始读取数据
MWrite_8118(0xF4); //用于从启动到应用模式的ccs811状态过渡,写没有数据的要求
CJ_8118_Read(0x00,&Status,1); //读取测量模式寄存器的状态
CJ_8118_Read(0x01,&MeasureMode,1);
Write_8118(0x01,0x10); //写测量模式寄存器,设定为每一秒测试一次,无中断
CJ_8118_Read(0xE0,&Error_ID,1);
// UsartPrintf(USART_DEBUG,"Error:%d\r\n",Error_ID); //检测CJ811的状态,反馈错误传感器错误
}
这里为了大家看得情况,我从相关C文件中截取出来,按照代码的运行顺序排列出来,错误情况的出现正式由于我注释了 IIC_SpeedCtl(CCS_time)函数
在我学习STM32F4系列板子时,对IIC有一点疑问。当时我正对STM32板子产生憧憬之情,也享受到库函数带来的配置函数的快感,相信库函数的程序胜过自己。在STM32板子上,也有关于IIC的内容,不过那是硬件电路的,我们只需要调用函数即可,不过,在具体实践中,我从原子的视频中得知STM32虽然拥有IIC的硬件电路,但是可靠性却说没有那么优秀,在具体使用时,用软件模拟IIC通信的可靠性更高,而且,会更加方便。
一般在IIC通信中,各个IIC从器件都会有一个位置地址,紧接着是器件的寄存器地址,
位置地址很容易理解,IIC允许多机通信,是因为位置地址的作用,如果没有位置地址,那么模块之间传递信息时肯定会失灵,数据会紊乱。
比如上图中的0x34(SHT20),0x81(CJ8118),0xfe(EEROM)就是从不同IIC期间里读出的值。
不过,并不是每种的芯片都是相同的,在SHT20里你可以发现地址是0x81和0x80
这个是SHT20
在上文一个段落,进行检测是,输入0x40作为地址,I2C_ReadByte(0X40, 0XE7, &value); //读取用户寄存器
是因为IIC地址通常是7位的,为了分辨读写操作 0x40<<1 =0x80,对吧就是这样
这个是CJ8118的
I2C_ReadByte(0x5A,0x20, &value); //读取用户寄存器 和上一段落的代码也是对应的。
除去IIC的位置地址,还有IIC器件的寄存器地址,这些寄存器地址才是我们获取数据,改变IIC器件工作方式的方法,这个部分各个IIC是不一统一的。
除了这种IIC期间,我还见过一种留出A0,A1,A2三个接口放我们自己定义IIC器件的物理地址。2*2*2=8种,地址自然支持8种不同的统一器件接入同一个IIC总线中。所以,大家在拿到一个IIC器件时,不要相当然的认为器件是怎么使用的,要首先看数据手册中的具体通信方式。虽然总体按照物理地址-寄存器地址-读/写的数据格式下来,但还是有不一样的地方的。所以在接上IIC总线上时有方向的调试,必要时通过串口打印方式判断出现错误的地方。
嗯,在使用CJ8118气体检测模块时,我曾经一度崩溃,因为只知道自己的程序不可以运行,却不知道自己到底是哪一步的问题,直到我利用串口打印的方式为自己的每一步进行记录。
串口打印很简单,毕竟串口的配置大家都是清楚的,而且不在本次的讲解范围内。
不过串口打印真的用起来很舒服,在调试程序中可以通过打印的数据直接定位到自己的错误地点,对修改自己不报错误的BUG十分有用。
同理,作品完成时,千万不要吝啬加指示灯(常)。
"/"***************************切割线**********************"/"
第一次写东西,如果不对的地方还请批评指正,希望对你也有所收获。
在此感谢在这个项目的实践上,中移onenet给予的支持。
原创作品,未经权利人授权禁止转载。详情见转载须知。 举报文章
我要举报该内容理由
×