手把手带你用FPGA设计
一个温湿度测量仪
—一、前期准备—
1、开发环境
myminieye的runber开发板,gowin软件,DHT11温湿度传感器。
2、DHT11温湿度传感器的原理
温湿度传感器SIG双向引脚接收到外部的触发信号后,先对微处理器发送应答信号,再开始温湿度数据的发送。详细的原理可参考《DHT11.pdf》,其时序图如下图所示:
在时序图中不同的信号类型对应的具体信号波形如下表所示
数据的处理:
3、 硬件连接
DHT11的VCC接3.5-5.5V直流供电,可直接由FPGA供电,GND接地,SIG为串行数据,在传感器模块已连接5.1KΩ上拉电阻,与FPGA的I/O引脚连接,闲置时为高电平。传感器的SIG引脚是双向引脚,其功能如下表所示
4、 整体设计思路
根据传感器的原理,fpga中in_out与传感器sig引脚连接的引脚应该设置为inout引脚,开始时in_out为输出状态,先输出一段时间的高电平,再输出18ms的低电平,然后in_out变为输入状态,等待传感器发送应答信号和温湿度数据。在fpga接收信号时应先判断数据的类型,接收结束后先进行校验,再选取相应位置的数据分别对温湿度数据转为十进制在数码管上显示。
在时序图中不同的信号类型对应的具体信号波形如下表所示
数据的处理:
二、具体模块设计
1、触发输出和数据读取模块
首先,DHT11传感器需要1s的上电时间,fpga的in_out引脚先输出1s的高电平,再输出18ms低电平触发信号,此时in_out的输出任务完成,应变为输入状态。DHT11发送回来的数据均以低电平开始,可根据高电平的时间来判断信号的类型。
在代码的编写上,首先设置几个重要参数,系统时钟为12MHz,输出高电平1s所需时钟周期个数DELAY=24'd12000000,输出低电平18ms所需时钟周期个数OUT=24'd216000。在开始测量的时候,设计一个计数器开始计数,具体状态的控制如下表所示
In_out变为输入状态之后,等待DHT11传感器应答信号和数据信号,设计一个计数器cnt,当in_out的输入为低电平时,计数器清0,当in_out的输入为高电平时,计数器cnt从零开始计数直到输入信号下降沿到来。
根据整个高电平期间cnt的计数来判断信号类型,判断条件如下表所示。设计一个标志信号data_en,当应答信号到来后data_en为1,此后接收到的数据为有效数据并进行存储。信号类型的判断条件的设计,应在能将信号区分开的前提下,尽可能将判断范围适当放宽一些。
数据判断与数据保存的条件
输入信号高电平期间计数器从0开始计数,到低电平时便返回0,而我们所需要的是cnt在返回0之前的最大值,因此需要创造一个判断条件表示某一时刻cnt为最大值,这里采用将信号“打一拍”的做法。将cnt“打一拍”后变为cnt1,再将cnt1打一拍后变为cnt2,代码如下图所示
将计数打一拍究竟有什么作用,先看看它的仿真图
在高电平期间,cnt一直在计数,而cnt1的计数会比cnt慢一个节奏,当下降沿到来时,cnt返回0,而此时cnt1的值是cnt在返回0之前的最大值,所以通过判断条件cnt1>cnt来判断高电平的结束,此时cnt1的值便可以用来判断信号的类型了。再打一拍得到cnt2是因为判断信号类型之后,下一个时钟周期到来cnt和cnt1都变成0了,在判断信号是“1”还是“0”之后,在下个时钟周期就需要将判断好的数据进行保存,此时cnt2>cnt1作为判断数据类型之后将数据赋值到40bit的数据中保存。
40bit数据保存的过程
DHT11输出数据时高位先出,先将40bit数据info中的低39为左移一位到高39位,将当前的数据保存在info的最低位,再将info数据左移后将下一个数据赋值到最低位
数据校验
40bit数据中,若前4byte数据相加后的低8位等于第5byte数据,则数据正确,否则校验失败。
2、数据转换模块
数据接收完成后,温湿度所对应的数据位八位二进制,为了在数码管上显示,需要将八位二进制数据转为十进制并将十进制的个位和十位用两个寄存器保存。
由于传感器的测量精度为1,小数部分可忽略,测量范围均在100以内,具体的方法可设计为温度和湿度各两个数码管显示,通过判断数据的范围确定十位的数据,个位的数据为数据减去十位数据的十倍。
3、数码管显示模块
Runber的数码管的使用需要位选和段选操作,首先将时钟分频得到较低频的时钟,控制数码管位选(sel),不同位的数码管分别显示不同的数据,利用八位二进制控制数码管八段灯的亮灭组成不同的数字。数码管每一段对应的管脚位置参考《RUNBER开发板用户手册》。
4、顶层模块
分别对各模块进行例化,每个模块只能实现单一的功能,把所需要的模块例化到顶层中是为了把各模块组合到一起,同时完成整个系统的功能。
5、引脚分配
参考《RUNBER开发板用户手册》与《runber原理图》,将输入输出端口分配到对应的引脚上
三、仿真和测试结果
在代码综合通过之后,需要进行仿真,通过仿真波形检查代码所实现的逻辑是否符合预期,仿真可实现触发信号输出和输入信号的读取,并且数码管所对应的数据也符合预期之后便可以烧录测试了。
在仿真成功后便可以下载到板卡进行测试,同时用示波器测量sig引脚信号的波形,结果如下图所示。
图中第一个高电平位in_out变为输入状态时,传感器还未发送应答信号,连接上拉电阻会默认为高电平,中间会有一个短暂的高电平信号,属于干扰信号。第二个高电平信号为应答信号。在设计上要求接收到应答信号之后才数据才有效,因此干扰信号不会对读取的数据有影响。
在示波器波形上根据DHT11输出的高电平时间可读出湿度及温度的数据,40bit的数据为:01010010(湿度整数),00000000(湿度小数),00011100(温度整数),00000000(温度小数),01101110校验位)。将数据转换为十进制可知湿度为82,温度为28,校验位110=82+28,其二进制为01101110。数码管显示的测量结果如下图所示。