找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 14086|回复: 20
打印 上一主题 下一主题
收起左侧

PMS7003 PM2.5测试仪,带SHT20温湿度 STM32源码

  [复制链接]
跳转到指定楼层
楼主
由于网上的PM2.5测试仪质量不一,多数测试仪传感器只能定性,而不能精确定量,而且价格还很贵,所以在家没事做了个PM2.5测试仪,带温度显示
配件:
1、空气质量传感器为攀腾第七代PMS7003传感器
2、温湿度传感器为SHT20
3、单片机STM32F103C8T6
屏幕各界面显示数据:空气质量指数,PM2.5.PM0.3.PM0.5.PM1.0.PM2.5.PM10颗粒数,含量以及温湿度




特别提示:代码我只上传了攀藤7003传感器的官方测试代码,希望各位电子爱好者勇于探索,功到才能自然成。


单片机源程序如下:
  1. #include "global_includes.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "stm32f10x_rcc.h"


  5. typedef struct
  6. {
  7.         uint16_t Buffer_Len;
  8.         uint16_t PM1_0_CF;
  9.         uint16_t PM2_5_CF;
  10.         uint16_t PM10_CF;
  11.         uint16_t PM1_0;
  12.         uint16_t PM2_5;
  13.         uint16_t PM10;
  14.         uint16_t Count0_3nm;
  15.         uint16_t Count0_5nm;
  16.         uint16_t Count1_0nm;
  17.         uint16_t Count2_5nm;
  18.         uint16_t Count5_0nm;
  19.         uint16_t Count10nm;
  20. }PM_Sensor_DataStruct;

  21. typedef enum {RESET = 0, SET = !RESET} FlagStatus;
  22. typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;

  23. PM_Sensor_DataStruct        PM_Sensor_Data;
  24. uint8_t         PM_Sensor_RxBuffer[50];
  25. uint16_t    PM_Sensor_RxTimeOut = 0;
  26. uint16_t    PM_Sensor_RxCount = 0;

  27. FlagStatus  PM_Sensor_RxFinish = RESET;


  28. void SysTick_Handler(void)  // SYS timer interrupt function
  29. {
  30.         //OS_TimeMS ++;   //   ++1us for os timer
  31.         //==========================================================================
  32.         if(PM_Sensor_RxTimeOut != 0x00) // timeout for PM data receive
  33.         {
  34.                 PM_Sensor_RxTimeOut--;
  35.         }
  36.         else
  37.         {
  38.                 if((PM_Sensor_RxCount)&&(PM_Sensor_RxBuffer[0] == 'B')&&(PM_Sensor_RxBuffer[1] == 'M'))
  39.                 {
  40.                         PM_Sensor_RxCount = 0;
  41.                         PM_Sensor_RxFinish = SET;
  42.                         USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
  43.                 }
  44.                 else
  45.                 {
  46.                         PM_Sensor_RxCount = 0;
  47.                 }
  48.         }
  49. }

  50. void USART1_IRQHandler(void)  // USART1 interrupt
  51. {
  52.         static uint8_t                 USART1_ByteData = 0;

  53.         if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  54.         {
  55.                 USART1_ByteData = USART_ReceiveData(USART1);

  56.                 if(PM_Sensor_RxFinish == RESET)
  57.                 {
  58.                         PM_Sensor_RxBuffer[PM_Sensor_RxCount++] = USART1_ByteData;
  59.                         PM_Sensor_RxTimeOut = 20;
  60.                 }

  61.         }
  62.         //============================================================================
  63.         if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)
  64.         {
  65.                 USART1_ByteData = USART_ReceiveData(USART1);
  66.                 USART_ClearFlag(USART1, USART_FLAG_ORE);
  67.         }

  68.         if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)
  69.         {
  70.                 USART_ClearFlag(USART1, USART_FLAG_NE);
  71.         }


  72.         if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)
  73.         {
  74.                 USART_ClearFlag(USART1, USART_FLAG_FE);
  75.         }

  76.         if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)
  77.         {
  78.                 USART_ClearFlag(USART1, USART_FLAG_PE);
  79.         }
  80. }
  81. //=============================================================================
  82. //PM_USART1_Configuartion  USART1 configuration
  83. //=============================================================================
  84. void PM_USART1_Configuartion(void)
  85. {
  86.           USART_InitTypeDef USART_InitStructure;
  87.           GPIO_InitTypeDef  GPIO_InitStructure;

  88.          
  89.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
  90.                                                         RCC_APB2Periph_GPIOC, ENABLE);

  91.          
  92.           RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE);

  93.        
  94.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  95.        
  96.        
  97.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  98.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                //
  99.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  100.        
  101.        
  102.         /* PA9 USART1_Tx */
  103.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  104.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                        //推挽输出-TX
  105.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  106.         /* PA10 USART1_Rx */
  107.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  108.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入-RX
  109.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  110.           USART_InitStructure.USART_BaudRate             = 9600;                                                //波特率
  111.           USART_InitStructure.USART_WordLength           = USART_WordLength_8b;                   //设置数据长度为8bit
  112.           USART_InitStructure.USART_StopBits             = USART_StopBits_1;                      //停止位为1
  113.           USART_InitStructure.USART_Parity               = USART_Parity_No;                       //无校验位
  114.           USART_InitStructure.USART_HardwareFlowControl  = USART_HardwareFlowControl_None;//数据流控制为none
  115.           USART_InitStructure.USART_Mode                 = USART_Mode_Rx | USART_Mode_Tx; //接收和发送模式都打开

  116.           USART_Init(USART1, &USART_InitStructure);                                                 //初始化串口1

  117.           USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);                                         // 接收接收中断

  118.         USART_ITConfig(USART1, USART_IT_ERR | USART_IT_PE, ENABLE);

  119.           /* Enable the USART1 */
  120.           USART_Cmd(USART1, ENABLE);                                                                          //使能USART1
  121. }


  122. //=============================================================================
  123. //Check_PMSensor_DataValid    //
  124. //=============================================================================
  125. ErrorStatus        Check_PMSensor_DataValid(void)
  126. {
  127.         uint16_t         Cal_CheckSum;
  128.         uint16_t         Buffer_CheckSum;
  129.         uint16_t         Buffer_Len;
  130.         uint8_t         i;
  131.         ErrorStatus Result = ERROR;

  132.         if((PM_Sensor_RxBuffer[0] == 'B')&&(PM_Sensor_RxBuffer[1] == 'M'))
  133.         {
  134.                 Buffer_Len = (uint16_t)((PM_Sensor_RxBuffer[2] << 8) | PM_Sensor_RxBuffer[3]);

  135.                 Buffer_CheckSum = (uint16_t)((PM_Sensor_RxBuffer[Buffer_Len + 2] << 8) | PM_Sensor_RxBuffer[Buffer_Len + 3]);

  136.                 Cal_CheckSum = 0;
  137.                 for(i=0;i<(Buffer_Len + 2);i++)
  138.                 {
  139.                         Cal_CheckSum += PM_Sensor_RxBuffer[i];
  140.                 }

  141.                 if(Cal_CheckSum == Buffer_CheckSum)
  142.                         Result = SUCCESS;
  143.         }
  144.         return Result;
  145. }
  146. //=============================================================================
  147. //PMSensor_DataReflash    //
  148. //=============================================================================
  149. void PMSensor_DataReflash(void)
  150. {
  151.         uint16_t Buffer_Len;

  152.         memset(&PM_Sensor_Data,0,(sizeof(PM_Sensor_Data) - 2)); //PM_Sensor_Data.PM2_5_Old should not set to zero
  153.        
  154.         Buffer_Len = (uint16_t)((PM_Sensor_RxBuffer[2] << 8) | PM_Sensor_RxBuffer[3]);
  155.         if(Buffer_Len == 28)   //PMS1003/5003
  156.         {
  157.                 PM_Sensor_Data.Buffer_Len = 28;
  158.                 PM_Sensor_Data.PM1_0_CF = (uint16_t)((PM_Sensor_RxBuffer[4]<<8) | PM_Sensor_RxBuffer[5]);
  159.                 PM_Sensor_Data.PM2_5_CF = (uint16_t)((PM_Sensor_RxBuffer[6]<<8) | PM_Sensor_RxBuffer[7]);
  160.                 PM_Sensor_Data.PM10_CF         = (uint16_t)((PM_Sensor_RxBuffer[8]<<8) | PM_Sensor_RxBuffer[9]);
  161.                 PM_Sensor_Data.PM1_0         = (uint16_t)((PM_Sensor_RxBuffer[10]<<8) | PM_Sensor_RxBuffer[11]);
  162.                 PM_Sensor_Data.PM2_5         = (uint16_t)((PM_Sensor_RxBuffer[12]<<8) | PM_Sensor_RxBuffer[13]);
  163.                 PM_Sensor_Data.PM10         = (uint16_t)((PM_Sensor_RxBuffer[14]<<8) | PM_Sensor_RxBuffer[15]);
  164.                 PM_Sensor_Data.Count0_3nm = (uint16_t)((PM_Sensor_RxBuffer[16]<<8) | PM_Sensor_RxBuffer[17]);
  165.                 PM_Sensor_Data.Count0_5nm = (uint16_t)((PM_Sensor_RxBuffer[18]<<8) | PM_Sensor_RxBuffer[19]);
  166.                 PM_Sensor_Data.Count1_0nm = (uint16_t)((PM_Sensor_RxBuffer[20]<<8) | PM_Sensor_RxBuffer[21]);
  167.                 PM_Sensor_Data.Count2_5nm = (uint16_t)((PM_Sensor_RxBuffer[22]<<8) | PM_Sensor_RxBuffer[23]);
  168.                 PM_Sensor_Data.Count5_0nm = (uint16_t)((PM_Sensor_RxBuffer[24]<<8) | PM_Sensor_RxBuffer[25]);
  169.                 PM_Sensor_Data.Count10nm = (uint16_t)((PM_Sensor_RxBuffer[26]<<8) | PM_Sensor_RxBuffer[27]);
  170.                
  171.         }
  172.         else if(Buffer_Len == 20)// PMS3003
  173.         {
  174.                 PM_Sensor_Data.Buffer_Len = 20;
  175.                 PM_Sensor_Data.PM1_0_CF = (uint16_t)((PM_Sensor_RxBuffer[4]<<8) | PM_Sensor_RxBuffer[5]);
  176.                 PM_Sensor_Data.PM2_5_CF = (uint16_t)((PM_Sensor_RxBuffer[6]<<8) | PM_Sensor_RxBuffer[7]);
  177.                 PM_Sensor_Data.PM10_CF         = (uint16_t)((PM_Sensor_RxBuffer[8]<<8) | PM_Sensor_RxBuffer[9]);
  178.                 PM_Sensor_Data.PM1_0         = (uint16_t)((PM_Sensor_RxBuffer[10]<<8) | PM_Sensor_RxBuffer[11]);
  179.                 PM_Sensor_Data.PM2_5         = (uint16_t)((PM_Sensor_RxBuffer[12]<<8) | PM_Sensor_RxBuffer[13]);
  180.                 PM_Sensor_Data.PM10         = (uint16_t)((PM_Sensor_RxBuffer[14]<<8) | PM_Sensor_RxBuffer[15]);
  181.                 PM_Sensor_Data.Count0_3nm = 0;
  182.                 PM_Sensor_Data.Count0_5nm = 0;
  183.                 PM_Sensor_Data.Count1_0nm = 0;
  184.                 PM_Sensor_Data.Count2_5nm = 0;
  185.                 PM_Sensor_Data.Count5_0nm = 0;
  186.                 PM_Sensor_Data.Count10nm = 0;
  187.         }
  188. }

  189. int main(void)
  190. {
  191.         /*!< At this stage the microcontroller clock setting is already configured,
  192.                 this is done through SystemInit() function which is called from startup
  193.                 file (startup_stm32f10x_xx.s) before to branch to application main.
  194.                 To reconfigure the default setting of SystemInit() function, refer to
  195.                 system_stm32f10x.c file
  196.         */
  197.         SetSysClockInternal();  // sysclock for internal  RC
  198.     /**/   
  199.         SysTick_Init();

  200.         /**/
  201.         NVIC_Configuration();

  202.         /**/
  203.         PM_USART1_Configuartion();
  204.        
  205.         /**/
  206. ……………………

  207. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
PMS7003测试代码.rar (2.24 KB, 下载次数: 312)





评分

参与人数 2黑币 +8 收起 理由
七号123 + 4 很给力!
zhangli019 + 4 赞一个!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:228577 发表于 2017-8-21 10:33 | 只看该作者
想看看
回复

使用道具 举报

板凳
ID:238505 发表于 2017-10-11 16:43 | 只看该作者
很好的参考
回复

使用道具 举报

地板
ID:198608 发表于 2017-10-11 23:52 来自手机 | 只看该作者
楼主,能向你学习吗
回复

使用道具 举报

5#
ID:242109 发表于 2017-10-23 15:03 | 只看该作者
学习了
回复

使用道具 举报

6#
ID:70546 发表于 2017-11-21 21:59 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

7#
ID:15207 发表于 2017-12-26 16:47 | 只看该作者
这个传感器是上电后每隔一段时间定时主动发送一条串口数据给单片机吗?
回复

使用道具 举报

8#
ID:267330 发表于 2017-12-26 20:00 | 只看该作者
我正要找SHT20程序啊
回复

使用道具 举报

9#
ID:270197 发表于 2018-1-2 14:59 | 只看该作者
看看,谢谢
回复

使用道具 举报

10#
ID:273651 发表于 2018-1-9 11:02 | 只看该作者
谢谢楼主的分享
回复

使用道具 举报

11#
ID:288544 发表于 2018-3-7 09:55 | 只看该作者
感谢分享
回复

使用道具 举报

12#
ID:289262 发表于 2018-3-29 09:46 | 只看该作者
好东西,下载学习下。谢谢
回复

使用道具 举报

13#
ID:334781 发表于 2018-5-21 16:35 | 只看该作者
SHT20 这款传感器不错,有51的程序更好了
回复

使用道具 举报

14#
ID:366196 发表于 2018-7-6 14:29 | 只看该作者
资料能发一份到我邮箱吗??gavin1111@126.com
谢谢
回复

使用道具 举报

15#
ID:366196 发表于 2018-7-6 14:37 | 只看该作者
memset(&PM_Sensor_Data,0,(sizeof(PM_Sensor_Data) - 2));请问这句是什么意思?memset是什么
回复

使用道具 举报

16#
ID:560737 发表于 2019-6-12 11:25 | 只看该作者
看看大佬的
回复

使用道具 举报

17#
ID:526058 发表于 2019-11-9 23:52 | 只看该作者
这代码质量还可以,就是没贴完整。
回复

使用道具 举报

18#
ID:646328 发表于 2019-11-21 10:23 | 只看该作者
学习一下,观摩
回复

使用道具 举报

19#
ID:818839 发表于 2020-9-14 14:01 | 只看该作者
您的这个PMS7003的机器能给我一些吗?我不要7003模块,只要外壳和板子
回复

使用道具 举报

20#
ID:825701 发表于 2020-12-24 21:13 | 只看该作者
没想到,这里居然有我想要的
回复

使用道具 举报

21#
ID:1120670 发表于 2024-5-16 16:08 | 只看该作者
问一下大佬,global_includes.h是什么文件,里面都声明了哪些啊?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表