你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32l073的四个串口的usart4和usart5如何同时使用?

[复制链接]
ataudio 提问时间:2017-7-14 16:08 /
本帖最后由 ataudio 于 2017-7-14 16:11 编辑

首先,开发板使用的是stm32l073rz-nucleo。stm32l073支持4个usart串口,1个lpsuart。当前项目需要使用4个串口。我选择了usart1、2、4、5.前三个已经能够正常的共同使用。但是usart5在使用过程中,没有任何反应。单步跟踪时,usart5的发送过程能顺利过去,但是串口助手没有任何输出。请教,这是为何呢?

配置代码如下:
stm32l0xx_it.c
void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart1);
}

/* USART2的中断处理函数 */
void USART2_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart2);
}

/* USART4的中断处理函数 */
void USART4_5_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart4);
}

/* USART5的中断处理函数,这个中断处理函数是自己添加的,并且usart5的中断向量也是自行添加到.s文件中的。 */
void USART5_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart5);
}


usart.c
/* USART init function */
void MX_UART_Init(UART_HandleTypeDef* huart)
{
    if (huart == &hlpuart1)
    {
        huart->Instance = LPUART1;        
        huart->Init.BaudRate = 9600;
    }
    else if (huart == &huart1)
    {
        huart->Instance = USART1;        
        huart->Init.BaudRate = 9600;
    }
    else if (huart == &huart2)
    {
        huart->Instance = USART2;        
        huart->Init.BaudRate = 9600;
    }
    else if (huart == &huart4)
    {
        huart->Instance = USART4;        
        huart->Init.BaudRate = 9600;
    }
    else if (huart == &huart5)
    {
        huart->Instance = USART5;        
        huart->Init.BaudRate = 9600;
    }

    huart->Init.WordLength = UART_WORDLENGTH_8B;
    huart->Init.StopBits = UART_STOPBITS_1;
    huart->Init.Parity = UART_PARITY_NONE;
    huart->Init.Mode = UART_MODE_TX_RX;
    huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(huart) != HAL_OK)
    {
        Error_Handler();
    }

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

        GPIO_InitTypeDef GPIO_InitStruct;
        if(uartHandle->Instance==USART1)
        {
                /* Peripheral clock enable */
                __HAL_RCC_USART1_CLK_ENABLE();

                /**USART1 GPIO Configuration   
                PA9     ------> USART2_TX
                PA10    ------> USART2_RX
                */
                GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                GPIO_InitStruct.Pull = GPIO_PULLUP;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
                HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

                /* Peripheral interrupt init */
                HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
                HAL_NVIC_EnableIRQ(USART1_IRQn);               
        }
    else if(uartHandle->Instance==USART2)
        {
                /* Peripheral clock enable */
                __HAL_RCC_USART2_CLK_ENABLE();

                /**USART2 GPIO Configuration   
                PA2     ------> USART2_TX
                PA3     ------> USART2_RX
                */
                GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                GPIO_InitStruct.Pull = GPIO_PULLUP;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
                HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

                /* Peripheral interrupt init */
                HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
                HAL_NVIC_EnableIRQ(USART2_IRQn);               
        }   
    else if(uartHandle->Instance==USART4)
        {
                /* Peripheral clock enable */
                __HAL_RCC_USART4_CLK_ENABLE();

                /**USART4 GPIO Configuration   
                PC10    ------> USART4_TX
                PC11    ------> USART4_RX
                */
                GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                GPIO_InitStruct.Pull = GPIO_PULLUP;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                GPIO_InitStruct.Alternate = GPIO_AF6_USART4;
                HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

                /* Peripheral interrupt init */
                HAL_NVIC_SetPriority(USART4_5_IRQn, 0, 0);
                HAL_NVIC_EnableIRQ(USART4_5_IRQn);                
        }
    else if(uartHandle->Instance==USART5)
        {
                /* Peripheral clock enable */
                __HAL_RCC_USART5_CLK_ENABLE();

                /**USART2 GPIO Configuration
                :RZ LQFP64 Pin55/56  
                PB3     ------> USART5_TX
                PB4     ------> USART5_RX
                :VZ LQFP100 Pin41/42  
                PE10     ------> USART5_TX
                PE11     ------> USART5_RX
                */
                GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                GPIO_InitStruct.Pull = GPIO_PULLUP;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                GPIO_InitStruct.Alternate = GPIO_AF6_USART5;
                HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

                /* Peripheral interrupt init */
                HAL_NVIC_SetPriority(USART4_5_IRQn, 0, 0);
                HAL_NVIC_EnableIRQ(USART4_5_IRQn);                
        }   
}



