STM32读取PM2.5.PM10的数据。串口1发送命令,串口2读取数据。

STM32读取PM2.5.PM10的数据。串口1发送命令,串口2读取数据。
用串口1发送开机命令,STM32接收到数据后通过串口2发送给传感器。数据的发送是通过中断发送,下面贴出程序源码,由于是初学,有不合适的欢迎提出来一起学习。

串口1初始化,及相关函数
#include “usart.h”

/**

  • @brief 配置中断优先级参数 使用中断时在主函数开始要加入 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);配置嵌套向量中断控制器组

  • @param 无

  • @retval 无
    **/
    static void NVIC_Config(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = CUSTOM_USART1_IRQ; //配置USART为中断源
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级
    NVIC_Init(&NVIC_InitStructure);
    }

/**

  • @brief 初始化串口1,配置中断优先级

  • @param 无

  • @retval 无
    **/
    void USART1_Custom_Init(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStrutre;

    CUSTOM_USART1_APBxClkCmd(CUSTOM_USART1_CLK, ENABLE);
    CUSTOM_USART1_GPIO_APBxClkCmd(CUSTOM_USART1_GPIO_CLK, ENABLE);

    // 将USART Tx的GPIO配置为推挽复用模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = CUSTOM_USART1_TX_GPIO_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(CUSTOM_USART1_TX_GPIO_PORT, &GPIO_InitStructure);

    // 将USART Rx的GPIO配置为浮空输入模式
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = CUSTOM_USART1_RX_GPIO_PIN;
    GPIO_Init(CUSTOM_USART1_RX_GPIO_PORT, &GPIO_InitStructure);

    USART_InitStrutre.USART_BaudRate = CUSTOM_USART1_BaudRate;
    USART_InitStrutre.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStrutre.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStrutre.USART_Parity = USART_Parity_No;
    USART_InitStrutre.USART_StopBits = USART_StopBits_1;
    USART_InitStrutre.USART_WordLength = USART_WordLength_8b;
    USART_Init(CUSTOM_USART1x, &USART_InitStrutre); //初始化串口1

    NVIC_Config(); //需要中断服务的时候开启
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //需要中断服务的时候开启,开启串口接受中断

    USART_Cmd(CUSTOM_USART1x, ENABLE);// 使能串口
    }

/**

  • @brief 发送一个字节
  • @param pUSARTx选择串口 Data数据
  • @retval 无
    **/
    void Usart_SendByte(USART_TypeDef *pUSARTx, uint8_t Data)
    {
    USART_SendData(pUSARTx, Data);
    while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
    }

/**

  • @brief 发送一个数组
  • @param pUSARTx选择串口 data数组首地址 num数组长度
  • @retval 无
    */
    void Usart_SendArray(USART_TypeDef
    pUSARTx, uint8_t *data, uint8_t num)
    {
    uint8_t t;
    for(t = 0; t < num; t++)
    {
    Usart_SendByte(pUSARTx, data[t]);
    }
    while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
    }

///**
//* @brief 接收一个字节
//* @param pUSARTx选择串口
//* @retval 接收到的数据
//**/
//uint8_t Usart_ReceiveByte(USART_TypeDef *pUSARTx)
//{
// uint8_t GetData = 0;
// if(USART_GetFlagStatus(pUSARTx ,USART_FLAG_RXNE) == SET)
// GetData = USART_ReceiveData(pUSARTx);
// USART_ClearFlag(pUSARTx, USART_FLAG_RXNE);
// return GetData;
//}

///**
//* @brief 接收多个字节的数组 该函数使用需要有帧头帧尾
//* @param pUSARTx选择串口 data数组首地址 start帧头 end帧尾
//* @retval 错误返回1
//**/
//void Usart_ReceiceArray(USART_TypeDef* pUSARTx, uint8_t *data, uint8_t num)
//{
// uint8_t temp;
// for(temp = 0; temp < num; temp++)
// {
// data[temp] = Usart_ReceiveByte(pUSARTx);
// }
//}

//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, (uint8_t) ch);
while (USART_GetFlagStatus(CUSTOM_USART1x, USART_FLAG_TXE) == RESET);

	return ch;

}

//重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
while (USART_GetFlagStatus(CUSTOM_USART1x, USART_FLAG_RXNE) == RESET);

	return (int)USART_ReceiveData(CUSTOM_USART1x);

}

串口1对应的头文件

#ifndef USART_H
#define USART_H

