[STM32F0] STM32 NUCLEO 驱动AM2301

[复制链接]
879|1
 楼主| gaoyang9992006 发表于 2020-8-29 22:50 | 显示全部楼层 |阅读模式
本帖最后由 gaoyang9992006 于 2020-9-16 10:18 编辑

am2301.rar (13.37 MB, 下载次数: 2)
说明,使用的是NUCLEO-STM32F072RB开发板,板载一个LED,利用这个LED做一个线程,用于指示工作中。
通过PA10驱动AM2301单线协议的温湿度传感器。通过板载虚拟串口进行消息打印UART2,PA2,PA3
为了方便将所有用到的am2301相关函数都放到了am2301.h头文件里
  1. #include "stm32f0xx_hal.h"

  2. //读传感器 端口位定义,可修改
  3. //*
  4. #define AM2301_PIN  GPIO_PIN_10
  5. #define AM2301_PORT GPIOA
  6. #define AM2301_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
  7. #define AM2301_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()


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

  12. void Read_AM2301_PIN_Init(void)
  13. {
  14.     AM2301_GPIO_CLK_ENABLE();
  15.     GPIO_InitTypeDef GPIO_InitStruct;
  16.     GPIO_InitStruct.Mode    = GPIO_MODE_INPUT;
  17.     GPIO_InitStruct.Pull    = GPIO_PULLUP;
  18.     GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
  19.     GPIO_InitStruct.Pin     = AM2301_PIN;
  20.     HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);
  21. }

  22. void Write_AM2301_PIN_Init(void)
  23. {
  24.     AM2301_GPIO_CLK_ENABLE();
  25.     GPIO_InitTypeDef GPIO_InitStruct;
  26.     GPIO_InitStruct.Mode    = GPIO_MODE_OUTPUT_PP;
  27.     GPIO_InitStruct.Pull    = GPIO_PULLUP;
  28.     GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
  29.     GPIO_InitStruct.Pin     = AM2301_PIN;
  30.     HAL_GPIO_Init(AM2301_PORT, &GPIO_InitStruct);
  31. }

  32. unsigned char Read_AM2301_PIN(void)
  33. {
  34.     return HAL_GPIO_ReadPin(AM2301_PORT, AM2301_PIN);
  35. }

  36. void SET_AM2301_PIN(void)
  37. {
  38.     HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_SET);
  39. }

  40. void RESET_AM2301_PIN(void)
  41. {
  42.     HAL_GPIO_WritePin(AM2301_PORT, AM2301_PIN,GPIO_PIN_RESET);
  43. }

  44. unsigned char Read_AM2301_Data(void)
  45. {
  46.     unsigned char i,cnt,buffer,tmp;
  47.     for (i = 0; i < 8; i++)
  48.     {
  49.         cnt=0;
  50.         while(!Read_AM2301_PIN())
  51.         {
  52.            if(++cnt>=3000)
  53.                break;
  54.         }
  55.         rt_hw_us_delay(30);
  56.         tmp=0;
  57.         if(Read_AM2301_PIN())
  58.             tmp=1;
  59.         cnt=0;
  60.         while(Read_AM2301_PIN())
  61.         {
  62.             if(++cnt>=2000)
  63.                 break;
  64.         }
  65.         buffer<<=1;
  66.         buffer|=tmp;
  67.     }
  68.     return buffer;
  69. }

  70. unsigned char Read_Sensor(void)
  71. {
  72.     unsigned char i;
  73.     Write_AM2301_PIN_Init();
  74.     RESET_AM2301_PIN();
  75. //    rt_thread_mdelay(2);
  76.     HAL_Delay(2);
  77.     SET_AM2301_PIN();
  78.     rt_hw_us_delay(30);
  79.     SET_AM2301_PIN();

  80.     Read_AM2301_PIN_Init();
  81.     Sensor_AnswerFlag=0;
  82.     if(Read_AM2301_PIN()==GPIO_PIN_RESET)
  83.     {
  84.         Sensor_AnswerFlag=1;
  85.         Sys_CNT=0;
  86.         while(Read_AM2301_PIN()==GPIO_PIN_RESET)
  87.         {
  88.             if(++Sys_CNT>3000)
  89.             {
  90.                 Sensor_ErrorFlag=1;
  91.                 return 0;
  92.             }
  93.         }
  94.         Sys_CNT=0;
  95.         while(Read_AM2301_PIN()==GPIO_PIN_SET)
  96.         {
  97.             if(++Sys_CNT>3000)
  98.             {
  99.                 Sensor_ErrorFlag=1;
  100.                 return 0;
  101.             }
  102.         }
  103.         for(i=0;i<5;i++)
  104.         {
  105.             AM2301_Data[i] = Read_AM2301_Data();
  106.         }
  107.     }
  108.     else
  109.     {
  110.         Sensor_AnswerFlag=0;
  111.     }
  112.     return 1;
  113. }


