【精品博文】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;

如果,采用博主的

结果如下:

(0)

相关推荐

  • NRF24L01双向传输(一对一)

    NRF24L01双向传输(一对一) 简介 本文章记录两个NRF24L01无线模块实现双向传输的软件设计~ 为什么可以双向传输呢?这要归功于它具有Enhanced ShockBurst,可以工作在主接收 ...

  • STM32驱动NRF24L01

    前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长. 1. 简介 NRF24L01是 nordic 的无线通信芯片,它具有以下特 ...

  • 【精品博文】老莫填坑:数字集成电路与系统中的状态机的使用

    今天简单务虚的谈一谈数字集成电路与系统中状态机的使用. 状态机是用来干嘛的?如果你只是学了现在本科教学大纲里的那点内容,大概以为状态机就是做做什么序列检测器,检测一下一串序列里面有没有"11 ...

  • 【精品博文】老莫出题:数字集成电路与系统设计的寒假作业

    现在已经进入寒假阶段了,各位学生朋友们应该都已经回家或者在回家的路上了.也有少量的同学们还可能留在学校准备一些类似于"美国数学建模大赛"之类的竞赛事宜.总的来说放假是好事,辛苦了一 ...

  • 【精品博文】数字音频I2S总线

    赢一个双肩背包 有多难? 戳一下试试看! →_→ 长摁识别 一.I2S总线概述 音响数据的采集.处理和传输是多媒体技术的重要组成部分.众多的数字音频系统已经进入消费市场,例如数字音频录音带.数字声音处 ...

  • 【精品博文】SHT11温湿度测量值错误小结

    [求助]SHT11湿度测量值错误 情况一:公司器件库里刚领出来的10个SHT11,焊接后,直接测试,发现测量值有问题. 查了一下Datasheet,感觉有可能是因为SHT11没有经过充分水合.于是按照 ...

  • 【精品博文】数字集成电路与系统设计MooC规划

    最近老发一些吐槽文,有点荒废业务,还是不太好.毕竟还是需要传道授业解惑,尽教师应尽的职责的.所以今天写一篇别的. 最近啊,这个MooC,也就是中文讲的"慕课"在全国范围内都很火,各 ...

  • 【精品博文】书架应该有这样一本书-----《数字图像处理》

    炎炎夏日,AET又有新活动,在6月1日,按照惯例,学校会发个小红包给有孩子的家长,今年的礼物很特别,一张购书卡,我觉得特别有意义,想起了我的童年,想起了我珍藏的小人书,今天就给大家推荐这本计算机专业学 ...

  • 土壤温湿度传感器如何帮助作物度过寒潮

    根据中国气象局报告,未来10天,冷空气活动频繁,全国大部分地区气温偏低1~2℃,部分地区有6~8℃降温,各地需警惕大风降温对设施农业的影响,提前做好棚舍加固和防寒保暖工作. 近期寒潮一波未平一波又起, ...

  • 智能温湿度传感器与普通温湿度传感器相比有哪些优势

    传感器与通信.计算机被称为现代信息系统的三大支柱,是当前各发达国家竞相发展的高新技术,传感器技术所涉及的知识领域非常广泛,其研究和发展也越来越多地和其他学科技术的发展紧密联系.从上个世纪开始算起,传感 ...

  • 392 温湿度传感器-数显器-控制器

    392 温湿度传感器-数显器-控制器 背景 在空调.冷库.温室.气扫式膜蒸馏等领域都需要测量和控制空气湿度:空气湿度通常用相对湿度表示,因相对湿度与空气温度密切相关,所以通常需要温湿度同时测量. 性能 ...