打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【精品博文】stm32F4----DHT22(AM2302)数字温湿度传感器读取(六)

经过了自己用FPGA来驱动DHT22,http://blog.chinaaet.com/xzy610030/p/5100051014

下面开始用STM32F4来读取温湿度了。

首先非常感谢他人的原创,受益匪浅:http://blog.csdn.net/xiayufeng520/article/details/46292899

最后实现如下:

am2302.h

#ifndef   _AM2302_H#define   _AM2302_H#ifdef  _cplusplus   extern "C" {#endif#include "stm32f4xx.h"//AM2302  IO  define#define  AM2302_GPIO_PORT  GPIOG#define  AM2302_PIN        GPIO_Pin_0  #define  AM2302_GPIO_CLK   RCC_AHB1Periph_GPIOG  //#define  HIGH    1#define  LOW     0typedef  struct{  uint8_t   humiHighByte; uint8_t   humiLowByte; uint8_t   temmHighByte; uint8_t   temmLowByte; uint8_t   check_num;}AM2302_Data_TypeDef;  //带参宏,可以像内联函数一样使用,输出高电平或低电平  #define  AM2302_DATA_OUT(a) if (a)                      GPIO_SetBits(AM2302_GPIO_PORT,AM2302_PIN);                    else                            GPIO_ResetBits(AM2302_GPIO_PORT,AM2302_PIN)   //读取引脚的电平  #define  AM2302_DATA_IN()      GPIO_ReadInputDataBit(AM2302_GPIO_PORT,AM2302_PIN)      void AM2302_GPIO_Config(void);  static void AM2302_Mode_IPU(void);  static void AM2302_Mode_Out_PP(void);  uint8_t Read_AM2302(AM2302_Data_TypeDef *AM2302_Data);  static uint8_t Read_Byte(void);   #ifdef  _cplusplus   }#endif   #endif

am2302.c如下:

#include "am2302.h"#include "delay.h"/* *函数名: *描述  : *输入  : *输出  :*/void AM2302_GPIO_Config(void){  //定义一个GPIO_InitTypeDef类型结构体 GPIO_InitTypeDef   GPIO_InitStructure; //开启GPIO 外设时钟  RCC_AHB1PeriphClockCmd(AM2302_GPIO_CLK, ENABLE); //选择要控制的GPIO 引脚 GPIO_InitStructure.GPIO_Pin  =  AM2302_PIN; //设置引脚模式为通用推挽输出 GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_OUT; //设置引脚速率为50MHz   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;            //调用库函数,初始化GPIO_AM2302    GPIO_Init(AM2302_GPIO_PORT, &GPIO_InitStructure);                    //拉高PIN_AM2302   GPIO_SetBits(AM2302_GPIO_PORT, AM2302_PIN);     }/*  * 函数名:AM2302_Mode_IPU  * 描述  :使AM2302-DATA引脚变为输入模式  * 输入  :无  * 输出  :无  */  static void AM2302_Mode_IPU(void)  {        GPIO_InitTypeDef GPIO_InitStructure;                 /*选择要控制的GPIOD引脚*/          GPIO_InitStructure.GPIO_Pin = AM2302_PIN;                /*设置引脚模式为浮空输入模式*/        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ;                /*调用库函数,初始化GPIOD*/        GPIO_Init(AM2302_GPIO_PORT, &GPIO_InitStructure);     }  /*  * 函数名:AM2302_Mode_Out_PP  * 描述  :使AM2302-DATA引脚变为输出模式  * 输入  :无  * 输出  :无  */  static void AM2302_Mode_Out_PP(void)  {      GPIO_InitTypeDef GPIO_InitStructure;                 /*选择要控制的GPIOD引脚*/                                                                   GPIO_InitStructure.GPIO_Pin = AM2302_PIN;                /*设置引脚模式为通用推挽输出*/      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                /*设置引脚速率为50MHz */        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;             /*调用库函数,初始化GPIOD*/      GPIO_Init(AM2302_GPIO_PORT, &GPIO_InitStructure);           } static uint8_t Read_Byte(void)  {                 uint8_t i, temp=0;              for(i=0;i<8;i++)           {                     /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/           while(AM2302_DATA_IN()  ==  Bit_RESET) {}                          /*AM2302 以22~30us的高电平表示“0”,以68~75us高电平表示“1”,              通过检测60us后的电平即可区别这两个状态*/                  Delay_us(30); //延时50us                                   if(AM2302_DATA_IN() == Bit_SET)//60us后仍为高电平表示数据“1”             {                /*轮询直到从机发出的剩余的 30us 高电平结束*/                   while(AM2302_DATA_IN()==Bit_SET);                          temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1                                 }             else  //60us后为低电平表示数据“0”             {                               temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0             }       }       return temp;  }  uint8_t Read_AM2302(AM2302_Data_TypeDef *AM2302_Data)  {        /*输出模式*/      unsigned char tmp;   AM2302_Mode_Out_PP();     AM2302_DATA_OUT(HIGH);    Delay_ms(2);    /*主机拉低*/     AM2302_DATA_OUT(LOW);     /*延时2ms*/     Delay_ms(2);            /*总线拉高 主机延时30us*/     AM2302_DATA_OUT(HIGH);             Delay_us(30);   //延时30us                /*主机设为输入 判断从机响应信号*/     AM2302_Mode_IPU();          /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/       if(AM2302_DATA_IN()==Bit_RESET)   //T !         {                        /*轮询直到从机发出 的80us 低电平 响应信号结束*/           while(AM2302_DATA_IN()==Bit_RESET){}                        /*轮询直到从机发出的 80us 高电平 标置信号结束*/          while(AM2302_DATA_IN()==Bit_SET){}               /*开始接收数据*/             AM2302_Data->humiHighByte= Read_Byte();                                                  AM2302_Data->humiLowByte= Read_Byte();                                  AM2302_Data->temmHighByte= Read_Byte();                  AM2302_Data->temmLowByte= Read_Byte();                                          AM2302_Data->check_num= Read_Byte();                                                                   /*读取结束,引脚改为输出模式*/      AM2302_Mode_Out_PP();          /*主机拉高*/          AM2302_DATA_OUT(HIGH);                 /*检查读取的数据是否正确*/          tmp = AM2302_Data->humiHighByte + AM2302_Data->humiLowByte + AM2302_Data->temmHighByte+ AM2302_Data->temmLowByte;        if(AM2302_Data->check_num == tmp )            return SUCCESS;          else            return ERROR;     }     else     {                    return ERROR;     }            }

