作者:卢老师,华清远见嵌入式学院讲师。

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感器技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。它具有成本低,性能稳定,抗干扰能力强等优点。

其中对应引脚2int是输出引脚,连接SAM3S4B芯片PA6引脚。

DHT11器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约 4.7kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。

电气连接图

TH_DATA 接SAM3S4B的PA6引脚:

实现程序

主程序:
        int
main(void)
        {
                unsigned char
acc[3]={0,0,0};
                unsigned char temp[2]={0,0}; //data comes
from the tem-hum sensor
                unsigned char hum[2]={0,0}; //data
comes from the tem-hum sensor
                /* Initialize the SAM system
*/
                sysclk_init();
                sysTick_Config(sysclk_get_cpu_hz()
/ 1000);//interrupt in every ms
                WDT->WDT_MR =
WDT_MR_WDDIS;
                /* Configure UART pins
*/
                gpio_configure_group(PINS_UART0_PIO,PINS_UART0,PINS_UART0_FLAGS);//add
luyj
2013.5.8
                configure_console();
                pmc_enable_periph_clk(ID_PIOA);//add
by luyj 2013.5.8

                while(1)
                {
                        Read_Temp_Hum(temp,hum);
                        printf("
temp[0]=%d temp[1]=%d hum[0]=%d,hum[1]=%d\r"
,temp[0],temp[1],hum[0],hum[1]);
                        mdelay(1000)
;
                }
        }

上面的是主程序main,主要是系统时钟选为外部晶振,pll倍频cpu_hz为64Mhz,关闭看门狗,配置串口用于打印温湿度值,使能PA口的能源管理器(PMC),接下来开始每隔一秒读取温湿度。

void SetTemIntType(uint8_t
type)
        {
                switch
(type)
                {
                        case
0:
                        NVIC_EnableIRQ((IRQn_Type)
ID_PIOA);
                        pio_enable_interrupt(PIOA, PIO_PA6
);
                        pio_handler_set_priority(PIOA, (IRQn_Type)
ID_PIOA, IRQ_PRIOR_PIO);
                        pio_handler_set(PIOA,
ID_PIOA, PIO_PA6, (PIO_PULLUP | PIO_DEBOUNCE |
IRQ_FALLING_EDGE),TUM_Handler);//Interrupt on falling edge

                        break;
                        case
1:
                        NVIC_EnableIRQ((IRQn_Type)
ID_PIOA);
                        pio_enable_interrupt(PIOA, PIO_PA6
);
                        pio_handler_set(PIOA, ID_PIOA, PIO_PA6,
(PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE),TUM_Handler); //Interrupt on
rising edge
                        pio_handler_set_priority(PIOA,
(IRQn_Type) ID_PIOA,
IRQ_PRIOR_PIO);
                        break;
                        case
2:
                        pio_disable_interrupt(PIOA, PIO_PA6
);
                        break;
                        default:
                        break;
                }
        }

上面的子程序SetTemIntType();是对PA6温度采集引脚的中断使能与取消,在采集具体数据时,需要采集PA6电平保持时间,为此,必须及时响应PA6发出的上升沿和下降沿,在这里用中断实现。

DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。

校验位数据定义:
        “8bit湿度整数数据 + 8bit湿度小数数据+8bit温度整数数据 +
8bit温度小数数据”8bit校验位等于所得结果的末8位。

示例一:接收到的40位数据为:
        0011 0101 0000 0000 0001 1000 0000
0000 0100 1101
        湿度高8位 湿度低8位 温度高8位 温度低8位 校验位

计算:
        0011 0101+0000 0000+0001 1000+0000 0000= 0100 1101

接收数据正确
        湿度:0011 0101=35H=53%RH
        温度:0001
1000=18H=24℃

数据时序图:

用户主机(MCU)发送一次开始信号后,DHT11从低功耗模式转换到高速模式,待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,触发一次信采集。信号发送如图所示。

根据芯片时序图,可以看出这个芯片涉及到微秒的操作,所以利用了M3的System
Tick记时,相当精确,再根据时序可以读到数据,

温湿度读取步骤:
        第一步:DHT11上电,延时1s待稳定,测试温湿度,保存数据,DHT11的DATA数据线保持高电平,处于输入状态,检测外部信号。
        第二步:微处理器IO设为输出低电平,保持大于18ms,然后转为输入状态,等待DHT11作出应答。

程序如下:(不同的版本管脚不同)
        gpio_configure_pin(PIO_PA6_IDX
,PIO_OUTPUT_1|PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE );// Set PA6 to
output
        gpio_set_pin_low(PIO_PA6_IDX);// set to
