本篇博文最后修改时间:2016年4月11日,05:04。
一、简介
本篇介绍如何在SimpleBLEPeripheral工程中,采集DHT11的温湿度值。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF(主芯片CC2541)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.net/feilusia
联系方式:[email protected]
技术交流QQ群(香瓜BLE之CC2541):127442605
四、基础知识
1、DHT11是什么?
答:DHT11是一个数字温湿度传感器,里面包括1个电阻式感湿元件和1个NTC测温元件,并与1个高性能8位单片机相连接。
1)湿度
测量范围:20-90%
精度:±5%RH
2)温度
测量范围:RH 0-50 ℃
精度:±2 ℃
2、如何硬件连接DHT11?
答:
如上图,DHT11虽然有4个引脚,但实际上只用到3个,剩一个悬空。(模块最终会只引出3个引脚)
第2引脚可以用MCU的一个IO口进行单线双向传输数据。
注:本文中使用CC2541的P0_0口连接DHT11的第2引脚。
五、实验前提
在进行本文步骤前,请先完成以下博文的步骤:
《CC2541之串口收发》:http://blog.csdn.net/feilusia/article/details/47431659
六、代码修改
1、编写并添加DHT11驱动
1)写一个DHT11.c(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//****************************************************************************** //name: DHT11.c //introduce: 读取DHT11温湿度 //author: 甜甜的大香瓜 //changetime: 2016.04.11 //email: [email protected] //****************************************************************************** //map #include "DHT11.h" #include <ioCC2540.h> #include "string.h" //define #define DATA_PIN P0_0 //输入口为P0.0 #define SET_PIN_IN P0DIR &= ~0x01; asm("NOP"); asm("NOP") //配置IO为输入 #define SET_PIN_OUT P0DIR |= (1 << 0); asm("NOP"); asm("NOP") //配置IO为输出 #define SET_DATA_PIN DATA_PIN = 1; asm("NOP"); asm("NOP") //拉高P0.0 #define CLR_DATA_PIN DATA_PIN = 0; asm("NOP"); asm("NOP") //拉低P0.0 typedef signed char int8; typedef unsigned char uint8; typedef signed short int16; typedef unsigned short uint16; typedef signed long int32; typedef unsigned long uint32; //function static void Delay_Us(uint16 nUs); static uint8 DHT11_Read_Char(void); //****************************************************************************** //name: Delay_Us //introduce: us延时函数 //parameter: nUs:us数 //return: none //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.11 //****************************************************************************** static void Delay_Us(uint16 nUs) { while (nUs--) { asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); asm("NOP");asm("NOP");asm("NOP");asm("NOP"); } } //****************************************************************************** //name: DHT11_Read_Char //introduce: DHT11的读单个字节函数 //parameter: none //return: none //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.11 //****************************************************************************** static uint8 DHT11_Read_Char(void) { uint8 i; uint8 nDht11_bit; uint8 nDht11_char; uint8 nFLAG; for(i=0; i < 8; i++){ nFLAG = 2; while((DATA_PIN == 0) && (nFLAG++)); Delay_Us(19); if(DATA_PIN == 1){ nDht11_bit = 1; } else{ nDht11_bit = 0; } nFLAG = 2; while((DATA_PIN == 1) && (nFLAG++)); if(nFLAG == 1){ break; } nDht11_char <<= 1; nDht11_char |= nDht11_bit; } return nDht11_char; } //****************************************************************************** //name: DHT11_Read_Humiture //introduce: DHT11的读温湿度函数 //parameter: none //return: TRUE:读取正确,FALSE:读取错误 //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.11 //****************************************************************************** boolean DHT11_Read_Humiture(uint8 *pDHT11_data) { uint8 nHumidity_integer; uint8 nHumidity_decimal; uint8 nTemperature_integer; uint8 nTemperature_decimal; uint8 nChecksum; uint8 nChecksum_count; uint8 nFLAG; //主机开始信号 SET_PIN_OUT; //IO口配置为输出 SET_DATA_PIN; //输出高电平 CLR_DATA_PIN; //输出低电平 Delay_Us(20000); //延时至少18MS SET_DATA_PIN; //输出高电平 Delay_Us(20); //切换到DHT11端发数据 SET_PIN_IN; //IO口配置为输入 Delay_Us(20); if(DATA_PIN == 0) { //DHT11响应 nFLAG = 2; while((DATA_PIN == 0) && (nFLAG++)); nFLAG = 2; while((DATA_PIN == 1) && (nFLAG++)); //DHT11读值 nHumidity_integer = DHT11_Read_Char(); //湿度高位,整数 nHumidity_decimal = DHT11_Read_Char(); //湿度低位,小数 nTemperature_integer = DHT11_Read_Char(); //温度高位,整数 nTemperature_decimal = DHT11_Read_Char(); //温度低位,小数 nChecksum = DHT11_Read_Char(); //校验和 //结束 SET_DATA_PIN; //计算校验和 nChecksum_count = nHumidity_integer + nHumidity_decimal + nTemperature_integer + nTemperature_decimal; //验证数据正确性 if(nChecksum == nChecksum_count) { //正确,则将读出的值保存到全局变量 pDHT11_data[0] = nHumidity_integer; pDHT11_data[1] = nHumidity_decimal; pDHT11_data[2] = nTemperature_integer; pDHT11_data[3] = nTemperature_decimal; } else { //错误,则值全为0 pDHT11_data[0] = 0; pDHT11_data[1] = 0; pDHT11_data[2] = 0; pDHT11_data[3] = 0; return DHT11_FALSE; } } else { //错误,则值全为0 pDHT11_data[0] = 0; pDHT11_data[1] = 0; pDHT11_data[2] = 0; pDHT11_data[3] = 0; return DHT11_FALSE; } return DHT11_TRUE; }
//****************************************************************************** //name: DHT11.h //introduce: 读取DHT11温湿度 //author: 甜甜的大香瓜 //changetime: 2016.04.11 //email: [email protected] //****************************************************************************** #ifndef __DHT11_H__ #define __DHT11_H__ //define typedef enum{ DHT11_TRUE, DHT11_FALSE }boolean; //function extern boolean DHT11_Read_Humiture(unsigned char *pDHT11_data); //温湿传感启动 #endif
4)在IAR设置中添加香瓜任务的源文件路径
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
1)定义DHT11采集事件、DHT11串口发送事件(SimpleBLEPeripheral.c的SimpleBLEPeripheral_ProcessEvent中)
//香瓜 //周期采集DHT11温湿度事件 if ( events & SBP_DHT11_READ_HUMITURE_EVT ) { //关总中断,不关会出现0的数据 EA = 0; //采集DHT11温湿度 DHT11_Read_Humiture(sbDHT11_data); //开总中断 EA = 1; //启动定时器执行串口打印DHT11温湿度事件 osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_DHT11_USART_EVT, SBP_DHT11_USART_EVT_PERIOD ); //启动定时器执行周期采集DHT11温湿度事件 osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_DHT11_READ_HUMITURE_EVT, SBP_DHT11_READ_HUMITURE_EVT_PERIOD ); return (events ^ SBP_DHT11_READ_HUMITURE_EVT); } //串口打印DHT11温湿度事件 if ( events & SBP_DHT11_USART_EVT ) { uint8 nString[15] = {0}; //温度 sprintf((char *)nString, "DHT11 temp: %d.%d", sbDHT11_data[2], sbDHT11_data[3]); NPI_PrintString(nString); NPI_PrintString("\r\n"); //湿度 sprintf((char *)nString, "DHT11 humi: %d.%d", sbDHT11_data[0], sbDHT11_data[1]); NPI_PrintString(nString); NPI_PrintString("\r\n"); //多几个换行便于查看串口数据 NPI_PrintString("\r\n"); NPI_PrintString("\r\n"); return (events ^ SBP_DHT11_USART_EVT); } //香瓜
#define SBP_DHT11_READ_HUMITURE_EVT 0x0004 //周期采集DHT11温湿度事件 #define SBP_DHT11_USART_EVT 0x0008 //串口打印DHT11温湿度事件
//香瓜 #define SBP_DHT11_USART_EVT_PERIOD 10 #define SBP_DHT11_READ_HUMITURE_EVT_PERIOD 1000 //香瓜
if ( events & SBP_START_DEVICE_EVT ) { // Start the Device VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs ); // Start Bond Manager VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs ); // Set timer for first periodic event osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); //香瓜 //启动定时器执行周期采集DHT11温湿度事件 osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_DHT11_READ_HUMITURE_EVT, SBP_DHT11_READ_HUMITURE_EVT_PERIOD ); //香瓜 return ( events ^ SBP_START_DEVICE_EVT ); }
//香瓜 static uint8 sbDHT11_data[4] = {0}; //香瓜
//香瓜 #include "DHT11.h" #include "stdio.h" //香瓜
七、实验结果
香瓜用两台安卓手机分别连接测试,都能在连接的同时保证串口工具正常收到DHT11的数据。
并且在不停地对DHT11哈气时,可以看到温度和湿度都会升高。