FPGA 20个例程篇:5.温度传感器实时采集温度

您所在的位置:网站首页 温度采集模块常见故障 FPGA 20个例程篇:5.温度传感器实时采集温度

FPGA 20个例程篇:5.温度传感器实时采集温度

2023-05-31 09:38| 来源: 网络整理| 查看: 265

二、常用通信协议,摸索探究: 5.温度传感器实时采集温度

       温度传感器、重力传感器等等这些传感器模块在生活中有非常广泛的应用,只是可能大家平时没有留心去观察。举个现实中的例子,比如我们经常用的平板电脑或者电子书阅读器都有“自动旋转”的功能,这里面其实就是用了重力传感器,硬件上重力传感器去检测当前用户使用设备的姿势,并传入SOC芯片一个信号,软件上再根据该信号去改变屏幕的旋转角度。同样的温度传感器也使用广泛,因为现在很多的嵌入式产品都带有温度显示或者温度检测的功能,这里毫无疑问都会用到温度传感器去实时采集当前设备的温度,其中典型的就有:LM75和DS18B20,它们是实际应用最多的两种温度传感器。

        如图1所示,豌豆开发板上配有一颗NXP原装的LM75温度传感器,同时LM75也是一款支持IIC通信的外设,在这个例程中通过读取LM75的当前采样温度,我们也实际动手用verilog实现IIC的底层时序逻辑,IIC通信协议在实际工作中很常用,相信大家在学习实践过这个例程后一定可以触类旁通,举一反三地去完成后续例程的相关设计。

 图1 豌豆开发板Artix7上LM75电路

        IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备,是典型的半双工通信方式,IIC总线有两根双向的信号线一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步,如图2所示是IIC总线的硬件拓扑结构,在一般情况下硬件上对于SDA和SCL都会连接4.7K或10K上拉电阻。

 图2 IIC总线的硬件拓扑结构

       对于IIC总线协议,虽然属于低速总线,但其较UART和SPI相对复杂些,笔者上学读书的时候在学习这部分内容,看了很多相关的教程,对此说得也都模糊不清,随着工作的积累,在工作以后实践才慢慢搞清楚IIC总线的通信原理和底层逻辑,在这里笔者把对IIC总线协议的总结和理解详细地分享给大家。

        IIC因为其总线硬件结构简单,成本较低,在各个领域得到了广泛的应用。IIC 标准速率为 100kbit/s,快速模式为 400kbit/s,是一种多主机总线,连接在IIC总线上的器件分为主机和从机,主机有权发起和结束一次通信,而从机只能被主机呼叫;当总线上有多个主机同时启用总线时,IIC也具备冲突检测和仲裁的功能来防止错误产生;每个连接到IIC总线上的器件都有一个唯一的地址(7bit),且每个器件都可以作为主机也可以作为从机,但同一时刻只能有一个主机,总线上的器件增加和删除不影响其他器件正常工作;IIC总线在通信时总线上发送数据的器件为发送器,而接收数据的器件为接收器,如下图3所示是IIC总线的通信示意图。

 图3 IIC总线通信示意图

      如图4所示是IIC总线从机寻址示意图,IIC总线上数据传输是广义的,既包括地址又包括数据。主机在发送起始信号后必须先发送一个字节的数据,该数据的高7位为从机地址,最低位表示后续字节的传送方向,其中0表示主机发送数据,1表示主机接收数据;总线上所有的从机接收到该字节数据后都将这7位地址与自己的地址进行比较,如果相同,则认为自己被主机寻址,然后再根据第8位将自己定为发送器或接收器。

 

