打印
[STM32F0]

STM32F072开发板驱动AM2301

[复制链接]
450|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 jiekou001 于 2020-8-27 23:50 编辑

补充上手册
AM2301A规格书.pdf (1.28 MB)

am2301.h
#include "stm32f0xx_hal.h"


//读传感器 端口位定义,可修改
//*
#define AM2301_PIN  GPIO_PIN_10
#define AM2301_PORT GPIOA
#define AM2301_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
#define AM2301_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()
//*/
/*通过LED测试输出用
#define AM2301_PIN  GPIO_PIN_5
#define AM2301_PORT GPIOA
#define AM2301_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
#define AM2301_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()
*/

unsigned char Sensor_AnswerFlag;  //收到起始标志位
unsigned char Sensor_ErrorFlag;   //读取传感器错误标志
unsigned int  Sys_CNT;
unsigned char AM2301_Data[5]={0x00,0x00,0x00,0x00,0x00};

unsigned char Read_AM2301_PIN(void)
{
    AM2301_GPIO_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Mode    = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull    = GPIO_PULLUP;
    GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pin     = AM2301_PIN;
    HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);
    return HAL_GPIO_ReadPin(AM2301_PORT, AM2301_PIN);
}

void SET_AM2301_PIN(void)
{
    AM2301_GPIO_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Mode    = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull    = GPIO_PULLUP;
    GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pin     = AM2301_PIN;
    HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_SET);
}

void RESET_AM2301_PIN(void)
{
    AM2301_GPIO_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.Mode    = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull    = GPIO_PULLUP;
    GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pin     = AM2301_PIN;
    HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);
    HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_RESET);
}

unsigned char Read_AM2301_Data(void)
{
    unsigned char i,cnt,buffer,tmp;
    for (i = 0; i < 8; i++)
    {
        cnt=0;
        while(!Read_AM2301_PIN())
        {
           if(++cnt>=3000)
               break;
        }
        rt_hw_us_delay(30);
        tmp=0;
        if(Read_AM2301_PIN())
            tmp=1;
        cnt=0;
        while(Read_AM2301_PIN())
        {
            if(++cnt>=2000)
                break;
        }
        buffer<<=1;
        buffer|=tmp;
    }
    return buffer;
}

unsigned char Read_Sensor(void)
{
    unsigned char i;
    RESET_AM2301_PIN();
    rt_thread_mdelay(2);
    SET_AM2301_PIN();
    rt_hw_us_delay(30);
    SET_AM2301_PIN();
    Read_AM2301_PIN();
    Sensor_AnswerFlag=0;
    if(Read_AM2301_PIN()==GPIO_PIN_RESET)
    {
        Sensor_AnswerFlag=1;
        Sys_CNT=0;
        while(Read_AM2301_PIN()==GPIO_PIN_RESET)
        {
            if(++Sys_CNT>3000)
            {
                Sensor_ErrorFlag=1;
                return 0;
            }
        }
        Sys_CNT=0;
        while(Read_AM2301_PIN()==GPIO_PIN_SET)
        {
            if(++Sys_CNT>3000)
            {
                Sensor_ErrorFlag=1;
                return 0;
            }
        }
        for(i=0;i<5;i++)
        {
            AM2301_Data[i] = Read_AM2301_Data();
        }
    }
    else
    {
        Sensor_AnswerFlag=0;
    }
    return 1;
}
main.c
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2020-08-27     RT-Thread    first version
*/

#include <rtthread.h>
#include <board.h>
#include <am2301.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

int main(void)
{
    int count = 1,i=0;
    unsigned int shidu,wendu;

    while (count++)
    {
//       LOG_D("Hello RT-Thread!");
        rt_kprintf("Hello RT-Thread!\n");
        rt_thread_mdelay(1000);
        SET_AM2301_PIN();
        rt_thread_mdelay(1000);
        RESET_AM2301_PIN();

  //      if(Read_AM2301_PIN())
        Read_Sensor();
        for(i=0;i<5;i++)
        rt_kprintf("AM2301_Data[%d]=%d\n",i,AM2301_Data[i]);

        shidu=AM2301_Data[0];
        shidu<<=8;
        shidu=shidu|AM2301_Data[1];
        wendu=AM2301_Data[2];
        wendu<<=8;
        wendu=wendu|AM2301_Data[3];
        rt_kprintf("shidu=%d\n",shidu);
        rt_kprintf("wendu=%d\n",wendu);
        for(i=0;i<5;i++)
        {
            AM2301_Data[i] = 0;
        }
        shidu=0;
        wendu=0;
    }

    return RT_EOK;
}

使用特权

评论回复
评论
jiekou001 2020-8-27 23:08 回复TA
这个结果是包含一个小数的,实际数值需要除以10。 这里没有处理这个。 
沙发
jiekou001|  楼主 | 2020-8-27 22:44 | 只看该作者
am2301.rar (3.23 MB)
这是基于RT-Thread RTOS的
利用PA10端口读取AM2301,先建立读取高低电平的函数,然后再搞定拉高拉低的,然后按照时序搞定

使用特权

评论回复
板凳
jiekou001|  楼主 | 2020-8-27 23:06 | 只看该作者
对读取结果进行校验,发现非常正确。

使用特权

评论回复
地板
wahahaheihei| | 2020-8-27 23:49 | 只看该作者
给楼主点赞。

使用特权

评论回复
5
wahahaheihei| | 2020-8-27 23:49 | 只看该作者
楼主这个芯片的读取时序手册有吗?

使用特权

评论回复
6
jiekou001|  楼主 | 2020-8-27 23:50 | 只看该作者
wahahaheihei 发表于 2020-8-27 23:49
楼主这个芯片的读取时序手册有吗?

已补充。马上休息。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

134

主题

1347

帖子

2

粉丝