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); //初始化串口1NVIC_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
}
}