图4 IIC总线从机寻址示意图

      如图5所示非常形象地说明了IIC总线的起始信号S和终止信号P的电平变化,SCL为高电平时,SDA由高变低表示起始信号,SCL为高电平时,SDA由低变高表示停止信号,起始信号和停止信号都是由主机发出,起始信号产生后总线处于占用状态,停止信号产生后总线处于空闲状态。

 图5 IIC总线起始信号S和终止信号P示意图

      如图6所示是IIC总线主从机应答示意图,IIC总线通信时每个字节为8位长度,数据传送时,先传送最高位,后传送低位,发送器发送完一个字节数据后接收器必须发送1位应答位来回应发送器即一帧共有9位。

 图6 IIC总线主从机应答示意图

       如图7所示是 IIC总线数据保持和建立时间示意图,IIC总线在进行数据传送时,时钟线SCL为低电平期间发送器向数据线上发送一位数据,在此期间数据线上的信号允许发生变化,时钟线SCL为高电平期间接收器从数据线上读取一位数据,在此期间数据线上的信号不允许发生变化,必须保持稳定。

 图7 IIC总线数据保持和建立时间示意图

结合上面的具体说明,我们可以对IIC总线通信过程和寻址方式归纳如下:

1.主机发送起始信号启用总线;

2.主机发送一个字节数据指明从机地址和后续字节的传送方向;

3.被寻址的从机发送应答信号回应主机;

4.发送器发送一个字节数据;

5.接收器发送应答信号回应发送器;

… … (循环步骤4、5)

n.通信完成后主机发送停止信号释放总线

        可能有的同学看完上面的说明和介绍后,还是对IIC总线协议有些不太理解,那么下面笔者就画图进行更加细节上的说明,如图8、9、10所示是典型的IIC总线通信时序图,其中阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送,A表示应答,A非表示非应答,S表示起始信号,P表示终止信号,图片非常直观明了,对照上面的归纳总结很容易理解,所以在这里不过多赘述了,如果还存在疑问,那么请大家一起来学习实践完这个例程后就会自然而然地理解了。 

图8 IIC总线主机向从机发送数据示意图

图9 IIC总线从机向主机发送数据示意图

 图10 IIC总线主机先向从机发送数据,然后从机再向主机发送数据示意图

      在熟悉了IIC总线通信的底层逻辑后,我们回过头来再阅读NXP的LM75芯片手册,把对于FPGA设计上的有效信息提取出来,这时候结合实例,回顾前面介绍的IIC总线协议知识就更容易加深理解了。

      如图11所示是LM75的地址定义说明,正如前面所说,IIC总线上每个设备都有唯一的标识地址,这里手册写得很清楚对于LM75的7位地址,高4位固定是4 'b 1001,而对于低3位则有A2、A1、A0决定,如果在PCB板上连接到GND是逻辑0,如果连接到VCC是逻辑1,在原理图中我们把LM75的三个引脚都接GND了,所以LM75的7位地址是7 'b 1001000,然后大家需要注意在IIC通信过程中主机发送地址时,前7位是从机的物理地址,最后1位是0表示主机发送数据,1表示主机接收数据,在这个例程中我们需要对LM75读取采集温度数据,所以主机发送地址的应该是8'b10010001。

 图11 LM75的地址定义说明

       如图12所示是LM75中对MSB和LSB数据的定义,手册里标明了温度传感器的有效最低分辨率是0.125摄氏度,MSB的8位和LSB的前3位共同组成了一个11位的有效采集数据,而这个数据即是当前温度值的补码,所谓补码即正数的补码是它本身,负整数的补码是符号位不变,其余位按位取反加一!

 图12 LM75中对MSB和LSB数据的定义

       进一步地,如图13所示是LM75的温度采集数据解析示意图,举例说明11位的采集数据应该怎么计算,再具体折合成当前的温度值,感兴趣的同学可以把表中的例子动手算一算,其实说到底当前的温度值即上述11位的有效采集数据取原码值再乘以0.125即可。

 图13 LM75的温度采集数据解析示意图

       如图14所示是LM75读温度采集值的IIC时序逻辑图,LM75也有几种不同类型的IIC读写逻辑,感兴趣的同学可以仔细深入研究下芯片手册,当然下面这种用法是LM75最普遍的读取方式,介绍到这里大家不妨可以回过头看一看这和前面的图2-27的IIC总线通信时序图恰好完全吻合,即IIC总线主机先向从机发送数据,然后从机再向主机发送数据。

 图14 LM75读温度采集值的IIC时序逻辑图

       在详细说明IIC总线协议的通信细节,以及提取LM75温度传感器的有效信息后,下面就到了具体编码的环节,在这个例程中我们实现如下功能:每次用户按下豌豆开发板按键,即会触发一次LM75采集当前温度的动作,FPGA再把LM75采集到的温度数据从BCD码转换成ASCII码,最后通过RS232打印到上位机串口助手上显示。

        这里需要两个核心模块即i2c_lm75和lm75bcd_ascii,前者是LM75的IIC读取控制模块,后者是将LM75读取后的MSB和LSB组成的16位数据转换成对应温度的ASCII码模块,如表1和2所示是两个模块的信号列表,下面简要说明两个模块的核心设计内容。

