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

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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版