main.c
...
        MX_UART_Init(&huart1);
    MX_UART_Init(&huart2);

    #ifdef DEF_USART4
    MX_UART_Init(&huart4);
    #endif
    #ifdef DEF_USART5
     MX_UART_Init(&huart5);
    #endif

...
     while (1)
        {
          // 虚拟串口用的usart2,重定向
            printf("\nloop!\n");

        /* Insert 5 seconds delay */
        BSP_LED_On(LED2);
                HAL_Delay(1000);

       /* usart1中断发送 */
        if(HAL_UART_Transmit_IT(&huart1, (uint8_t*)gcTx1Buffer, TX1BUFFERSIZE)!= HAL_OK)
        {
            Error_Handler();
        }
        while (Uart1Ready != SET)
        {
        }
        Uart1Ready = RESET;        
        HAL_Delay(500);

        /* Checks if Buffer full indication has been set */


        BSP_LED_On(LED2);
        HAL_Delay(1000);

        #ifdef DEF_USART4
        if(HAL_UART_Transmit(&huart4, (uint8_t*)gcTx4Buffer, TX4BUFFERSIZE, 1000)!= HAL_OK)
        {
            Error_Handler();
        }
        HAL_Delay(500);
        #endif

        #ifdef DEF_USART5
        if(HAL_UART_Transmit(&huart5, (uint8_t*)gcTx5Buffer, TX5BUFFERSIZE, 1000)!= HAL_OK)
        {
            Error_Handler();
        }
        HAL_Delay(1000);
        #endif
        printf("\nOff!\n");               

        
                //BSP_LED_Init(LED2);
                //HAL_Delay(2000);

          //printf("\nWake up.\n");
            HAL_Delay(1000);
           //DisplayClkInfo();
        }

....


通过查看startup_stm32l073xx.s,

在原本保留字的位置上,增加了DCD  USART5_IRQHandler,以及后文增加了:EXPORT  USART5_IRQHandler              [WEAK]

但是程序运行过程中,usart5应该输出的内容,从pb3、pb4连接到电脑后,串口助手没有响应。
通过关闭usart4,也没有变化。

现在我关注到usart4、5在定义中断IRQn时,定义为共用的USART4_5_IRQn(第27号)。因此,USART4的中断处理用了USART4_5_IRQn作为设置参数。而USART5_IRQHanfler也用了USART4_5_IRQn。
这里有没有矛盾?
为何不见usart5的输出,怎么解决?

谢谢指正。

333.PNG
收藏 评论7 发布时间:2017-7-14 16:08

举报

7个回答
ataudio 回答时间:2017-7-14 17:23:45
通过示波器抓取信号,usart5是有输出信号的。信号的长度和输出信息一样。但是内容好像不一致。
我设置了gcTxbuf[4]={0xA5,0xAA,0x55,0x85};

根据示波器读的数据是,负电平:1010 1101 0011 0101 0100 1010 1010 1000,即AD 35 4A A8.
原因还不明。
zhao.zhao 回答时间:2017-7-14 17:45:25
自行添加中断函数到启动文件中,恐怕不行吧?
zhao.zhao 回答时间:2017-7-14 17:48:02
看样子是串口4 5共用一个中断向量,应该在串口4 5的中断函数中识别出来,分别处理
ataudio 回答时间:2017-7-14 17:54:53
zhao.zhao 发表于 2017-7-14 17:48
看样子是串口4 5共用一个中断向量,应该在串口4 5的中断函数中识别出来,分别处理 ...

如果不另外定义中断函数。4和5进同一个中断,根据什么,如何区分huart呢?

void USART4_5_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart??);
}
zhao.zhao 回答时间:2017-7-14 20:24:12
用的是同一个中断向量,你如果定义2个中断函数,也就是2个中断入口地址,肯定是错的;
通过分别判断2个串口的标志位来判断到底是谁触发的中断;
这个我没试过,你可以尝试一下下面写法
void USART4_5_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart4);
    HAL_UART_IRQHandler(&huart5);
}
zhao.zhao 回答时间:2017-7-14 20:44:36
增加的这一句“DCD  USART5_IRQHandler”其实没有用的 , 这个启动文件中 指明了复位和各个中断的入口地址,和芯片的架构有关,芯片确定后,各个中断的入口地址也就确定了,和你文字的改动增加已经没有任何关系了,这些文字只是给写程序的人一些文字的提示,标识出了什么中断就执行什么地方的指令的文字含义。所以USART4 USART5,中断后只会执行 “跳转到 USART4_5_IRQHandler 处的指令”。你自己增加的指令只是你的一厢情愿,机器是不会理睬的。
zhao.zhao 回答时间:2017-7-14 20:49:34
串口4和5的发送应该不会有问题, 因为没有用到中断。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版