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

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. C# TreeView使用技巧

    节点勾选设置 TreeView树中节点勾选要求: 1.不选中一个节点,则其所有的子节点都不被选中. 2.选中一个节点,则其所有的子节点都被选中. 3.当一个节点的所有子节点都没有被选中时,该节点也没有 ...

  2. emc 郵件設置

    1. 進入Data Domain管理界面后,在Administration--->Settings界面.點擊More mail Server--->Set Mail Server---&g ...

  3. android 入门-生命周期 activity

    生命周期 activity http://blog.csdn.net/android_tutor/article/details/5772285 http://www.cnblogs.com/John ...

  4. 将数据导出成excel表

    /// <summary> /// 生成excel表 /// </summary> /// <param name="dt">数据表</p ...

  5. Servlet中的GET和POST之间的区别

    自己的感悟: get和post这是http协议的两种方法,另外还有head, delete等 这两种方法有本质的区别,get只有一个流,参数附加在url后,大小个数有严格限制且只能是字符串.post的 ...

  6. Unity3D项目开发一点经验

    我们主要使用3dsmax2010进行制作,输出FBX的类型导入Unity3D中.默认情况下,3dsmax8可以和U3D软件直接融合,自动转换为FBX物体. 注意事项如下: 1.面数控制 在MAX软件中 ...

  7. HDU 5213 Lucky 莫队+容斥

    Lucky Problem Description WLD is always very lucky.His secret is a lucky number K.k is a fixed odd n ...

  8. Activity之间传递数据的方式及常见问题总结

    Activity之间传递数据一般通过以下几种方式实现: 1. 通过intent传递数据 2. 通过Application 3. 使用单例 4. 静态成员变量.(可以考虑 WeakReferences) ...

  9. Big Event in HDU

    Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe ...

  10. 标准W3C盒子模型和IE盒子模型

    标准W3C盒子模型和IE盒子模型   CSS盒子模型:网页设计中CSS技术所使用的一种思维模型. CSS盒子模型组成:外边距(margin).边框(border).内边距(padding).内容(co ...