嵌入式技术论坛
直播中

YYXIAO

8年用户 1120经验值
擅长:接口/总线/驱动
私信 关注
[问答]

如何查看UART2使用的引脚呢?

我在rtconfig.h文件中添加了BSP_USING_UART2宏定义后,如何查看UART2使用的引脚呢?我查看了stm32f1xx_hal_uart.c文件中的HAL_UART_MspInit函数,里面是空的,不知道默认是使用的哪两个引脚,烦请各路大牛指教。

回帖(9)

王桂兰

2022-12-29 15:12:43
不知道你用的是不是 studio 开发环境,如果是的话,参考 drivers/board.h 中的提示内容

/** After configuring corresponding UART or UART DMA, you can use it.
*
* STEP 1, define macro define related to the serial port opening based on the serial port number
*                 such as     #define BSP_USING_UART1
*
* STEP 2, according to the corresponding pin of serial port, define the related serial port information macro
*                 such as     #define BSP_UART1_TX_PIN       "PA9"
*                             #define BSP_UART1_RX_PIN       "PA10"
*
* STEP 3, if you want using SERIAL DMA, you must open it in the RT-Thread Settings.
*                 RT-Thread Setting -> Components -> Device Drivers -> Serial Device Drivers -> Enable Serial DMA Mode
*
* STEP 4, according to serial port number to define serial port tx/rx DMA function in the board.h file
*                 such as     #define BSP_UART1_RX_USING_DMA
*
*/
应该是在 board.h 中添加要使用的串口,并且指定串口用到的引脚号,如下所示

/* 串口1 */
#define BSP_USING_UART1
#define BSP_UART1_TX_PIN       "PA9"
#define BSP_UART1_RX_PIN       "PA10"
/* 串口2 */
#define BSP_USING_UART2
#define BSP_UART2_TX_PIN       "PA2"
#define BSP_UART2_RX_PIN       "PA3"
另外附上串口初始化的函数调用流程

rt_device_find(device.c)    // 查找注册串口设备
rt_device_open(device.c)    // 打开串口设备
    |-> device_init(device.c)  // 串口设备初始化
        |-> serial->ops->configure(serial.c)
            |-> stm32_configure(drv_usart.c)
                |-> stm32_gpio_configure(drv_usart.c)  // 串口引脚和时钟初始化
                |-> HAL_UART_Init(stm32f4xx_hal_uart.c)
                    |-> HAL_UART_MspInit(stm32f4xx_hal_msp.c) // CubeMX配置的话此部分有效,可以不用配置因为在 stm32_gpio_configure 已经对引脚初始化过了
    |-> device_open(device.c)    // 打开串口设备
        |-> rt_serial_open(serial.c)
            |-> serial->ops->control(serial.c)
                |-> stm32_control(drv_usart.c)
                    |-> stm32_dma_config(drv_usart.c)   // DMA配置
举报

YYXIAO

2022-12-29 15:13:09
感谢老哥的回答,我是用的studio环境生成的工程,我是在rtconfig.h里面增加了串口的宏定义,如下图:
2.jpg
使用list_device可以看到该设备已经注册成功了,如下:
3.jpg
但是我想知道uart2和uart3用的是那两个收发引脚,并且,我全局搜索BSP_UART1_TX_PIN宏定义时,未找到任何地方引用。
举报

王桂兰

2022-12-29 15:13:23
正常来说是在 board.h 中进行引脚的配置的,可以参考官方文档 RT-Thread 完整版串口的驱动开发。不知道你是不是基于芯片创建的工程,因为 rtconfig.h 是用 env 或者 RT-Thread Settings 工具配置生成的,如果自己手动在里面添加内容,重新配置后手动添加的内容就被更新掉消失了。