信号列表

信号名

I/O

位宽

clk

I

1

rst_n

I

1

lm75_en

I

1

i2c_sda

I/O

1

i2c_scl

O

1

lm75_dout

O

16

lm75_dout_vld

O

1

表1 i2c_lm75模块信号列表

信号列表

信号名

I/O

位宽

clk

I

1

rst_n

I

1

din

I

16

din_vld

I

1

lm75_fifo_rdy

I

1

lm75_ascii_dout

O

8

lm75_ascii_dout_vld

O

1

表2 lm75bcd_ascii模块信号列表

       对于i2c_lm75模块,需要在这里介绍FPGA中对三态门的设计,典型地如IIC,MDIO等等接口,对于FPGA来说是inout信号,即是输出信号同时也是输入信号,一般性的设计方法即是用dir信号区分,dir信号为高对于FPGA表示输出,dir信号为低对于FPGA表示输入。如下图15所示是FPGA控制IIC总线的三态门示意图,通过i2c_sda_dir信号控制i2c_sda_out和i2c_sda_in信号作为FPGA的输出和输入,再连接到外围器件的i2c_sda上,这样设计也简化了代码的逻辑,提高了代码的可读性。

图15 FPGA控制IIC总线的三态门示意图     

        如图16所示是LM75读取温度采集数据的状态机,模块中选取SCL是250Khz时钟,大家回过头对照前面的说明,就可以非常清晰地理解整个模块的状态机设计思想了,在这里不再赘述了,LM75的IIC读取控制模块的整体代码设计如图17所示,搞清楚逻辑后,就非常容易理解。

 图16 LM75读温度采集数据的状态机

图17 IIC读取LM75采样温度模块的代码设计

       在lm75bcd_ascii模块中,我们需要把从LM75读到的MSB+LSB组成的16位数据转化成ASCII码,通过前面阅读LM75数据手册,大家了解到这16位数据,只有前11位是有效的,其中最高位0代表温度为正值,1代表温度为负值,同时如果是负值则需要把当前温度值取补码再做计算,最后把10位的采集数据值乘0.125摄氏度,即为当前采样温度值,考虑到是乘0.125即除8的关系,所以在模块设计中笔者需要对已经取补码后的10位的lm75_value值再做处理:前7位直接作为整数位,这样就完成了右移3位即除8的效果,后3位作为小数位将其转化成0、125、250、375、500、675、750、875,然后整数位百位、十位、个位逐位取整并转换成ASCII 码,同样的小数位也第一位、第二位、第三位逐位取整并转换成ASCII码,温度正负号、小数点前三位、小数点、小数点后三位、回车行组成72位9个ASCII码写入FIFO中,下游的串口发送模块再把FIFO中的数据打印到上位机的串口调试助手上,如图18所示是该模块的代码设计,供大家参考。

图18 BCD码转ASCII码模块的代码设计

       如图19所示是温度传感器实时采集温度顶层文件的例化,大家把各个模块之间的相关信号例化到一起即可,这里key_scan和uart_transfer模块在前面的例程中已经详细说明,忘记的同学可以回过头复习下,笔者也在工程里加入了ILA方便大家上板观察信号波形,如图20所示是该例程的上板现象,按下豌豆开发板按键,即可触发一次LM75采集温度,再转换成ASCII码打印到串口助手上显示。

图19 温度传感器实时采集温度顶层文件的例化

图20 串口调试助手打印温度采集值

源工程代码下载链接(含datasheet):

链接:https://pan.baidu.com/s/1pxKyQ5hSkqMApxkb0OhMfw  提取码:54es   



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3