创建2个线程,一个用于LED闪烁,一个用于AM2301读取与显示。
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date           Author       Notes
  8. * 2020-08-29     RT-Thread    first version
  9. */

  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include <am2301.h>

  13. //配置优先级,栈大小,时间片,设置不对没法运行的。
  14. #define THREAD_PRIORITY         5
  15. #define THREAD_STACK_SIZE       512
  16. #define THREAD_TIMESLICE        5

  17. //LED配置
  18. #define LED_PIN  GPIO_PIN_5
  19. #define LED_PORT GPIOA
  20. #define LED_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
  21. #define LED_GPIO_CLK_DISABLE()    __HAL_RCC_GPIOA_CLK_DISABLE()
  22. #define LED_ON()        HAL_GPIO_WritePin(LED_PORT, LED_PIN,GPIO_PIN_SET);
  23. #define LED_OFF()        HAL_GPIO_WritePin(LED_PORT, LED_PIN,GPIO_PIN_RESET);
  24. void led(void *parameter)
  25. {
  26.     LED_GPIO_CLK_ENABLE();
  27.     GPIO_InitTypeDef GPIO_InitStruct;
  28.     GPIO_InitStruct.Mode    = GPIO_MODE_OUTPUT_PP;
  29.     GPIO_InitStruct.Pull    = GPIO_PULLUP;
  30.     GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;
  31.     GPIO_InitStruct.Pin     = LED_PIN;
  32.     HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);

  33.     while(1)
  34.     {
  35.         rt_kprintf("LED=============================================\n");
  36.         LED_ON();
  37.         rt_kprintf("LED is ON\n");
  38.         rt_thread_mdelay(2500);
  39.         LED_OFF();
  40.         rt_kprintf("LED is OFF\n");
  41.         rt_thread_mdelay(2500);
  42.     }
  43. }

  44. MSH_CMD_EXPORT(led, RT-led sample);


  45. void am2301(void *parameter)
  46. {
  47.     unsigned char i=0;
  48.     int wendu,shidu;
  49.     rt_kprintf("\n");
  50.     while(1)
  51.     {
  52.         rt_kprintf("AM2301=============================================\n");
  53.         rt_thread_mdelay(10000);
  54.         Read_Sensor();
  55.         for(i=0;i<5;i++)
  56.             rt_kprintf("AM2301_Data[%d]=%d\n",i,AM2301_Data[i]);

  57.         if(AM2301_Data[4]==(AM2301_Data[0]+AM2301_Data[1]+AM2301_Data[2]+AM2301_Data[3])) rt_kprintf("Check is OK\n");
  58.         shidu=AM2301_Data[0];
  59.         shidu<<=8;
  60.         shidu=shidu|AM2301_Data[1];
  61.         wendu=AM2301_Data[2];
  62.         wendu<<=8;
  63.         wendu=wendu|AM2301_Data[3];
  64.         rt_kprintf("shidu=%d.%d\%\n",shidu/10,shidu%10);
  65.         rt_kprintf("wendu=%d.%dC\n",wendu/10,wendu%10);
  66.         for(i=0;i<5;i++)
  67.             AM2301_Data[i]=0;
  68.     }

  69. }
  70. MSH_CMD_EXPORT(am2301, RT-am2301 sample);
  71. int myapp(void)
  72. {
  73.     static rt_thread_t tid1 = RT_NULL;
  74.     static rt_thread_t tid2 = RT_NULL;
  75.         /* 创建线程1 */
  76.         tid1 = rt_thread_create("thread1",
  77.                                 am2301, RT_NULL,
  78.                                 THREAD_STACK_SIZE,
  79.                                 THREAD_PRIORITY, THREAD_TIMESLICE);
  80.         if (tid1 != RT_NULL)
  81.             rt_thread_startup(tid1);

  82.         tid2 = rt_thread_create("thread2",
  83.                                 led, RT_NULL,
  84.                                 THREAD_STACK_SIZE,
  85.                                 THREAD_PRIORITY-1, THREAD_TIMESLICE);
  86.         if (tid2 != RT_NULL)
  87.             rt_thread_startup(tid2);

  88.     return 0;
  89. }
  90. MSH_CMD_EXPORT(myapp, RT-Thread sample);


  91. int main(void)
  92. {
  93.     rt_kprintf("Hello\n");
  94.     rt_thread_mdelay(1000);
  95.     myapp();
  96.     return RT_EOK;
  97. }



 楼主| gaoyang9992006 发表于 2020-8-29 22:53 | 显示全部楼层
553695f4a6b7cb1eda.png
这么凌乱的显示顺序,说明一个问题两个线程是互相不影响的,不会傻傻的只让一个线程霸占了CPU,也就是通过RTOS实现了分时复用CPU。
这就是RTOS的好处,如果你用于按键操作,同时要扫描显示到数码管,你会发现RTOS是你明智的选择。这样按键傻傻等待的时候不会导致显示中断
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部