STM32L0 drv_usart.c的BUG及解决【已解决】

发布于 2020-08-18 17:25:28

操作过程

  1. 使用RT-studio基于芯片 STM32L071RB 建立工程
  2. 选择 lpuart1 作为输出口, TXD=pc1 RXD=pc0
  3. 编译,没有错,下载,没有输出。

据官方文档介绍,使用完整版的rtt是不用修改就可以使用uart等资源的。

先说两个问题:

1、不支持 TXD=pc1 RXD=pc0
2、串口号 uart_num 的提取算法存在bug,没考虑到 lpuart 串口号提取

对drv_usart.c如下做修改:

1.添加数据

在数组 uart_afs[] 中添加TXD=pc1 RXD=pc0的数据【注意TX在前,与后头算法有关】

{ .pin_index = GET_PIN(C,  1), .afs[0] = {.uart_num = UART_IS_TX|1, .af_num = 6}},
{ .pin_index = GET_PIN(C,  0), .afs[0] = {.uart_num = UART_IS_RX|1, .af_num = 6}},

2.修改串口号提取算法

去除原始算法 uart_num = config->name[4] - '0';
使用以下代码替代,【完整函数请转到1楼】

   uart_num = config->name[rt_strlen(config->name)-1] - '0';

   if(config->name[0]=='u')
   {
       uart_num = config->name[4] - '0';
   }
   else 
   {
       uart_num = config->name[6] - '0';
   }

对数组数据进行一下说明:

一、为什么是TX在前面呢?
因为后面的for循环里面 index = index + 2 的方式去找tx引脚
二、.uart_num是什么?
其实我也不知道,猜的,肯定是串口几呗,我们的是 lpuart1,那就是1咯
三、.af_num = 6 是为什么呢?
使用cubemx生成代码,看初始化代码,宏定义 GPIO_AF6_LPUART1 ,不用转到定义了,AFn就n啦
四、串口号提取
原始代码用了config->name[4],对于uartx的串口是有效的,但是对于lp打头的就不对了。解决的方法就是把那个数字找出来,方法很多,直接转成数字,取最后一个字节,是不是又发现了就两种串口呀,不是4就是6呀,判断一下也可以。

查看更多

关注者
0
被浏览
204
1 个回答
wlof
wlof 2020-08-18

在stm32L071RB上测试通过,其他的板子没有测试

修改后的函数:

