【入门级求助】-基于zigbee2530的DHT11传感(含源代码和注释)
我自己觉得zigbee开发板一个测量并传输芯片内部实验不好玩,自己又设计了2个
首先我自己买了一个18B20测温度,连接成功后,又买了一个DHT11,在18B20代码上修改的,但是出了些问题:
我在单片机上使用DHT11是成功的(含串口通信),移植到zigbee中的,大家看看出了那些问题:(主要在171 187行)
/***********************************************************************************zigbee?2530?DHT11?湿度 zigbee CC2530 DHT11 传感器
Filename: SensorTXRX.c
Description: DHT11 温湿度传感器
我的思路:移植自 单片机,在18B20温度传感器基础上改的,但是传输的结果总是默认值
***********************************************************************************/
typedef unsigned char U8;//魏然2013年2月23日
typedef unsigned int U16;//wrwrwrwrwr
U8 U8FLAG,U8temp;//从DATA总线上读到的位值
U8 U8comdata;//从DHT11读取的一个字节的数据///????????????????????????????????
#define set_DQ_in P1DIR &= ~0x40 //P1.5
#define set_DQ_out P1DIR |= 0x40
U8 shidu_shi,shidu_ge,wendu_shi,wendu_ge;
U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;//校验过的温度高8位,温度低8位,湿度高8位,湿度低8位,校验和8位
U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;//未经校验的数据
//sbit P2_0 = P2^2;//此端口是数据输入端
//U8 dispbuf1[]="hum= temp= \n"; //用于串口通讯的字符数组。
U8 table1[]="0123456789";
/***********************************************************************************
* INCLUDES
*/
#include <hal_lcd.h>
#include <hal_led.h>
#include <hal_joystick.h>
#include <hal_assert.h>
#include <hal_board.h>
#include <hal_int.h>
#include "hal_mcu.h"
#include "hal_button.h"
#include "hal_rf.h"
#include "util_lcd.h"
#include "basic_rf.h"
#include "Uart.h"
#include "mydefine.h"
#include "ioCC2530.h"
/***********************************************************************************
* CONSTANTS
*/
// Application parameters
#define RF_CHANNEL 25 // 2.4 GHz RF channel
// BasicRF address definitions
#define PAN_ID 0x2007
#define SWITCH_ADDR 0x2520
#define LIGHT_ADDR 0xBEEF
#define APP_PAYLOAD_LENGTH 10
#define WENDU_CMD 0
#define GUANG_CMD 1
#define ZHENG_CMD 2
// Application states
#define IDLE 0
#define SEND_CMD 1
// Application role
#define NONE 0
#define SWITCH 1
#define LIGHT 2
#define APP_MODES 2
#define LED_BlUE 1
#define LED_RED 2
#define LED_YELLOW 3
/***********************************************************************************/
/**********************************************************************************/
static uint8 pRxData[APP_PAYLOAD_LENGTH];
static basicRfCfg_t basicRfConfig;
#ifdef SECURITY_CCM
// Security key
static uint8 key[]= {
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
};
#endif
#ifdef DataRX
uchar UartData[30]="XWWK test Data!";
#endif
#ifdef SensorDataTX
uchar UartData[30]=" sg HUM:sg";
#endif
WORD res;
BYTE Tx_buffer[APP_PAYLOAD_LENGTH]=" sg HUM:sg";
unsigned char ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //x小数处理 0.1
unsigned char display[5]={0x00,0x00,0x00,0x00,0x00};
/***********************************************************************************
* LOCAL FUNCTIONS
*/
static void appDataRx();
static void appSensorTX();
void Wait(unsigned int wait);
void work_temp(WORD tem);
//////////////////////////////魏然2013年2月23日////////////////////////
/*此部分是温湿度传感器公司给的程序段中的延时函数,为了便于理解,没有修改此处*/
void Delay(U16 z)
{
U8 x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
/*****************从DHT11读取一个字节函数******************/
void COM(void)//
{
U8 i;
for(i=0;i<8;i++) //循环8次,读取8bit的数据
{
U8FLAG=2;//读取并等待DHT11发出的12-14us低电平开始信号
//set_DQ_out;//P1DIR=0x00;////
while((!P1_5)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;//跳过门限后判断总线是高还是低,高为1,低为0
//if(DHT11_DATA)
if(P1_5)U8temp=1;
U8FLAG=2;//等待1bit的电平信号结束,不管是0是1在118us后都变为低电平,否则错误超时
while((P1_5)&&U8FLAG++);//当U8FLAG加到255后溢出为0,跳出循环,并后加加为1
if(U8FLAG==1)break; //超时则跳出for循环
U8comdata<<=1;//左移1位,LSB补0
U8comdata|=U8temp; //LSB赋值
}
}
/*****************DHT11读取五个字节函数******************/
void RH(void)
{
//set_DQ_out;//P1DIR=0x01;//
P1_5=0;//主机拉低18ms
Delay(40);
P1_5=1;//总线由上拉电阻拉高 主机延时20us-40us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
P1_5=1;
// P1DIR &= ~0x40//set_DQ_out;//P1DIR=0x00;
if(!P1_5)////判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行//
//【疑问一】这里永远进不来,也就是说,我把if后条件为1,才继续进入函数执行,我觉得是P1_5端口没数据进来
{
U8FLAG=2;//判断DHT11发出的80us的低电平响应信号是否结束
while((!P1_5)&&U8FLAG++);////判断DHT11发出的80us的低电平响应信号是否结束
U8FLAG=2;
while((P1_5)&&U8FLAG++);//判断DHT11是否发出80us的高电平,如发出则进入数据接收状态
COM();//读取湿度值整数部分的高8bit
U8RH_data_H_temp=U8comdata;
COM();
U8RH_data_L_temp=U8comdata;
COM();
U8T_data_H_temp=U8comdata;
COM();
U8T_data_L_temp=U8comdata;
COM();
U8checkdata_temp=U8comdata;////读取校验和的8bit
set_DQ_out;//P1DIR=0x01;//【疑问二】我看许多示例程序都有这个,我在做失败的情况下,添加了此行,但还是不正确,为什么?
P1_5=1;
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);//进行数据校验
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;//温湿度数据传递
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}
shidu_shi=U8T_data_H/10; //把读进来的数据放在shidu_shi中
shidu_ge=U8T_data_H%10;
wendu_shi=U8RH_data_H/10;
wendu_ge=U8RH_data_H%10;
//
Tx_buffer[8]=table1[shidu_shi]; //把对应的数字放置在 字符数组 中准备传送、、问题是,为什么不直接赋值,而是通过另外一个数组转化?
Tx_buffer[9]=table1[shidu_ge];
Tx_buffer[1]=table1[wendu_shi]; //个位因为放大了 10 倍,此位实为小数位
Tx_buffer[2]=table1[wendu_ge];
//
}
}
//以上是我在温度传感上自己从单片机移植过来的,下面是原来的代码
///////////////////////////////////////////////////////////////////////
/***********************************************************************************
* @fn main
*
* @brief 主程序
***********************************************************************************/
void main(void)
{
// 射频配置
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;
#ifdef SECURITY_CCM
basicRfConfig.securityKey = key;
#endif
// IO初始化
halBoardInit();
initUART0();
// RF初始化
if(halRfInit()==FAILED) {
HAL_ASSERT(FALSE);
}
halLedClear(LED_BlUE );//亮蓝灯
halLedClear(LED_RED); //亮红灯
halLedClear(LED_YELLOW); //亮红灯
Wait(8);
halLedSet(LED_BlUE );
halLedSet(LED_RED);
halLedSet(LED_YELLOW);
#ifdef DataRX
UartTX_Send_String(UartData,15);//向串口发送测试数据
Wait(8);
UartData[0]='T';
UartData[1]='e';
UartData[2]='m';
UartData[3]='p';
UartData[4]=':';
#endif
while(1)
{
#ifdef SensorDataTX
RH();
// res=read_temp();//获取温度
// work_temp(res); //格式转换
/*
Tx_buffer[1]=display[2]+48;
Tx_buffer[2]=display[1]+48;
Tx_buffer[3]=46;
Tx_buffer[4]=display[0]+48;
Tx_buffer[1]='c';
Tx_buffer[2]='e';
Tx_buffer[3]=' ';
Tx_buffer[4]='s';
Tx_buffer[5]='h';
Tx_buffer[6]='i';
Tx_buffer[7]='7';
Tx_buffer[8]='8';
Tx_buffer[9]='9';
*/
//UartTX_Send_String(Tx_buffer,4); //此处设置断点,查看温度,并可将温度上传至PC机
appSensorTX();
Wait(40);
#endif
#ifdef DataRX
appDataRx();
#endif
}
}
/***********************************************************************************
* @fn appDataRx
*
* @brief 实时接收数据,成功接收后改变红灯的状态
************************************************************************************/
static void appDataRx()
{
BYTE i;
//初始化射频配置
basicRfConfig.myAddr = LIGHT_ADDR;//设置地址
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}
basicRfReceiveOn();//打开接收
//主循环
while (1)
{
while(!basicRfPacketIsReady());
if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0)
{
if(pRxData[0] == WENDU_CMD )
{
for(i=0;i!=10;i++){
Tx_buffer[i]=pRxData[i+1];
}
UartTX_Send_String(UartData,5);//向串口发送字头
UartTX_Send_String(Tx_buffer,APP_PAYLOAD_LENGTH-1);//温度上传至PC机
halLedToggle(LED_BlUE);
Wait(1);
halLedToggle(LED_BlUE);
}
}
}
//串口中断程序在 Uart.c
}
/***********************************************************************************
* @fn appSensorTX
*
* @brief 每隔2S发送一次数据,发送成功,红灯闪烁一次
*
************************************************************************************/
static void appSensorTX()
{
Tx_buffer[0] =WENDU_CMD ; //温度命令
// Initialize BasicRF
basicRfConfig.myAddr = SWITCH_ADDR; //设置地址
if(basicRfInit(&basicRfConfig)==FAILED)
{
HAL_ASSERT(FALSE);
}
// Keep Receiver off when not needed to save power
basicRfReceiveOff();
basicRfSendPacket(LIGHT_ADDR, Tx_buffer, APP_PAYLOAD_LENGTH);
halLedToggle(LED_RED);
Wait(1);
halLedToggle(LED_RED);
}
/***********************************************************************************
* @fn Wait
*
* @brief 延时程序
*
************************************************************************************/
void Wait(unsigned int wait)
{
unsigned int largeWait;
largeWait = 6000;
unsigned int i;
for(i=0;i!=wait;i++)
{
while(largeWait--);
}
return;
}
void work_temp(WORD tem)
{
display[4]=tem&0x0f; // 取小数部分的值
display[0]=ditab[display[4]]; // 存入小数部分显示值
display[4]=tem>>4; // 取中间八位,即整数部分的值
display[3]=display[4]/100; // 取百位数据暂存
display[1]=display[4]%100; // 取后两位数据暂存
display[2]=display[1]/10; // 取十位数据暂存
display[1]=display[1]%10;
}