【STM32】STM32F302CB串口驱动异常排查

一、环境

1.STM32F302CB的单片机,串口使用默认接口PA9/10;

2.工程从F103C8移植而来;

2.std驱动库

二、情况描述

1.最开始配置为验证正常的BOOT + 新移植的rtt APP

2.现象为串口输出乱码;

3.验证旧APP串口功能正常,对比新旧APP串口初始化无明显差异;

三、排查故障

1.去掉rtt相关初始化代码,只跑串口初始化和打印:现象无明显变化,乱码

2.去掉BOOT,将APP中断向量表便宜改为0:无变化,懵逼;

3.调试,检查GPIO寄存器,AF功能寄存器配置:无明显异常,继续懵逼;

4.调试,检查RCC寄存器,配置参数无明显异常,懵逼二式;

5.调试,检查USART1寄存器,配置参数无明显异常,波特率寄存器计算方式一眼没看懂准备上简单粗暴的办法;

6.上绝招,旧代码跑一遍,查看GPIO,USART,RCC寄存器各主要参数,其他基本都粗略记得参数,唯独波特率平时都直接给没关系细节,遂记录之;

7.新代码跑一遍,八九不离十直接看USART波特率寄存器,啪,此贴终结。。。

数分钟休息时间过去。。。

四、寻找原因

1.确认初始化参数无误,直接看串口初始化库函数:

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
{
    ...
    if (USARTx == USART1)
    {
        apbclock = RCC_ClocksStatus.USART1CLK_Frequency;
    }
    ...
    divider = (uint32_t)((2 * apbclock) / (USART_InitStruct->USART_BaudRate));
    tmpreg  = (uint32_t)((2 * apbclock) % (USART_InitStruct->USART_BaudRate));
    ...
}

2.忽略其他参数,变量就一个:“RCC_ClocksStatus.USART1CLK_Frequency”,追溯到源头函数中有这样一段:

void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
    /* USART1CLK clock frequency */
    if((RCC->CFGR3 & RCC_CFGR3_USART1SW) == 0x0)
    {
#if defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F301x8) || defined(STM32F302x8)
        /* USART1 Clock is PCLK1 instead of PCLK2 (limitation described in the 
        STM32F302/01/34 x4/x6/x8 respective erratasheets) */
        RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->PCLK1_Frequency;
#else
        /* USART Clock is PCLK2 */
        RCC_Clocks->USART1CLK_Frequency = RCC_Clocks->PCLK2_Frequency;
#endif  
    }
}

WTF,问题就在这里,新建工程时还专门纠结过这个问题,std标准库中,没有F302xB这个型号的启动文件,有F302x8和F303xB的都有,唯独没有这个F302xB;本着“就近原则”,当然是选择“同系列”的F302x8,因此keil魔术棒工程设置汇总的全局宏定义为“STM32F302x8”,而实际上STM32F302C8/CB并不只是FLASH和ROM大小上的差异,这,这谁想得到啊。。。

五、总结

1.在库源码中继续以“STM32F302x8”为关键字搜索,发现部分定时器还有差异,F302/3x8等系列的部分定时器时钟最高能到144M(MCU 主时钟最高为72M),看来是因为这里将USART的时钟源从PCLK2调整到1去了。

2.上ST官网下载“Device Errata”和“Device Limitations”文档,确认与代码中描述一致;

3.检查官网F3的STD库,已经是2015年更新了,看来F3的STD库差不多已经是弃疗状态了;

4.祭出STM32CubeMx,新建F302CB工程,得到F302xC的启动文件,这里也应征了F302xB和xC一样是256kB的Flash;

5.搜索STD库中关于MCU信号的宏定义,确定STD所需的全局MCU型号宏定义:

#if !defined (STM32F303xC) && !defined (STM32F334x8) && !defined (STM32F302x8) && !defined (STM32F303xE)
/* #define STM32F303xC */   /*!< STM32F303CB, STM32F303CC, STM32F303RB, STM32F303RC, STM32F303VB, STM32F303VC
                                 STM32F302CB, STM32F302CC, STM32F302RC, STM32F302RB, STM32F302VC, STM32F302VB,
                                 STM32F358CC, STM32F358RC and STM32F358VC Devices */ 
/* #define STM32F334x8 */   /*!< STM32F334C4, STM32F334K4, STM32F334C6, STM32F334R6, STM32F334K6, STM32F334C8, STM32F334R8, STM32F334K8,                         
                                 STM32F303K8, STM32F303K6, STM32F303C8, STM32F303C6, STM32F303R8, STM32F303R6 and STM32F328C8 Devices */
/* #define STM32F302x8 */   /*!< STM32F302K6, STM32F302K8, STM32F302C6, STM32F302C8, STM32F302R6, STM32F302R8, 
                                 STM32F301K8, STM32F301C8, STM32F301R8, STM32F301K6, STM32F301C6, STM32F301R6, STM32F313K8 and STM32F318C8 Devices */ 
/* #define STM32F303xE */   /*!< STM32F303CE, STM32F303CD, STM32F303RE, STM32F303RD, STM32F303VE, STM32F303VD, STM32F303ZE,
                                 STM32F303ZD, STM32F302CE, STM32F302CD, STM32F302RE, STM32F302RD, STM32F302VE, STM32F302ZE, 
                                 STM32F302ZD and STM32F398VE Devices */ 
#endif /* STM32F303xC  || STM32F334x8 || STM32F302x8 || STM32F303xE */

STM32F303xC,取值走人;

咳咳...收拾改得一团糟的代码,吃个饭回来继续码...

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值