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> 

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
针对STM32G4HAL串口空闲中断接收不定数据的问题,可以按照以下步骤进行解决: 1. 开启串口空闲中断,即在初始化串口时,将USART_CR1_REG中的USART_CR1_IDLEIE位设置为1。 2. 在串口空闲中断中,通过读取USART_ISR_REG寄存器中的位USART_ISR_RXNE和USART_ISR_IDLE来判断是接收数据还是空闲中断。 3. 如果是接收数据,则读取USART_RDR_REG寄存器中的数据,并将其存储到缓冲区中。 4. 如果是空闲中断,则通过计算接收到的数据度来确定数据度,并将其存储到缓冲区中。 5. 在数据度达到预定度时,可以通过回调函数或者其他方式来通知数据接收已经完成。 下面是一个示例代码: ```c uint8_t rx_buffer[100]; uint8_t rx_counter = 0; uint8_t rx_length = 0; uint8_t rx_flag = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USARTx) { if(rx_flag == 0) { //接收数据 if((__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) == RESET)) { rx_buffer[rx_counter++] = (uint8_t)(huart->Instance->RDR & 0x00FF); } //空闲中断 else if(__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET) { rx_length = rx_counter; rx_counter = 0; rx_flag = 1; } } } } ``` 在上面的代码中,当接收数据时,将数据存储到缓冲区中,并将计数器rx_counter加1。当空闲中断发生时,计算接收到的数据度,并将其存储到rx_length中。在接收完成后,将rx_flag设置为1,表示数据接收已经完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值