OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6954|回复: 15

UART9串口,发送波特率是接收的一半,才能通信。比如单片机波特率设为9600,串口助手19200才能正常通信,否则乱码

[复制链接]

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
发表于 2021-9-9 15:27:32 | 显示全部楼层 |阅读模式
1金钱
使用HAL库函数,我遇到问题是其他串口正常,只有UART9串口,发送波特率是接收的一半,才能通信。比如单片机波特率设为9600,串口助手19200才能正常通信,否则乱码。同一个原子例程模板改的,串口1,2,6,7,8都是正常相同的波特率

最佳答案

查看完整内容[请看2#楼]

找到原因了,HAL库函数中没有考虑UART9和UART10这两种串口的情形,只把USART1和USART6按照所在的APB2时钟设置波特率了,UART9和UART10也在APB2时钟下面。但是没考虑UART9和UART10,程序中除了USART1和USART6,其他串口都按照最后的else情况 ,按照APB1时钟设置了,时钟差别2倍关系,BRR按照APB1设置,实际UART9,UART10时钟确是APB2,所以波特率也是2倍关系。详情查看UART_SetConfig(UART_HandleTypeDef *huart) iif(huart->Init.O ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
 楼主| 发表于 2021-9-9 15:27:33 | 显示全部楼层
本帖最后由 yuanzinpl 于 2021-9-11 17:01 编辑

找到原因了,HAL库函数中没有考虑UART9和UART10这两种串口的情形,只把USART1和USART6按照所在的APB2时钟设置波特率了,UART9和UART10也在APB2时钟下面。但是没考虑UART9和UART10,程序中除了USART1和USART6,其他串口都按照最后的else情况 ,按照APB1时钟设置了,时钟差别2倍关系,BRR按照APB1设置,实际UART9,UART10时钟确是APB2,所以波特率也是2倍关系。详情查看UART_SetConfig(UART_HandleTypeDef *huart)
iif(huart->Init.OverSampling == UART_OVERSAMPLING_8)  {
    /*-------------------------- USART BRR Configuration ---------------------*/
#if defined(USART6)
    if((huart->Instance == USART1) || (huart->Instance == USART6))
    {
      huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
    }
#else
    if(huart->Instance == USART1)
    {
      huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
    }        
#endif /* USART6 */
    else
    {
      huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
    }
  }
  else
  {
    /*-------------------------- USART BRR Configuration ---------------------*/
#if defined(USART6)
    if((huart->Instance == USART1) || (huart->Instance == USART6))
    {
      huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
    }
#else
    if(huart->Instance == USART1)
    {
      huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate);
    }        
#endif /* USART6 */
    else
    {
      huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate);
    }
  }

USART1    APB2

USART2    APB1

USART3    APB1

UART4      APB1

UART5      APB1

USART6   APB2

UART7      APB1

UART8      APB1

UART9      APB2

UART10     APB2



根据串口初始化函数推测,HAL库函数确是没有专门针对UAR9,UART10进行设置
大部分参数This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or   *         UART peripheral.


后来发现STM32CUBE生成的UART9代码工程中对应的HAL库函数就增加了UART9,UART10这两种串口如下
static void UART_SetConfig(UART_HandleTypeDef *huart)
{
   uint32_t tmpreg;
   uint32_t pclk;
   /* Check the parameters */
   assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
   assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
   assert_param(IS_UART_PARITY(huart->Init.Parity));
   assert_param(IS_UART_MODE(huart->Init.Mode));
   /*-------------------------- USART CR2 Configuration -----------------------*/
   /* Configure the UART Stop Bits: Set STOP[13:12] bits
      according to huart->Init.StopBits value */
   MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
   /*-------------------------- USART CR1 Configuration -----------------------*/
   /* Configure the UART Word Length, Parity and mode:
      Set the M bits according to huart->Init.WordLength value
      Set PCE and PS bits according to huart->Init.Parity value
      Set TE and RE bits according to huart->Init.Mode value
      Set OVER8 bit according to huart->Init.OverSampling value */
   tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling;
   MODIFY_REG(huart->Instance->CR1,
              (uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
              tmpreg);
   /*-------------------------- USART CR3 Configuration -----------------------*/
   /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
   MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);

#if defined(USART6) && defined(UART9) && defined(UART10)
     if ((huart->Instance == USART1) || (huart->Instance == USART6) || (huart->Instance == UART9) || (huart->Instance == UART10))
     {
       pclk = HAL_RCC_GetPCLK2Freq();

     }
#elif defined(USART6)
     if ((huart->Instance == USART1) || (huart->Instance == USART6))
     {
       pclk = HAL_RCC_GetPCLK2Freq();
     }
#else
     if (huart->Instance == USART1)
     {
       pclk = HAL_RCC_GetPCLK2Freq();
     }
#endif /* USART6 */
     else
     {
       pclk = HAL_RCC_GetPCLK1Freq();
     }
   /*-------------------------- USART BRR Configuration ---------------------*/
   if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
   {
     huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
   }
   else
   {
     huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
   }

}