如果是基于开发板创建的工程和基于芯片创建的不一样,基于开发板创建的工程上面的串口的引脚都已经配置好了,就不用自己修改了,学习的话还是建议使用基于芯片创建的工程来操作,这样更灵活。基于开发板创建的工程可以作为外设使用的参考demo。
基于开发板创建的工程引脚定义在 CubeMX 软件中进行配置,可以在文件 board/CubeMX_Config/Src/stm32f4xx_hal_msp.c 中函数 HAL_UART_MspInit 里面查看,如下所示

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspInit 0 */
  /* USER CODE END USART1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration   
    PA9     ------> USART1_TX
    PA10     ------> USART1_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_AF7_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */
  /* USER CODE END USART1_MspInit 1 */
  }
  else if(huart->Instance==USART3)
  {
  /* USER CODE BEGIN USART3_MspInit 0 */
  /* USER CODE END USART3_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART3_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**USART3 GPIO Configuration   
    PB10     ------> USART3_TX
    PB11     ------> USART3_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_AF7_USART3;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  /* USER CODE BEGIN USART3_MspInit 1 */
  /* USER CODE END USART3_MspInit 1 */
  }
}
举报

王桂兰

2022-12-29 15:13:34
引脚的使用是在文件 drivers/include/config/uart_config.h 中的,例如说里面的一段,这里面就是用了串口2的收发引脚,别的串口也在这个文件里面。

#if defined(BSP_USING_UART2)
#ifndef UART2_CONFIG
#define UART2_CONFIG                                                
    {                                                               
        .name = "uart2",                                            
        .Instance = USART2,                                         
        .irq_type = USART2_IRQn,                                    
        .tx_pin_name = BSP_UART2_TX_PIN,                           
        .rx_pin_name = BSP_UART2_RX_PIN,                           
    }
#endif /* UART2_CONFIG */
在文件 drivers/drv_usart.c 中将使用到的串口都定义在结构体数组 uart_config 里面,如下所示。

static struct stm32_uart_config uart_config[] =
{
#ifdef BSP_USING_UART1
    UART1_CONFIG,
#endif
#ifdef BSP_USING_UART2
    UART2_CONFIG,
#endif
#ifdef BSP_USING_UART3
    UART3_CONFIG,
#endif
    ... ... // 省略
};
然后在函数 rt_hw_usart_init() 中会把所有定义的串口设备都注册到系统中,使用的就是结构体数组 uart_config 中定义的串口设备进行注册的。

int rt_hw_usart_init(void)
{
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
    rt_err_t result = 0;
    stm32_uart_get_dma_config();
    for (int i = 0; i < obj_num; i++)
    {
        uart_obj[i].config = &uart_config[i];
        uart_obj[i].serial.ops    = &stm32_uart_ops;
        uart_obj[i].serial.config = config;
        /* register UART device */
        result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
                                       RT_DEVICE_FLAG_RDWR
                                       | RT_DEVICE_FLAG_INT_RX
                                       | RT_DEVICE_FLAG_INT_TX
                                       | uart_obj[i].uart_dma_flag
                                       , NULL);
        RT_ASSERT(result == RT_EOK);
    }
    return result;
}
举报

YYXIAO

2022-12-29 15:13:44
非常感谢老哥的详细回答,您说的这些文件我其实都找过了,rtthread是用的4.0.3版本的,我是基于开发板创建的工程,这样确实,即使我的rtconfig.h文件中添加了BSP_USING_UART2定义,也不会生成UART2的初始化代码,那如果我在cubemx软件中修改了引脚配置,stm32f1xx_hal_msp.c文件会重新生成相应外设引脚初始化的代码吗?
举报

YYXIAO

2022-12-29 15:13:50
再请教老哥一个问题,就是我在cubemx里面新增了串口外设,如何更新rttstudio工程里面的stm32f1xx_hal_msp.c文件呢,可以自动生成吗?
举报

王桂兰

2022-12-29 15:13:59
我个人建议,在学习或者开发的过程中使用基于芯片创建的工程,因为这样更通用一点,基于芯片创建的工程修改 CubeMX 软件的引脚配置后,stm32f1xx_hal_msp.c 文件就会生成你配置的引脚的相关代码。

基于开发板创建的工程引脚功能都给你配置好了,在 env 工具里面选中就能使用了,但是基于开发板创建的不够灵活和通用。
举报

王桂兰

2022-12-29 15:14:06
在 cubeMX 里面配置是会生成的,但是你修改配置的话可能就会导致基于开发板创建的工程编译错误,基于开发板创建的工程应该是在 env 里面使能选中使能相应的功能就能使用了。
举报

YYXIAO

2022-12-29 15:15:10
我现在换成了基于芯片创建工程,board.h文件里面的内容就比较熟悉了,嘿嘿,感谢老哥的指点
举报

更多回帖

发帖
×
20
完善资料,
赚取积分