WSN之DHT11溫溼度傳感器

/**
 描述:DHT11 測試
*/
#include "ioCC2530.h"
#include <stdio.h>

#define uchar unsigned char 
#define uint unsigned int

#define  DHT11_DATA  P0_4

/*****************全局變量的定義******************/
uchar  Overtime_counter;  //判斷等待是否超時的計數器。利用uchar型的數值範圍進行自動延時控制(時長由初值決定),並判斷是否超時
uchar  bit_value;          //從DATA總線上讀到的位值
uchar  T_data_H, T_data_L, RH_data_H, RH_data_L, checkdata;//校驗過的溫度高8位,溫度低8位,溼度高8位,溼度低8位,校驗和8位
uchar  T_data_H_temp, T_data_L_temp, RH_data_H_temp, RH_data_L_temp, checkdata_temp;//未經校驗的數據
uchar  comdata;            //從DHT11讀取的一個字節的數據

void Delay(uint);
void InitialAD(void);
char  str[16];


/*****************************************************
 * @brief   初始化串口
*****************************************************/
void initUARTSEND(void)
{
    PERCFG = 0x00;       // 設置外設控制爲P0
    P0SEL = 0x2c;            // 選擇P0_2,P0_3,P0_4,P0_5作爲串口
    P2DIR &= ~0XC0;              //P0優先作爲UART0

    U0CSR |= 0x80;          //UART方式
    U0GCR |= 9;                    
    U0BAUD |= 59;           //波特率設爲19200
    UTX0IF = 0;                 //UART0 TX中斷標誌初始置位0
}

/********************************************
 * @brief   串口發送數據
 *
 * @param   Data - 數據
 *          len - 數據長度
********************************************/
void UartTX_Send_String(char Data[], int len)
{
  int j;
  for (j = 0; j < len; j++)
  {
    U0DBUF = Data[j];   // 填充數據到串口數據寄存器
    while (UTX0IF == 0); // 等待串口發送完畢
    UTX0IF = 0;         // 將串口中斷標誌置0,準備下一次的發送
  }
}

/*****************延時函數******************/
void Delay(unsigned int n)
{
    unsigned int i;
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
    for(i = 0; i < n; i++);
}

void Delay_10us(unsigned char n)
{
    for( ; n > 0; n--);
}

/*****************從DHT11讀取一個字節函數******************/        
void  Read_Byte(void)
{
        uchar i;
        for (i = 0; i < 8; i++)                     //循環8次,讀取8bit的數據
        {
          Overtime_counter = 2;                          //讀取並等待DHT11發出的12-14us低電平開始信號
          //P0DIR &= ~0x10;
          while ((!DHT11_DATA) && Overtime_counter++);
          Delay_10us(80);                   //26-28us的低電平判斷門限
          bit_value = 0;                          //跳過門限後判斷總線是高還是低,高爲1,低爲0
          if(DHT11_DATA)
            bit_value = 1;
          Overtime_counter=2;                          //等待1bit的電平信號結束,不管是0是1在118us後都變爲低電平,否則錯誤超時
          while (DHT11_DATA && Overtime_counter++);  //當U8FLAG加到255後溢出爲0,跳出循環,並後加加爲1
          if (Overtime_counter == 1)
            break;                           //超時則跳出for循環        
          comdata <<= 1;                      //左移1位,LSB補0
          comdata |= bit_value;                  //LSB賦值
        }
}

/*****************DHT11讀取五個字節函數******************/
void Read_DHT11(void)
{
        uchar checksum;
        P0DIR |= 0x10;
        DHT11_DATA = 0;//主機拉低18ms
        Delay(8900);
        DHT11_DATA = 1;//總線由上拉電阻拉高 主機延時20us-40us
        Delay_10us(150);
        DHT11_DATA = 1;//主機轉爲輸入或者輸出高電平,DATA線由上拉電阻拉高,準備判斷DHT11的響應信號
        //P0DIR &= ~0x10;
        if (!DHT11_DATA)//判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行        
        {
          Overtime_counter = 2; //判斷DHT11發出的80us的低電平響應信號是否結束
          while ((!DHT11_DATA)&&Overtime_counter++);
          Overtime_counter=2;   //判斷DHT11是否發出80us的高電平,如發出則進入數據接收狀態
          while ((DHT11_DATA)&&Overtime_counter++);
          Read_Byte();                //讀取溼度值整數部分的高8bit
          RH_data_H_temp = comdata;
          Read_Byte();                //讀取溼度值小數部分的低8bit
          RH_data_L_temp = comdata;
          Read_Byte();                //讀取溫度值整數部分的高8bit
          T_data_H_temp = comdata;
          Read_Byte();                //讀取溫度值小數部分的低8bit
          T_data_L_temp = comdata;
          Read_Byte();                //讀取校驗和的8bit
          checkdata_temp = comdata;
          //P0DIR |= 0x10;
          DHT11_DATA = 1;                //讀完數據將總線拉高
          checksum = (T_data_H_temp + T_data_L_temp + RH_data_H_temp + RH_data_L_temp);//進行數據校驗
          if (checksum == checkdata_temp)
            {
              RH_data_H = RH_data_H_temp;
              RH_data_L = RH_data_L_temp;
              T_data_H  = T_data_H_temp;
              T_data_L  = T_data_L_temp;
              checkdata = checkdata_temp;
            }
        }
}


/****************************************************************
*函數功能 :主函數                                                *
*入口參數 :無                                                        *
*返 回 值 :無                                                        *
*說    明 :無                                                        *
****************************************************************/
void main(void)
{      
    CLKCONCMD &= ~0x40;              //晶振
    while (CLKCONSTA & 0x40);     //等待晶振穩定
    CLKCONCMD &= ~0x47;             //CLKSPD128分頻
    SLEEPCMD |= 0x04;        
    P1DIR |= 0x01;

    initUARTSEND();

   Delay(50000);
   while (1)
   {
     Read_DHT11();//調用溫溼度讀取子程序
     Delay(60000);//循環採樣的延時,讀取模塊數據週期不易小於2S
     sprintf(str, "%dC, %dH\n", T_data_H, RH_data_H);
     UartTX_Send_String(str, 16);
     P1_0 ^= 1;
   }
}

DHT11溫溼度傳感器 下載地址
具體知識點,可在下載文檔研讀,個人今天學習了,還是不太懂,所以,望賜教~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章