#include “stm32f10x.h”
#include <stdio.h>

//串口1-USART1
#define CUSTOM_USART1_APBxClkCmd RCC_APB2PeriphClockCmd
#define CUSTOM_USART1_CLK RCC_APB2Periph_USART1
#define CUSTOM_USART1x USART1
#define CUSTOM_USART1_BaudRate 115200

//USART_GPIO
#define CUSTOM_USART1_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define CUSTOM_USART1_GPIO_CLK RCC_APB2Periph_GPIOA

#define CUSTOM_USART1_TX_GPIO_PORT GPIOA
#define CUSTOM_USART1_TX_GPIO_PIN GPIO_Pin_9
#define CUSTOM_USART1_RX_GPIO_PORT GPIOA
#define CUSTOM_USART1_RX_GPIO_PIN GPIO_Pin_10

#define CUSTOM_USART1_IRQ USART1_IRQn
#define CUSTOM_USART1_IRQHandler USART1_IRQHandler

//串口2-USART2
#define CUSTOM_USART2_APBxClkCmd RCC_APB1PeriphClockCmd
#define CUSTOM_USART2_CLK RCC_APB1Periph_USART2
#define CUSTOM_USART2x USART2
#define CUSTOM_USART2_BaudRate 9600

//USART_GPIO
#define CUSTOM_USART2_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define CUSTOM_USART2_GPIO_CLK RCC_APB2Periph_GPIOA

#define CUSTOM_USART2_TX_GPIO_PORT GPIOA
#define CUSTOM_USART2_TX_GPIO_PIN GPIO_Pin_2
#define CUSTOM_USART2_RX_GPIO_PORT GPIOA
#define CUSTOM_USART2_RX_GPIO_PIN GPIO_Pin_3

#define CUSTOM_USART2_IRQ USART2_IRQn
#define CUSTOM_USART2_IRQHandler USART2_IRQHandler

////串口3-USART3
//#define CUSTOM_USART3_APBxClkCmd RCC_APB1PeriphClockCmd
//#define CUSTOM_USART3_CLK RCC_APB1Periph_USART3
//#define CUSTOM_USART3x USART3
//#define CUSTOM_USART3_BaudRate 115200

////USART_GPIO
//#define CUSTOM_USART3_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//#define CUSTOM_USART3_GPIO_CLK RCC_APB2Periph_GPIOB

//#define CUSTOM_USART3_TX_GPIO_PORT GPIOB
//#define CUSTOM_USART3_TX_GPIO_PIN GPIO_Pin_10
//#define CUSTOM_USART3_RX_GPIO_PORT GPIOB
//#define CUSTOM_USART3_RX_GPIO_PIN GPIO_Pin_11

//#define CUSTOM_USART3_IRQ USART3_IRQn
//#define CUSTOM_USART3_IRQHandler USART3_IRQHandler

////串口4-UART4
//#define CUSTOM_USART3_APBxClkCmd RCC_APB1PeriphClockCmd
//#define CUSTOM_USART3_CLK RCC_APB1Periph_UART4
//#define CUSTOM_USART3x UART4
//#define CUSTOM_USART3_BaudRate 115200

////USART_GPIO
//#define CUSTOM_USART3_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//#define CUSTOM_USART3_GPIO_CLK RCC_APB2Periph_GPIOC

//#define CUSTOM_USART3_TX_GPIO_PORT GPIOC
//#define CUSTOM_USART3_TX_GPIO_PIN GPIO_Pin_10
//#define CUSTOM_USART3_RX_GPIO_PORT GPIOC
//#define CUSTOM_USART3_RX_GPIO_PIN GPIO_Pin_11

//#define CUSTOM_USART3_IRQ UART4_IRQn
//#define CUSTOM_USART3_IRQHandler UART4_IRQHandler

////串口5-UART5
//#define CUSTOM_USART3_APBxClkCmd RCC_APB1PeriphClockCmd
//#define CUSTOM_USART3_CLK RCC_APB1Periph_UART5
//#define CUSTOM_USART3x UART5
//#define CUSTOM_USART3_BaudRate 115200

////USART_GPIO
//#define CUSTOM_USART3_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
//#define CUSTOM_USART3_GPIO_CLK (RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD)

//#define CUSTOM_USART3_TX_GPIO_PORT GPIOC
//#define CUSTOM_USART3_TX_GPIO_PIN GPIO_Pin_12
//#define CUSTOM_USART3_RX_GPIO_PORT GPIOD
//#define CUSTOM_USART3_RX_GPIO_PIN GPIO_Pin_2