low
        mdelay(30);
        gpio_configure_pin(PIO_PA6_IDX
,PIO_INPUT|PIO_PULLUP ); // Set io to input

首先设置为高电平输出,然后延时30毫秒,再将该端口设置为输入。

第三步:DHT11的DATA检测外部低电平结束,设为输出80微秒低电平作为应答和80微秒高电平通知外设准备接受数据,微处理器等待数据接受。

此时程序中需要延时微秒数量级所以采用了cortex-M3系列系统自带的System Tick。

以下程序作为延时:
        for(i=0; i<3;
i++)
        {
                SetTemIntType(i&0x01);//

                while(pa6_counter == cnt_last);
                cnt_last
= pa6_counter;
        }

上面这段程序的意思是:先判断是否是下降沿,当i=0,下降沿触发,继续执行,如果没有来下降沿的话,那么pa6_counter ==
cnt_last就永远是真,一直在这里阻塞,当下降沿来了,则触发了PA6中断,这个中断的处理TUM_Handler如下:

if (PIN_PUSHBUTTON_1_ID == id && PIN_PUSHBUTTON_1_MASK ==
mask)
                {pa6_tc = SysTick->VAL;

                pa6_counter++;
        }

这时候 pa6_counter ++;
pa6_counter与cnt_last不相等,跳出中断,然后重新使他们两个相等,等待i=1,重新进入循环,这时候就变成了上升沿触发,道理同上,然后再等待i=2,又变成了下降沿触发。经过这三次触发方式的改变之后,开始传输数据。

第四步:DHT的DATA输出40位数据,微处理器按高低电平接受40位数据;

位数据“0”的格式为: 50 微秒的低电平和 26-28 微秒的高电平,位数据“1”的格式为: 50
微秒的低电平加70微秒的高电平。位数据“0”、“1”格式信号如图所示:

for(i=0; i<40;
i++)
        {
                SetTemIntType(1);// enable irq rising edge

                while( pa6_counter == cnt_last);

                cnt_last = pa6_counter;
                tc1 = pa6_tc;
//此时记录一下这个时刻嘀嗒倒计时计数器里面还有剩下多少。即箭头1标记的位置时刻,还剩多少

SetTemIntType(0);//
enable irq falling edge
                while(pa6_counter ==
cnt_last);
                cnt_last = pa6_counter;

                下面的if里面的意思是如果倒计时还没有执行到0,即还没有重新装载倒计时,那么,这个时间就是箭头1的计数器的值减去箭头2的计数器的值。
                if(pa6_tc
< tc1) //比较滴答当前值和中断产生时的大小
                {
                        tc
= tc1 - pa6_tc;
//记录经过多少滴答
                }
                否则的话,就说明当读到箭头2的时候,计数器已经重新装载了,那么这段时间就是要用64000减去他们的绝对值。
                else
                {
                        tc
= 64000 - (pa6_tc -
tc1);
                }
                前八位是temp高8位:如果tc大于3200个,那么就是数据格式1了,如果小于,那么就是数据0
                if(i
< 8)
                {
                        hum_10 <<=
1;
                        if(tc >=
3200)//根据,我们的时钟频率是64MHZ,即一个脉冲需要1/64us,
                        hum_10 |=
0x01; //3200个脉冲是
3200*(1/64)us,即50us
                }
                else if(i <
16)
                {
                        hum_01 <<=
1;
                        if(tc >=
3200)
                        hum_01 |=
0x01;
                }
                else if(i <
24)
                {
                        temp_10 <<=
1;
                        if(tc >=
3200)
                        temp_10 |=
0x01;
                }
                else if(i <
32)
                {
                        temp_01 <<=
1;
                        if(tc >=
3200)
                        temp_01 |=
0x01;
                }
                else
                {
                        chksum
<<= 1;
                        if(tc >=
3200)
                        chksum |=
0x01;
                }
        }

setTemIntType(1);//
enable irq rising edge
        while( pa6_counter ==
cnt_last);
        setTemIntType(2);// disable

*temp =
temp10;
        *(temp+1) = temp01;

*hum =
hum10;
        *(hum+1) = huM31;

chk = temp10;
        chk
+= temp01;
        chk += hum10;
        chk +=
huM31;

if(chk == chksum)
                return
1;
        else
                return 0;

要不停的读40次,因为每次都读1位,最后判断校验位,如果成功就读取成功,否则丢掉该数据。

结束信号:
        DHT11发完后继续输出低电平50微秒转为输入高电平,再次检查温湿度,等待外部信号。

