本帖最后由 gaoyang9992006 于 2020-9-16 10:18 编辑
am2301.rar
(13.37 MB)
说明,使用的是NUCLEO-STM32F072RB开发板,板载一个LED,利用这个LED做一个线程,用于指示工作中。
通过PA10驱动AM2301单线协议的温湿度传感器。通过板载虚拟串口进行消息打印UART2,PA2,PA3
为了方便将所有用到的am2301相关函数都放到了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()
unsigned char Sensor_AnswerFlag; //收到起始标志位
unsigned char Sensor_ErrorFlag; //读取传感器错误标志
unsigned int Sys_CNT;
unsigned char AM2301_Data[5]={0x00,0x00,0x00,0x00,0x00};
void Read_AM2301_PIN_Init(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);
}
void Write_AM2301_PIN_Init(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);
}
unsigned char Read_AM2301_PIN(void)
{
return HAL_GPIO_ReadPin(AM2301_PORT, AM2301_PIN);
}
void SET_AM2301_PIN(void)
{
HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_SET);
}
void RESET_AM2301_PIN(void)
{
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;
Write_AM2301_PIN_Init();
RESET_AM2301_PIN();
// rt_thread_mdelay(2);
HAL_Delay(2);
SET_AM2301_PIN();
rt_hw_us_delay(30);
SET_AM2301_PIN();
Read_AM2301_PIN_Init();
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;
}
创建2个线程,一个用于LED闪烁,一个用于AM2301读取与显示。
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-08-29 RT-Thread first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <am2301.h>
//配置优先级,栈大小,时间片,设置不对没法运行的。
#define THREAD_PRIORITY 5
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
//LED配置
#define LED_PIN GPIO_PIN_5
#define LED_PORT GPIOA
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define LED_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
#define LED_ON() HAL_GPIO_WritePin(LED_PORT, LED_PIN,GPIO_PIN_SET);
#define LED_OFF() HAL_GPIO_WritePin(LED_PORT, LED_PIN,GPIO_PIN_RESET);
void led(void *parameter)
{
LED_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 = LED_PIN;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
while(1)
{
rt_kprintf("LED=============================================\n");
LED_ON();
rt_kprintf("LED is ON\n");
rt_thread_mdelay(2500);
LED_OFF();
rt_kprintf("LED is OFF\n");
rt_thread_mdelay(2500);
}
}
MSH_CMD_EXPORT(led, RT-led sample);
void am2301(void *parameter)
{
unsigned char i=0;
int wendu,shidu;
rt_kprintf("\n");
while(1)
{
rt_kprintf("AM2301=============================================\n");
rt_thread_mdelay(10000);
Read_Sensor();
for(i=0;i<5;i++)
rt_kprintf("AM2301_Data[%d]=%d\n",i,AM2301_Data[i]);
if(AM2301_Data[4]==(AM2301_Data[0]+AM2301_Data[1]+AM2301_Data[2]+AM2301_Data[3])) rt_kprintf("Check is OK\n");
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.%d\%\n",shidu/10,shidu%10);
rt_kprintf("wendu=%d.%dC\n",wendu/10,wendu%10);
for(i=0;i<5;i++)
AM2301_Data[i]=0;
}
}
MSH_CMD_EXPORT(am2301, RT-am2301 sample);
int myapp(void)
{
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 创建线程1 */
tid1 = rt_thread_create("thread1",
am2301, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
tid2 = rt_thread_create("thread2",
led, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY-1, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
return 0;
}
MSH_CMD_EXPORT(myapp, RT-Thread sample);
int main(void)
{
rt_kprintf("Hello\n");
rt_thread_mdelay(1000);
myapp();
return RT_EOK;
}
|