使用C语言编写代码实现以下功能:循环接收串口数据自动缓冲处理解析出指令内容指令以#号开头以n结尾。
假设使用的是串口1,波特率为9600,以下是代码实现:
#include <stdio.h>
#include <string.h>
#include "stm32f4xx.h"
#define BUFFER_SIZE 128
char buffer[BUFFER_SIZE];
int buffer_index = 0;
int flag_receive = 0;
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
char received = USART_ReceiveData(USART1);
if (received == '#')
{
// 开始接收指令
buffer_index = 0;
flag_receive = 1;
}
else if (received == '\n')
{
// 指令接收完成
flag_receive = 0;
buffer[buffer_index] = '\0';
printf("Received: %s\n", buffer);
}
else if (flag_receive && buffer_index < BUFFER_SIZE - 1)
{
// 正在接收指令
buffer[buffer_index++] = received;
}
}
}
int main(void)
{
// 初始化串口1
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 配置PA9为复用功能,用于USART1_TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置PA10为复用功能,用于USART1_RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); // 将PA9引脚复用为USART1_TX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); // 将PA10引脚复用为USART1_RX
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// 使能USART1接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置USART1中断优先级
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
while (1)
{
// 程序主循环
}
}
解释一下代码:
- 定义了一个长度为128的缓冲区
buffer,一个缓冲区指针buffer_index,以及一个标志位flag_receive,表示当前是否在接收指令。 - 在
USART1_IRQHandler中断处理函数中,判断接收到的字符是否为#,如果是,则说明开始接收指令,将缓冲区指针归零,标志位设为1;如果接收到的字符为\n,则说明指令接收完成,标志位设为0,缓冲区最后一个字符设为\0,即字符串结尾标志,然后打印出接收到的指令。 - 在主函数中,初始化USART1,使能接收中断,配置中断优先级,然后进入主循环
原文地址: https://www.cveoy.top/t/topic/hrgr 著作权归作者所有。请勿转载和采集!