delay.c这里定义了两个delay函数,如下;

void Delay_us(__IO u32 us){  u32 temp;   SysTick->LOAD =  180 * us;   SysTick->VAL  =  0x00;  SysTick->CTRL =  0x0005;   temp  = SysTick->CTRL;  while((temp & 0x01) && (!(temp & (1 << 16))))  {    temp = SysTick->CTRL;  }  SysTick->VAL  =  0x00;  SysTick->CTRL =  0x00;} void Delay_ms(__IO u32 ms){  u32 temp;   SysTick->LOAD =  180000 * ms;   SysTick->VAL  =  0x00;  SysTick->CTRL =  0x0005;   temp  = SysTick->CTRL;  while((temp & 0x01) && (!(temp & (1 << 16))))  {    temp = SysTick->CTRL;  }  SysTick->VAL  =  0x00;  SysTick->CTRL =  0x00;}

main.c

  while(1) { /*调用Read_AM2302读取温湿度,若成功则输出该信息*/      if( Read_AM2302(&AM2302_Data)==SUCCESS)      {                   //计算出实际湿度值的10倍        RH_Value= AM2302_Data.humiHighByte*256 + AM2302_Data.humiLowByte;        RH_H = RH_Value/10;        RH_L = RH_Value%10;        //计算出时间温度值的10倍        TEMP_Value = AM2302_Data.temmHighByte*256 + AM2302_Data.temmLowByte;        TP_H = TEMP_Value/10;        TP_L = TEMP_Value%10;        printf("\r\n读取AM2302成功!\r\n\r\n湿度为%d.%d %RH,温度为 %d.%d℃ \r\n",RH_H,RH_L,TP_H,TP_L);//“\”表示转向一下行       }          else              printf("Read AM2302 ERROR!\r\n");

原博主的代码是没法直接通过的,和博主不一样的地方有下:

(1)GPIO那里,F1和F4是不一样的,  

GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_OUT;

 (2)用系统定时器编写了两个定时函数

void Delay_ms(__IO u32 ms)void Delay_us(__IO u32 us)

(3)最要的是这里:

AM2302_DATA_OUT(HIGH);

先拉高,在开始通信,这部分在FPGA也是这样处理的,这里又调试了好久。-------千万注意

(4)这里是一定要这样:

        tmp = AM2302_Data->humiHighByte + AM2302_Data->humiLowByte + AM2302_Data->temmHighByte+ AM2302_Data->temmLowByte;

如果,采用博主的

结果如下:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
STM32F1驱动AM2302温湿度传感器
stm32L152工程模板及操作内部自带的EEPROM示例(测试开发板为stm32L discovry)
STM32 SysTick基于3.5库函数
STM32 (Cortex-M3) 中NVIC(嵌套向量中断控制)的理解
stm32的按键扫描[操作寄存器+库函数]-Changing's Blog
contiki STM32移植
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服