本帖最后由 冒汗的心情 于 2016-4-15 16:26 编辑
CC2541用DHT11传感器采集温湿度
一、简介 文章介绍了如何在ti 的SimpleBLEPeripheral工程中,用CC2541采集DHT11的温湿度值。使用的协议栈版本:BLE-CC254x-1.4.0 编译软件:IAR 8.20.2,硬件平台:Smart RF(主芯片CC2541)。
二、基础知识 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.0ProjectsbleSimpleBLEPeripheralSourceGUA”路径下)
//******************************************************************************
//name: DHT11.c
//introduce: 读取DHT11温湿度
//author:
//changetime:
//email:
//******************************************************************************
//map
#include "DHT11.h"
#include
#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:
//changetime:
//******************************************************************************
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:
//changetime:
//******************************************************************************
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:
//changetime:
//******************************************************************************
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.0ProjectsbleSimpleBLEPeripheralSourceGUA”路径下)
//******************************************************************************
//name: DHT11.h
//introduce: 读取DHT11温湿度
//author:
//changetime:
//email:
//******************************************************************************
#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$....SimpleBLEPeripheralSourceGUA
2、添加DHT11相关事件
1)定义DHT11采集事件、DHT11串口发送事件(SimpleBLEPeripheral.c的SimpleBLEPeripheral_ProcessEvent中)
//香瓜
//周期采集DHT11温湿度事件
if ( events & SBP_DHT11_READ_HUMITURE_EVT )
{
//关总中断,不关会出现0的数据
EA = 0;
//采集DHT11温湿度
DHT11_Read_Humiture(***DHT11_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", ***DHT11_data[2], ***DHT11_data[3]);
NPI_PrintString(nString);
NPI_PrintString("rn");
//湿度
sprintf((char *)nString, "DHT11 humi: %d.%d", ***DHT11_data[0], ***DHT11_data[1]);
NPI_PrintString(nString);
NPI_PrintString("rn");
//多几个换行便于查看串口数据
NPI_PrintString("rn");
NPI_PrintString("rn");
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 ***DHT11_data[4] = {0};
/
5、添加DHT11相关头文件(SimpleBLEPeripheral.c中)
//
#include "DHT11.h"
#include "stdio.h"
//
五、实验结果 香瓜用两台安卓手机分别连接测试,都能在连接的同时保证串口工具正常收到DHT11的数据。 并且在不停地对DHT11哈气时,可以看到温度和湿度都会升高。
|