本篇博文最后修改时间:2017年01月06日,11:06。
一、简介
本文介绍如何在SimpleBLEPeripheral工程中,采集DHT11的温湿度值。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF(主芯片CC2541)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
五、基础知识
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引脚。
六、实验步骤
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: 897503845@qq.com
//******************************************************************************
//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: 897503845@qq.com
//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: 897503845@qq.com
//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: 897503845@qq.com
//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;
}
2)写一个头文件DHT11 .h(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//******************************************************************************
//name: DHT11.h
//introduce: 读取DHT11温湿度
//author: 甜甜的大香瓜
//changetime: 2016.04.11
//email: 897503845@qq.com
//******************************************************************************
#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
3)工程中添加DHT11 .c和DHT11 .h
4)在IAR设置中添加香瓜任务的源文件路径
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
2、添加DHT11相关事件
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);
}
//香瓜
2)定义DHT11采集事件、DHT11串口发送事件的宏(SimpleBLEPeripheral.h中)
#define SBP_DHT11_READ_HUMITURE_EVT 0x0004 //周期采集DHT11温湿度事件
#define SBP_DHT11_USART_EVT 0x0008 //串口打印DHT11温湿度事件
3)添加用到DHT11采集事件、DHT11串口发送事件用到的定时时间宏(SimpleBLEPeripheral.c中)
//香瓜
#define SBP_DHT11_USART_EVT_PERIOD 10
#define SBP_DHT11_READ_HUMITURE_EVT_PERIOD 1000
//香瓜
3、添加调用DHT11采集事件(SimpleBLEPeripheral.c的SimpleBLEPeripheral_ProcessEvent中的SBP_START_DEVICE_EVT事件)
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 );
}
4、添加DHT11的数据缓存区(SimpleBLEPeripheral.c中)
//香瓜
static uint8 sbDHT11_data[4] = {0};
//香瓜
5、添加DHT11相关头文件(SimpleBLEPeripheral.c中)
//香瓜
#include "DHT11.h"
#include "stdio.h"
//香瓜
七、注意事项
暂无
八、实验结果
香瓜用两台安卓手机分别连接测试,都能在连接的同时保证串口工具正常收到DHT11的数据。
并且在不停地对DHT11哈气时,可以看到温度和湿度都会升高。