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> 

在这里插入图片描述

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

STM32 HAL库中,使用串口中断接收不定长数据可以通过以下步骤实现1. **初始化串口**:配置串口的波特率、数据位、停止位等参数。 2. **使能接收中断**:在初始化完成后,使能串口接收中断。 3. **编写中断处理函数**:在中断处理函数中接收数据处理接收到的数据。 以下是一个示例代码,演示如何使用STM32 HAL实现串口中断接收不定长数据: ```c #include "stm32f1xx_hal.h" UART_HandleTypeDef huart1; uint8_t rxBuffer[100]; uint8_t rxIndex = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); // 使能接收中断 HAL_UART_Receive_IT(&huart1, &rxBuffer[rxIndex], 1); while (1) { // 主循环中可以处理接收到的数据 } } // 串口初始化函数 static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { // 初始化错误处理 while (1); } } // 中断处理函数 void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } // 接收完成回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 继续接收下一个字节 HAL_UART_Receive_IT(&huart1, &rxBuffer[++rxIndex], 1); // 处理接收到的数据 // 例如:检查是否接收到特定字符,结束接收 if (rxBuffer[rxIndex] == '\n') { // 接收完成,处理数据 rxBuffer[rxIndex] = '\0'; // 添加字符串结束符 // 处理数据... rxIndex = 0; // 重置索引 } } } // 系统时钟配置函数 void SystemClock_Config(void) { // 系统时钟配置代码 } // GPIO初始化函数 static void MX_GPIO_Init(void) { // GPIO初始化代码 } ``` 在这个示例中,`HAL_UART_Receive_IT`函数用于启动接收中断,每次接收一个字节。接收完成后,`HAL_UART_RxCpltCallback`回调函数被调用,在其中可以处理接收到的数据继续接收下一个字节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值