先吐槽这家淘宝吧,问了客服只有文档,没有代码,看了网上的资料,没有这代码,一怒之下,拿起键盘CNM。最后还是老老实实写吧,也就一个串口中断接收程序,外加数据帧的完整接收。
直接贴主要代码!
u16 USART1_RxCounter = 0;
char USART1_RxBuff[1024];
volatile uint8_t ucTemp; // 用于存储接收到的字节
volatile uint8_t u1_number = 0; // 用于记录接收到的字节数量
volatile uint8_t DATAH = 0; // 存储数据字节1
volatile uint8_t DATAL = 0; // 存储数据字节2
volatile uint8_t CHECKSUM = 0; // 存储校验字节
// 串口中断服务函数
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
ucTemp = USART_ReceiveData(USART1); // 读取接收到的数据
if(u1_number == 0 && ucTemp == 0xA5) // 如果是第一个字节且为特征字节
{
u1_number++;
}
else if(u1_number > 0 && u1_number < 4) // 如果已经接收到特征字节,继续接收数据
{
if(u1_number == 1)
{
DATAH = ucTemp; // 存储数据字节1
u1_number++;
}
else if(u1_number == 2)
{
DATAL = ucTemp; // 存储数据字节2
u1_number++;
}
else if(u1_number == 3)
{
CHECKSUM = ucTemp; // 存储校验字节
uint8_t sum = 0xA5 + DATAH + DATAL; // 计算校验和
sum = sum ^ 0x80 ; // ^ 异或,得到低7位数据
if(sum != CHECKSUM) // 如果最高位为1,则校验失败 ^ 异或,得到低7位数据
{
// 可以在这里添加错误处理代码
u1_number = 0; //从新计数
}
else
{
// 校验成功,计算浓度值
uint16_t concentration = (DATAH << 7) | (DATAL & 0x7F);
// 这里可以添加代码将浓度值发送给其他模块或显示
PM2_5_val = concentration;
}
u1_number = 0; // 重置计数器,准备接收下一帧数据
}
}
else
{
u1_number = 0; // 如果接收到的数据不是特征字节,重置计数器
}
USART_SendData(USART1, ucTemp); // 回显接收到的数据
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); // 等待发送完成
}
}
然后就是配置串口的中断等等,这个不重要,但凡学过的都会,按照你自己的来就好,我就不贴了。
通信协议:
测试
阿里云云端数据查看
可以看到数据正常显示
一段时间后
串口上位机数据查看,
一段时间后
数据正常读取。
代码完美运行!!!
注意:这个传感器是要通过穿孔的折射光等等判断PM值,请正确摆放传感器!
另外贴上该新款传感器的数据手册:(新)D01粉尘传感器说明书