STM32H743xx串口1中断接收不定长数据并转发用HAL实现
编译器平台及例程说明
编译器平台说明
1. Toolchain : MDK-ARM Community Version: 5.30.0.0(Kile V5)
2. Encoding : Encode in UTF-8 without signature
3. Device Specific Packs : Keil.STM32H7xx_DFP.2.7.0.pack
4. Preprocessor Symbols Define : USE_HAL_DRIVER, STM32H743xx
USE_HAL_DRIVER : 允许使用HAL库驱动
STM32H743xx : STM32H743xx芯片
5. Chip Type : STM32H743VIT6, Flash:2MByte, ROM:1MByte
6. 在stm32h7xx_hal_conf.h文件中HSE_VALUE为外部高速振荡器,默认25MHZ。此值必须与硬件保持一致。
例程说明
1. STM32H743xx串口1中断接收不定长数据并将接收到的数据转发到上位机显示用HAL实现
一、宏定义说明
// PA9 -- MCU_USART1_TXD -- 串口1发送
// PA10 -- MCU_USART1_RXD -- 串口1接收
#define USART1_TXD_Pin GPIO_PIN_9
#define USART1_RXD_Pin GPIO_PIN_10
#define USART1_GPIO GPIOA
/* 串口1接收缓存大小 */
#define UART1_RXD_BUF_SIZE 480
二、变量的定义
UART_HandleTypeDef USART1_HandlerType = {0};
//RxState[0..13] : 接收到的数据长度
//RxState[14] : (1)已接收到0x0D (0)未接收到0x0D
//RxState[15] : (1)已接收完成 (0)接收未完成
u16 RxState = 0; //串口1接收状态
static u8 RxBufIRQ[1] = {0}; //串口1中断接收缓存
u8 __attribute__ ((aligned(4))) UART1_RXD_BUF[UART1_RXD_BUF_SIZE] = {0}; //串口1接收缓存
三、串口初始化
/**********************************************************************************************************************************************
* 函数名 : vInit_USART_GPIO
* 描 述 : USART GPIO初始化
* 说 明 : 1. USRTA1 : PA9 PA10配置复用推完 上拉 高速
**********************************************************************************************************************************************/
static void vInit_USART_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //Enable GPIOA clock
GPIO_InitStructure.Pin = USART1_TXD_Pin | USART1_RXD_Pin; //GPIO pin
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; //GPIO mode,Alternate Function Push Pull
GPIO_InitStructure.Pull = GPIO_PULLUP; //GPIO pull-up
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; //GPIO speed,Fast speed
GPIO_InitStructure.Alternate = GPIO_AF7_USART1; //Alternate connected peripheral
HAL_GPIO_Init(USART1_GPIO, &GPIO_InitStructure); //GPIO init
}
/**********************************************************************************************************************************************
* 函数名 : vUSART_MspInit
* 说 明 : 1. 在HAL_UART_Init()-->HAL_UART_MspInit()中调用
**********************************************************************************************************************************************/
static void vUSART_MspInit(void)
{
vInit_USART_GPIO();
__HAL_RCC_USART1_CLK_ENABLE(); //Enable USART1 clock
HAL_NVIC_SetPriority(USART1_IRQn, 2, 0); //Set USART1 interrupt priority
HAL_NVIC_EnableIRQ(USART1_IRQn); //Enable USART1 interrupt channel
}
/**********************************************************************************************************************************************
* 函数名 : HAL_UART_MspInit
* 说 明 : 1.在串口初始化HAL_UART_Init()中会调用HAL_UART_MspInit()
**********************************************************************************************************************************************/
void HAL_UART_MspInit(UART_HandleTypeDef * huart)
{
if(huart->Instance == USART1)
{
vUSART_MspInit();
}
}
/**********************************************************************************************************************************************
* 函数名 : vInit_USART
* 描 述 : 初始化串口1
**********************************************************************************************************************************************/
void vInit_USART1(u32 baudRate)
{
u8 res = 0;
USART1_HandlerType.Instance = USART1; //Peripheral object
USART1_HandlerType.Init.BaudRate = baudRate; //Baud rate
USART1_HandlerType.Init.WordLength = UART_WORDLENGTH_8B; //Data bit
USART1_HandlerType.Init.StopBits = UART_STOPBITS_1; //Stop bit
USART1_HandlerType.Init.Parity = UART_PARITY_NONE; //Parity bit
USART1_HandlerType.Init.HwFlowCtl = UART_HWCONTROL_NONE; //Hardware flow control
USART1_HandlerType.Init.Mode = UART_MODE_TX_RX; //Operating mode
res = HAL_UART_Init(&USART1_HandlerType); //Init USART1
if(res != HAL_OK)
{
dprintf("UART1 Init Fail...\r\n");
}
/* 只有RxBufIRQ满数据才会触发接收完成中断 */
res = HAL_UART_Receive_IT(&USART1_HandlerType, (u8 *)RxBufIRQ, sizeof(RxBufIRQ));//Enable rececive interrupt
if(res != HAL_OK)
{
dprintf("Enable UART1 receive interrupt Fail...\r\n");
}
dprintf("7-STM32H743xx_CubeMx_USART......\r\n");
}
四、串口中断通用处理
/**********************************************************************************************************************************************
* 函数名 : USART1_IRQHandler
* 描 述 : 串口1中断服务
* 说 明 : 1. HAL_UART_IRQHandler()处理结束后需要重新开启接收中断HAL_UART_Receive_IT()
**********************************************************************************************************************************************/
void USART1_IRQHandler(void)
{
u16 timeOut = 0;
u32 res = 0;
/* HAL库串口中断通用处理 */
HAL_UART_IRQHandler(&USART1_HandlerType);
do
{
res = HAL_UART_GetState(&USART1_HandlerType);
timeOut++;
} while ((res != HAL_UART_STATE_READY) && (timeOut < 20000));
timeOut = 0;
do
{
res = HAL_UART_Receive_IT(&USART1_HandlerType, (u8 *)RxBufIRQ, sizeof(RxBufIRQ));
timeOut++;
} while ((res != HAL_OK) && (timeOut < 20000));
}
五、串口接收完成中断处理
/**********************************************************************************************************************************************
* 函数名 : HAL_UART_RxCpltCallback
* 描 述 : 串口接收完成回调函数
* 说 明 : 1. RxBufIRQ[0]不能用huart->pRxBuffPtr[0]代替
* 2. 串口接收完成中断是指RxBufIRQ接收满,才触发此接收完成中断
**********************************************************************************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart)
{
if(huart->Instance == USART1)
{
if(!(RxState & 0x8000))//Rececive unfinished
{
if(RxState & 0x4000)//Rececived 0x0D
{
if(RxBufIRQ[0] != 0x0A)//Rececived 0x0A
{
RxState = 0;//Rececived error, Restart
}
else
{
RxState |= 0x8000;//Rececive finished
}
}
else//Unrececive 0x0D
{
if(RxBufIRQ[0] == 0x0D)
{
RxState |= 0x4000;//Rececived 0x0D
}
}
UART1_RXD_BUF[RxState & 0x3FFF] = RxBufIRQ[0];
if(((++RxState) & 0x3FFF) > (UART1_RXD_BUF_SIZE - 1))//Data too long
{
RxState = 0;//Restart
}
}
}
}
六、测试例程
int main(void)
{
static u8 i = 0;
vStartUp_System();
vInit_System_BSP();
vShow_PlatformDevice_Info();
vInit_USART1(115200);
while (1)
{
/* 串口接收完成的处理 数据转发到上位机 */
if(RxState & 0x8000)
{
/* 发送数据到上位机 */
HAL_UART_Transmit(&USART1_HandlerType, UART1_RXD_BUF, (RxState & 0x3FFF), 200);
/* 等待发送完成 */
while(__HAL_UART_GET_FLAG(&USART1_HandlerType, UART_FLAG_TC) != SET);
/* 清空接收状态 */
RxState = 0;
}
HAL_Delay(10);
if((++i) > 50)
{
i = 0;
USER_LED_CPL();
}
}
}
七、运行效果
00> Segger Rtt Init Ok...
00> STM32H743VIT6 Start Running...
00> 7-STM32H743xx_CubeMx_USART......
00> Debug Versions......
00> Compile Date : Apr 1 2022 21:31:46
00>