static rt_err_t stm32_gpio_configure(struct stm32_uart_config *config)
{
#define UART_IS_TX        (1U<<7)
#define UART_IS_RX        (0U)

    rt_uint16_t tx_pin_num = 0;
    int index = 0, tx_af_num = 0, rx_af_num = 0;
    uint8_t uart_num = 0;
    GPIO_TypeDef *tx_port;
    GPIO_TypeDef *rx_port;
    uint16_t tx_pin;
    uint16_t rx_pin;
    get_pin_by_name(config->rx_pin_name, &rx_port, &rx_pin);
    get_pin_by_name(config->tx_pin_name, &tx_port, &tx_pin);
    
   struct gpio_uart_af {
       /* index get by GET_PIN */
       uint16_t pin_index;
       struct {
           /* when is TX the bit7 is 1, bit6-bit0 is uart number (1-8)  */
           uint8_t uart_num;
           uint8_t af_num;
       } afs[1];
   };

   static const struct gpio_uart_af uart_afs[] =
   {
      { .pin_index = GET_PIN(A,  0), .afs[0] = {.uart_num = UART_IS_TX|4, .af_num = 6}},
      { .pin_index = GET_PIN(A,  1), .afs[0] = {.uart_num = UART_IS_RX|4, .af_num = 6}},
      { .pin_index = GET_PIN(A,  2), .afs[0] = {.uart_num = UART_IS_TX|2, .af_num = 4}},
      { .pin_index = GET_PIN(A,  3), .afs[0] = {.uart_num = UART_IS_RX|2, .af_num = 4}},
      { .pin_index = GET_PIN(A,  9), .afs[0] = {.uart_num = UART_IS_TX|1, .af_num = 4}},
      { .pin_index = GET_PIN(A, 10), .afs[0] = {.uart_num = UART_IS_RX|1, .af_num = 4}},
      { .pin_index = GET_PIN(A, 14), .afs[0] = {.uart_num = UART_IS_TX|2, .af_num = 4}},
      { .pin_index = GET_PIN(A, 15), .afs[0] = {.uart_num = UART_IS_RX|2, .af_num = 4}},
      { .pin_index = GET_PIN(B,  3), .afs[0] = {.uart_num = UART_IS_TX|5, .af_num = 6}},
      { .pin_index = GET_PIN(B,  4), .afs[0] = {.uart_num = UART_IS_RX|5, .af_num = 6}},
      { .pin_index = GET_PIN(B,  6), .afs[0] = {.uart_num = UART_IS_TX|1, .af_num = 0}},
      { .pin_index = GET_PIN(B,  7), .afs[0] = {.uart_num = UART_IS_RX|1, .af_num = 0}},
      { .pin_index = GET_PIN(C,  1), .afs[0] = {.uart_num = UART_IS_TX|1, .af_num = 6}},
      { .pin_index = GET_PIN(C,  0), .afs[0] = {.uart_num = UART_IS_RX|1, .af_num = 6}},
      { .pin_index = GET_PIN(C, 10), .afs[0] = {.uart_num = UART_IS_TX|4, .af_num = 6}},
      { .pin_index = GET_PIN(C, 11), .afs[0] = {.uart_num = UART_IS_RX|4, .af_num = 6}},
      { .pin_index = GET_PIN(C, 12), .afs[0] = {.uart_num = UART_IS_TX|5, .af_num = 2}},

#ifdef GPIOD
      { .pin_index = GET_PIN(D,  2), .afs[0] = {.uart_num = UART_IS_RX|5, .af_num = 6}},
      { .pin_index = GET_PIN(D,  5), .afs[0] = {.uart_num = UART_IS_TX|2, .af_num = 0}},
      { .pin_index = GET_PIN(D,  6), .afs[0] = {.uart_num = UART_IS_RX|2, .af_num = 0}},
#endif
      
#ifdef GPIOE
          { .pin_index = GET_PIN(E,  8), .afs[0] = {.uart_num = UART_IS_TX|4, .af_num = 6}},
          { .pin_index = GET_PIN(E,  9), .afs[0] = {.uart_num = UART_IS_RX|4, .af_num = 6}},
          { .pin_index = GET_PIN(E, 10), .afs[0] = {.uart_num = UART_IS_TX|5, .af_num = 6}},
          { .pin_index = GET_PIN(E, 11), .afs[0] = {.uart_num = UART_IS_RX|5, .af_num = 6}},
#endif
   };

   /* get tx/rx pin index */
   uart_num = config->name[rt_strlen(config->name)-1] - '0';

   tx_pin_num = stm32_get_pin(tx_port, tx_pin);

   for (index = 0; index < sizeof(uart_afs) / sizeof(struct gpio_uart_af); index = index + 2)
   {
       if (uart_afs[index].pin_index == tx_pin_num)
       {
           if(uart_afs[index].afs[0].uart_num == (uart_num|UART_IS_TX))
           {
               tx_af_num = uart_afs[index].afs[0].af_num;
               rx_af_num = uart_afs[index + 1].afs[0].af_num;
           }
       }
   }

   /* gpio Init */
   GPIO_InitTypeDef GPIO_InitStruct = {0};

   /* gpio ports clock enable */
   stm32_gpio_clk_enable(tx_port);
   if (tx_port != rx_port)
   {
       stm32_gpio_clk_enable(rx_port);
   }

    /* rx pin initialize */
    GPIO_InitStruct.Pin = tx_pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
#if defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7)
    GPIO_InitStruct.Alternate = tx_af_num;
#endif
    HAL_GPIO_Init(tx_port, &GPIO_InitStruct);

    /* rx pin initialize */
    GPIO_InitStruct.Pin = rx_pin;
#if defined(SOC_SERIES_STM32L0) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0) || defined(SOC_SERIES_STM32H7)
    GPIO_InitStruct.Alternate = rx_af_num;
#endif
    HAL_GPIO_Init(rx_port, &GPIO_InitStruct);

    return RT_EOK;
}

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览