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

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# 创建Windows Service

    当我们需要一个程序长期运行,但是不需要界面显示时可以考虑使用Windows Service来实现.这篇博客将简单介绍一下如何创建一个Windows Service,安装/卸载Windows Servi ...

  2. x264 - 高品质 H.264 编码器

    转自:http://www.5i01.cn/topicdetail.php?f=510&t=3735840&r=18&last=48592660 H.264 / MPEG-4 ...

  3. linux文本模式下使用PPPOE拨号ADSL上网的方法

    转自:http://www.myzhenai.com.cn/post/945.html 转载请注明出处:http://www.myzhenai.com/thread-15431-1-1.html ht ...

  4. Unity3d 提示 "The scripts file name does not match the name of the class defined in the script!"的解决办法

    有两个原因,一个是文件的名称和类名不一致 第二个原因是有命名空间, 排除应该是可以修复的

  5. 直接拿来用!最火的Android开源项目(二)(转)

    GitHub上的开源项目不胜枚举,通过这些项目,也能让开发者在应用开发过程中事半功倍,作为开发者的你,在用这些开源项目吗?今天我们将介绍另外20个在GitHub上备受欢迎的Android开源项目,你准 ...

  6. ZEALER背后的乐视云视频

    ZEALER是我非常喜欢的一个测评网站,经常访问看看手机.电动牙刷及机械键盘的测试视频,非常欣赏王自如的数据化测评理念.敬畏之心,以及不祛痘的视频. 刚好最近对网络视频应用比较感兴趣,觉得ZEALER ...

  7. LoadRunner 脚本学习 -- 指针基础

    先搞清楚 ++a 和 a++的区别 ++a : 前缀++,  先自增,后表达式 a++ : 后缀++,  先表达式,后自增 前缀,自增立即生效. 后缀,下次才会看到效果. 一维数组的指针 Action ...

  8. 【MongoDB】2.可视化工具的安装和使用

    首先:关于  能支持MongoDB新版本的可视化工具,争议不断,各人都有各人的支持. 因此之前选择安装的时候就安装了MongoDB  3.0.14版本的. 最终,确定使用Robomongo作为我第一个 ...

  9. LR连接oracle时出现:SQLState=28000[Oracle][ODBC][Ora]ORA-01017:invalid username/password;logon denied

    出现的现象:

  10. ce游戏内存修改器(Cheat Engine)

    ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...