原理图
解析程序
逻辑是:
1、初始化串口和定时器10ms中断
2、循环读取一帧数据到rev_CH2O_bufferdata
3、在主函数解析数据rev_CH2O_bufferdata
4、最终的pm2.5数值就是CH2O_value
使用CH2O_value的数据即可。
PPB单位,除以1000就是ppm,再乘以1.34那么单位就是mg/m3。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "led.h"
#include "timer.h"
char rev_CH2O_bufferdata[15];
char rev_CH2O_data_cnt = 0;
char rev_CH2O_flag = 0;
char rev_CH2O_timercnt = 0;
char rev_CH2O_sucess = 0;
uint32_t CH2O_value = 0; //PPB单位
uint8_t CH2O_verify = 0;
unsigned char CH2O_verify_cnt = 0;
int main(void) {
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
delay_ms(500);
uart_init(9600);
TIM4_Int_Init(99, 7199); /* 10Khz的计数频率,计数到50为10ms */
TIM_Cmd(TIM4, ENABLE); /* 使能TIMx 开始计时 */
while (1) {
delay_ms(5);
if (rev_CH2O_sucess == 1) {
rev_CH2O_sucess = 0;
if ((rev_CH2O_bufferdata[0] == 0xff) && (rev_CH2O_bufferdata[1] == 0x17)) {
CH2O_verify = 0;
for (CH2O_verify_cnt = 1; CH2O_verify_cnt < 8; CH2O_verify_cnt++) {
CH2O_verify += rev_CH2O_bufferdata[CH2O_verify_cnt];
}
CH2O_verify = ~CH2O_verify;
CH2O_verify += 1;
if (CH2O_verify == rev_CH2O_bufferdata[8]) {
CH2O_value = rev_CH2O_bufferdata[4] * 256 + rev_CH2O_bufferdata[5];
}
}
}
}
}
// 10ms
void TIM4_IRQHandler(void) /* TIM4中断 */
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) /* 检查TIM4更新中断发生与否 */
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); /* 清除TIM4更新中断标志 */
//10ms一帧
if (rev_CH2O_flag == 1) {
rev_CH2O_timercnt++;
}
if (rev_CH2O_timercnt >= 4) {
rev_CH2O_timercnt = 0;
rev_CH2O_flag = 0;
//数据处理标志
rev_CH2O_sucess = 1;
}
}
}
//A9模块
void USART1_IRQHandler(void) /* 串口1中断服务程序 */
{
u8 receiveData;
if (USART_GetITStatus(USART1, USART_IT_RXNE) !=
RESET) /* 接收中断(接收到的数据必须是0x0d 0x0a结尾) */
{
receiveData = USART_ReceiveData(USART1); /* 读取接收到的数据 */
if (rev_pm25_flag == 0) {
rev_pm25_data_cnt = 0;
rev_pm25_bufferdata[rev_pm25_data_cnt++] = receiveData;
rev_pm25_flag = 1;
} else if (rev_pm25_flag == 1) {
rev_pm25_bufferdata[rev_pm25_data_cnt++] = receiveData;
if (rev_pm25_data_cnt >= 50) {
rev_pm25_data_cnt = 0;
}
}
}
}
帮助、问询
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?tab=BB08J2