回复

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-9-9 16:37:13 | 显示全部楼层
感觉是你时钟的问题
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
 楼主| 发表于 2021-9-9 16:40:37 | 显示全部楼层
补充下UART9的寄存器设置是正确的,本想截图,但是却不能添加图片。寄存器设置和UART8波特率9600时候的寄存器设置对比了  是相同的
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
 楼主| 发表于 2021-9-9 16:41:20 | 显示全部楼层
lpwithv 发表于 2021-9-9 16:37
感觉是你时钟的问题

系统时钟都是和其他例程相同的
回复

使用道具 举报

70

主题

6758

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12991
金钱
12991
注册时间
2012-11-26
在线时间
3789 小时
发表于 2021-9-10 08:54:28 | 显示全部楼层
直接用cubemx生成一个串口9的初始化代码试试,我也感觉是你时钟问题
学无止境
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2021-9-10 09:04:53 | 显示全部楼层
/*---------------------------- USART BRR Configuration -----------------------*/
  /* Configure the USART Baud Rate */
  RCC_GetClocksFreq(&RCC_ClocksStatus);

  if ((USARTx == USART1) || (USARTx == USART6))
  {
    apbclock = RCC_ClocksStatus.PCLK2_Frequency;
  }
  else
  {
    apbclock = RCC_ClocksStatus.PCLK1_Frequency;
  }
  
  /* Determine the integer part */
  if ((USARTx->CR1 & USART_CR1_OVER8) != 0)
  {
    /* Integer part computing in case Oversampling mode is 8 Samples */
    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));   
  }
  else /* if ((USARTx->CR1 & USART_CR1_OVER8) == 0) */
  {
    /* Integer part computing in case Oversampling mode is 16 Samples */
    integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));   
  }
  tmpreg = (integerdivider / 100) << 4;


你看看这一段
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3345
金钱
3345
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-10 09:28:41 | 显示全部楼层
去RCC里面看看,PCLK时钟有时候如果前面分频系数不是1,后面是会倍频的
回复

使用道具 举报

3

主题

117

帖子

0

精华

高级会员

Rank: 4

积分
559
金钱
559
注册时间
2018-10-3
在线时间
107 小时
发表于 2021-9-10 10:19:03 | 显示全部楼层
我也遇见过这个问题。当时用的是F4的。8路串口全部用完了。 会发现有uart9和uart10。 波特率都要除以2。具体还没找到原因。项目急解决了就没管了。
回复

使用道具 举报

4

主题

83

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
205
金钱
205
注册时间
2019-11-12
在线时间
77 小时
发表于 2021-9-10 10:46:59 | 显示全部楼层
不要想当然,仔细去看看手册。同名外设未必在一个apb,不同apb的时钟配置分频也未必一样。
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
 楼主| 发表于 2021-9-10 11:30:59 | 显示全部楼层
远命 发表于 2021-9-10 09:04
/*---------------------------- USART BRR Configuration -----------------------*/
  /* Configure the ...

波特率的设置是对的,仿真可以看到波特率寄存器的值,和其他串口是相同的。想上传截图,不知道为什么不能上传了
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2021-9-10 15:44:28 | 显示全部楼层
yuanzinpl 发表于 2021-9-10 11:30
波特率的设置是对的,仿真可以看到波特率寄存器的值,和其他串口是相同的。想上传截图,不知道为什么不能 ...

只是让你看看 时钟分配 ...不过你自己也找到了
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2021-9-10 15:51:27 | 显示全部楼层
yuanzinpl 发表于 2021-9-10 13:43
找到原因了,HAL库函数中没有考虑UART9和UART10这两种串口的情形,只把USART1和USART6按照所在的APB2时钟设 ...

C:\Users\wave\Desktop\时钟树.JPG    如果想深究可以看看自己的芯片数据手册 我的是没有9
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2021-9-10 15:52:15 | 显示全部楼层
远命 发表于 2021-9-10 15:51
如果想深究可以看看自己的芯片数据手册 我的是没有9

时钟树

时钟树

时钟树
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
568
金钱
568
注册时间
2015-1-12
在线时间
75 小时
 楼主| 发表于 2021-9-10 17:13:37 | 显示全部楼层
本帖最后由 yuanzinpl 于 2021-9-11 11:25 编辑

图片是那个芯片?我用的是STM32F413VGT6,规格书上有UART9,UART10,但是HAL库函数中没有对应的设置


UART9UART10.png
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2021-9-13 09:03:55 | 显示全部楼层
yuanzinpl 发表于 2021-9-10 17:13
图片是那个芯片?我用的是STM32F413VGT6,规格书上有UART9,UART10,但是HAL库函数中没有对应的设置


...

F429IGT6
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 23:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表