具体打印的当前温度

文章来源:华清远见嵌入式学院, 原文地址:http://www.embedu.org/Column/Column688.htm

基于FSIOT_A 实验平台SAM3S4B cortex-M3的温湿度采集的更多相关文章

  1. openstack(liberty):部署实验平台(一,基础网络环境搭建)

    openstack项目的研究,到今天,算是要进入真实环境了,要部署实验平台了.不再用devstack了.也就是说,要独立controller,compute,storage和network了.要做这个 ...

  2. ARM 架构、ARM7、ARM9、STM32、Cortex M3 M4 、51、AVR 之间有什么区别和联系?(转载自知乎)

    ARM架构:  由英国ARM公司设计的一系列32位的RISC微处理器架构总称,现有ARMv1~ARMv8种类. ARM7:       一类采用ARMv3或ARMv4架构的,使用冯诺依曼结构的内核. ...

  3. NFV实验平台

    NFV架构如下图所示. NFVI对应于数据平面,数据平面转发数据并提供用于运行网络服务的资源. MANO对应于控制平面,该控制平面负责构建各种VNF之间的连接以及编排NFVI中的资源. VNF层对应于 ...

  4. TurtleBot 3 & 2i ROS开源实验平台

    TurtleBot 3 & 2i ROS开源实验平台,全球更受欢迎的ROS平台. TurtleBot是ROS标准平台机器人,在全球开发人员和学生中深受欢迎.其有3个版本: TurtleBot1 ...

  5. 201871010110-李华 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 (1)理解并掌握代码风格及设计规范:(2)通过任务3进行协作开发,尝试进行代码复审,在进行同伴复审的过程中体会结对 ...

  6. 201871030108-冯永萍 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    实验三 软件工程结对项目 项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs ...

  7. 201871030125-王芬 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    实验三 软件工程结对项目 项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs ...

  8. 201871030119-马桂婷 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客 2018卓越工程师班 这个作业要求链接 实验三 软件工程结对项目 我的课程学习目标 1.体验软件项目开发中的两人合作,练习结对编程:2.掌握Github协作开发程序的操作方法 ...

  9. 201871030134-余宝鹏 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 1.体验软件项目开发中的两人合作,练习结对编程(Pair programming) 2.掌握GitHub协作开发程 ...

随机推荐

  1. PMP - 项目管理思维导图

  2. ApexSQL Log-SQL误操作恢复工具

    今天不小心对数据库执行了一次误操作,心想有没有什么工具能恢复这次误操作呢?于是找到了Log Explorer 4.2,可惜它最多只支持SQL 2005,在SQL 2008上无法使用,然后又找到了Ape ...

  3. 在IIS上部署SSL

    背景: 在处理DropboxAPI开发时,其重定向的URL地址必须是https的[除了localhost],不得已在自己网站上加了ssl,下面简单介绍下添加自签名证书,毕竟只是临时使用. 1.打开II ...

  4. 为GDI函数增加透明度处理

    用户对客户端的UI的要求越来越高,采用alpha通道对前景背景做混合是提高UI质量的重要手段. UI开发离不开GDI,然后要用传统的GDI函数来处理alpha通道通常是一个恶梦:虽然有AlphaBle ...

  5. 在windows系统的文件右键菜单中增加“命令提示符”

    本实用小工具能够在windows系统的文件右键菜单中增加“命令提示符”,方便快速进入制定文件的命令提示窗口,避免逐层输入或复制文件夹路径,极其实用. 工具下载地址如下:360云盘(访问密码:5b71) ...

  6. Android NDK开发实例教程

    WINDOWS系统+ Eclipse + NDK+Android 最近开始学习Android平台开发,Android还没有玩转,Java也是刚入门,这又要开始在Android中调用C语言,需要利用ND ...

  7. [转载]void及void*的深度剖析

    void的含义 void即"无类型",void *则为"无类型指针",可以指向任何数据类型. void指针使用规范 ①void指针可以指向任意类型的数据,亦即可 ...

  8. Liferay 6.2 改造系列之二十三:修改Liferay原始主题中"技术支持:Liferay"字样

    1.修改主题模板文件,具体位置如下 (1) portal-master\portal-web\docroot\html\themes\_unstyled\templates\portal_normal ...

  9. SU suxcontour命令学习

  10. happypack 原理解析

    说起 happypack 可能很多同学还比较陌生,其实 happypack 是 webpack 的一个插件,目的是通过多进程模型,来加速代码构建,目前我们的线上服务器已经上线这个插件功能,并做了一定适 ...