一、应用简介
本文介绍串口中断接收不定长字符串的方法。将串口1配置接收中断使能、空闲中断使能来接收不定长数据。
也就是在配置串口中断的时候使能接收中断和空闲中断。如下:
...
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
...
USART_IT_RXNE:接收中断,串口每收到一个字节就会产生一个此中断。
USART_IT_IDLE:空闲中断,总线上在一个字节的时间内没有再接收到数据的时候发生的。
之后在串口中断处理函数中分别判断处理2种中断就好了,如下:
// 接收数组大小
#define RECEIVE_BUF_SIZE 255
uint8_t g_usart1RxFlag = 0; // 串口1接收标志0-未接受1-接收
uint8_t g_uart1ReceiveBuff[RECEIVE_BUF_SIZE]; // 串口1接收缓冲
uint16_t g_uart1Len = 0; // 串口1接收长度
/**
@brief USART1中断
@param 无
@retval 无
*/
void USART1_IRQHandler(void)
{
// 接收中断的时候收集数据包
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE); //只USART_ReceiveData也可以
g_uart1ReceiveBuff[g_uart1Len] = USART_ReceiveData(USART1);
g_uart1Len++;
}
// 空闲中断的时候说明串口没数据了,收集完成
else if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)
{
USART1->SR;
USART1->DR;
// 标志位,代表有数据,此数据放到main处理去,不要放中断处理。我只打印一下
g_usart1RxFlag = 1;
printf("shoudao1:%s", g_uart1ReceiveBuff);
}
}
最后,main函数,如下
int main(void)
{
...
while (1)
{
// 数据处理
if(g_usart1RxFlag == 1)
{
// 数据处理,这里添加用户自定义处理,处理g_uart1ReceiveBuff后清空
g_usart1RxFlag = 0;
g_uart1Len = 0;
memset(g_uart1ReceiveBuff, 0x00, sizeof(g_uart1ReceiveBuff));
}
vTaskDelay(1); /* 1ms启动读一次 */
}
...
}
二、实例
bsp_usart.h
/**===========================================================================
@file bsp_usart.h
@brief 本文件是用于串口驱动
@author 青梅煮久
@version r0.1
@date 2021/04/26
----------------------------------------------------------------------------
Remark: (备注描述)
串口1的驱动。
串口1:用于日志打印、指令配置
----------------------------------------------------------------------------
History
----------------------------------------------------------------------------
| | |
-------------|-----------|----------------|---------------------------------
2021/04/26 | r0.1 | 青梅煮久 | 创建
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
============================================================================*/
#ifndef __BSP_USART_H
#define __BSP_USART_H
/*********************************************************************
* INCLUDES
*/
#include "stm32f10x.h"
#include
/*********************************************************************
* DEFINITIONS
*/
// 接收数组大小
#define RECEIVE_BUF_SIZE 255
/**
* 串口宏定义,不同的串口挂载的总线和IO不一样,移植时需要修改这几个宏
* 1-修改总线时钟的宏,uart1挂载到apb2总线,其他uart挂载到apb1总线
* 2-修改GPIO的宏
*/
/********************************串口1**********************************/
#define DEBUG_USARTx USART1
#define DEBUG_USART_CLK RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUDRATE 115200
#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT GPIOA
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define DEBUG_USART_IRQ USART1_IRQn
#define DEBUG_USART_IRQHandler USART1_IRQHandler
/*********************************************************************
* GLOBAL VARIABLES
*/
extern uint8_t g_usart1RxFlag; // 串口1接收标志0-未接受1-接收
extern uint8_t g_uart1ReceiveBuff[RECEIVE_BUF_SIZE]; // 串口1接收缓冲
extern uint16_t g_uart1Len; // 串口1接收长度
/*********************************************************************
* API FUNCTIONS
*/
void USART1_Config(void);
#endif /* __BSP_USART_H */
bsp_usart.c
/**===========================================================================
@file bsp_usart.h
@brief 本文件是用于串口驱动
@author 青梅煮久
@version r0.1
@date 2021/04/26
----------------------------------------------------------------------------
Remark: (备注描述)
串口1的驱动。
串口1:用于日志打印、指令配置
----------------------------------------------------------------------------
History
----------------------------------------------------------------------------
| | |
-------------|-----------|----------------|---------------------------------
2021/04/26 | r0.1 | 青梅煮久 | 创建
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
============================================================================*/
/*********************************************************************
* INCLUDES
*/
#include "bsp_usart.h"
#include "stm32f10x.h"
#include "string.h"
static void NVIC_Configuration(void);
/*********************************************************************
* GLOBAL VARIABLES
*/
uint8_t g_usart1RxFlag = 0; // 串口1接收标志0-未接受1-接收
uint8_t g_uart1ReceiveBuff[RECEIVE_BUF_SIZE]; // 串口1接收缓冲
uint16_t g_uart1Len = 0; // 串口1接收长度
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/**
@brief USART1 GPIO 配置,工作参数配置
@param 无
@retval 无
*/
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
/*
* 配置串口
* USART1_TX -> PA9 , USART1_RX -> PA10
*/
// 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
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(DEBUG_USARTx, &USART_InitStructure);
// 串口中断优先级配置
NVIC_Configuration();
// 使能串口中断
USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE);
// 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE);
}
/**
@brief 发送一个字节
@param pUSARTx -[in] 串口
@param ch -[in] 发送数据
@retval 无
*/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 发送一个字节数据到USART */
USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/**
@brief 发送8位的数组
@param pUSARTx -[in] 串口
@param array -[in] 发送数据
@param num -[in] 发送长度
@retval 无
*/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{
uint8_t i;
for(i=0; i
{
/* 发送一个字节数据到USART */
Usart_SendByte(pUSARTx,array);
}
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}
/**
@brief 发送字符串
@param pUSARTx -[in] 串口
@param str -[in] 发送数据
@retval 无
*/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do
{
Usart_SendByte( pUSARTx, *(str + k) );
k++;
} while(*(str + k)!='