//#define CUSTOM_USART3_IRQ UART5_IRQn
//#define CUSTOM_USART3_IRQHandler UART5_IRQHandler

void USART1_Custom_Init(void);
void Usart_SendByte(USART_TypeDef pUSARTx, uint8_t Data);
void Usart_SendArray(USART_TypeDef
pUSARTx, uint8_t *data, uint8_t num);
//uint8_t Usart_ReceiveByte(USART_TypeDef pUSARTx);
//void Usart_ReceiceArray(USART_TypeDef
pUSARTx, uint8_t *data, uint8_t num);

#endif

主函数:

#include “stm32f10x.h”
#include “delay.h”
#include “usart.h”
#include “pm10.h”

u8 USART_RX_Cmd[10];
u8 USART_RX_Data[10];
u8 Cmd_Data[9] = {0xAA, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x67, 0xBB};
u8 Cmd_End[9] = {0xAA, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x68, 0xBB};
u8 num, num_1 = 0, num_s1 = 0, num_2 = 0, num_s2 = 0;

int main(void)
{
u8 i, flag = 0;
uint16_t temp_10, temp;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
USART1_Custom_Init();
USART2_Custom_Init();
Usart_SendArray(USART2, Cmd_End, 9);
while(1)
{
if(flag == 1)
{
Usart_SendArray(USART2, Cmd_Data, 9);
temp_10 = USART_RX_Data[4] * 256 + USART_RX_Data[5];
temp = USART_RX_Data[2] * 256 + USART_RX_Data[3];
printf(“PM2.5浓度为%d\t PM10浓度为%d\r\n”, temp, temp_10);
for(i=0; i<9; i++)
{
USART_RX_Data[i] = 0x00;
}
}
if((USART_RX_Cmd[0] == 0xAA) && (USART_RX_Cmd[1] == 0x01))
{
Usart_SendArray(USART2, USART_RX_Cmd, 9);
for(i=0; i<9; i++)
{
USART_RX_Cmd[i] = 0x00;
}
flag = 1;
}
if((USART_RX_Cmd[0] == 0xAA) && (USART_RX_Cmd[1] == 0x03))
{
Usart_SendArray(USART2, USART_RX_Cmd, 9);
for(i=0; i<9; i++)
{
USART_RX_Cmd[i] = 0x00;
USART_RX_Data[i] = 0x00;
}
flag = 0;
}
delay_ms(5000);
}
}

void CUSTOM_USART1_IRQHandler(void) //串口1中断服务程序
{
if(USART_GetITStatus(CUSTOM_USART1x ,USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(CUSTOM_USART1x, USART_IT_RXNE);
USART_RX_Cmd[num_1] = USART_ReceiveData(CUSTOM_USART1x);
num_1 ++;
}
if(USART_RX_Cmd[num_1 - 1] == 0xAA)
num_s1 = num_1 - 1;
if((USART_RX_Cmd[num_s1] == 0xAA) && (USART_RX_Cmd[num_1 - 1] == 0xBB))
{
num_1 = 0;
}
if(USART_GetFlagStatus(CUSTOM_USART1x, USART_FLAG_ORE) == SET) //溢出
{
USART_ClearFlag(CUSTOM_USART1x, USART_FLAG_ORE); //读SR
USART_ReceiveData(CUSTOM_USART1x); //读DR
}
}

void CUSTOM_USART2_IRQHandler(void) //串口2中断服务程序
{
if(USART_GetITStatus(CUSTOM_USART2x ,USART_IT_RXNE) == SET)
{
USART_ClearITPendingBit(CUSTOM_USART2x, USART_IT_RXNE);
USART_RX_Data[num_2] = USART_ReceiveData(CUSTOM_USART2x);
num_2 ++;
}
if(USART_RX_Data[num_2 - 1] == 0xAA)
num_s2 = num_2 - 1;
if((USART_RX_Data[num_s2] == 0xAA) && (USART_RX_Data[num_2 - 1] == 0xBB))
{
num_2 = 0;
}
if(USART_GetFlagStatus(CUSTOM_USART2x, USART_FLAG_ORE) == SET) //溢出
{
USART_ClearFlag(CUSTOM_USART2x, USART_FLAG_ORE); //读SR
USART_ReceiveData(CUSTOM_USART2x); //读DR
}
}

数据读取的完整工程代码