作为环境数据监测站首先要获取大气中可吸入颗粒物的数据。为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据。
该型传感器的检测对象如下:
M2.5:测量空气中0.3-2.5微米颗粒物;
PM10:测量空气中 0.3-10微米颗粒物。
该传感器采用的通讯协议如下:
(1)波特率: 9600bit/S;数据位:8位;停止位:1位;校验位:无;
(2)数据发送间隔时间为0.8~1.2S(秒) ,
(3)数据格式:7个字节,其中校验位=PM2.5(H)+PM2.5(L)+PM10(H)+PM10(L)。如图:
(4)数据处理:
接收到的数据按公式计算后得到PM2.5和PM10的值,例如:
PM2.5= ( PM2.5(H)×256+PM2.5(L)) ×0.1;
PM10= ( PM2.5(H)×256+PM2.5(L)) ×0.1
传感器要与OneNet麒麟座相连,我们必须看看其接口需求:
如上图所示其需要5V电源和一个串口以及一个GPIO口,我们在麒麟座上发现USART1(PA9:USART1_TX,PA10:USART1_RX)端口已经引到了J5端子排的J5_6和J5_5。同时需要的一个GPIO口我们选用PA8,因为也被引到了J5端子排的J5_7。只有5V电源我们没有发现引出来,但这没有问题,所有的5V电源均引自电源开关SW1的第6脚,我们焊接一根导线来解决这个问题。至于接地(GND)已经引到了端子排J5_9和J6_2,直接使用就可以了。
接好线后我们使用STM32CubeMX配置好硬件接口,串口的通讯参数,中断,时钟等,并生成基本的配置代码,如下图所示:
配置代码如下:
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)rxBuffer, 7);
}
以上最后一行用于开启接收中断并且设置接收缓冲以及接收缓冲接收最大数据量,因为传感器的返回字节为固定的7个字节所以我们就直接设定好了。当然中断产生后,中断服务程序会关掉中断,所以我们在回调函数中要将其重开才能进行下一次接收。
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(Senser_Set_GPIO_Port, Senser_Set_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Pin = Senser_Set_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(Senser_Set_GPIO_Port, &GPIO_InitStruct);
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART1)
{
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
配置完成后我们还需要按照协议对数据进行解析,解析完全就是将协议翻译成编程语言,非常简单,在此就不说了。最后再来一张结果显示: