项目场景:
客户做的一个单片机项目,使用rtthread+stm32f103c8t6组合,通过TIM3的1,2,3通道输出pwm,控制灯闪烁,亮灭。
问题描述
TIM3的1,2,3通道引脚因为硬件布线原因需要重映射,1,2通道分别映射到PB4,PB5 ,调试过程发现只有3通道PB0有PWM输出,其他两个引脚无输出,因为之前使用cubeMx生成的工程运行过,因此排除硬件原因,从软件入手分析。
原因分析:
主要分析手段就是打断点,确认寄存器是否配置正确,排查到TIM3_REMAP寄存器的时候发现代码已经走过,但是寄存器里面的值却没有变化。
__HAL_AFIO_REMAP_TIM3_PARTIAL
这种情况说明寄存器没有写成功,或者说寄存器没有工作,所以要打开AFIO的时钟。
__HAL_RCC_AFIO_CLK_ENABLE
时钟打开后PB5有了pwm输出,但是PB4依旧没有变化。
继续观察寄存器,发现PB4的ODR寄存器和IDR寄存器值始终没有变化。一开始以为代码在别的地方进行了初始化,于是将断点放在程序一开始运行的地方,发现PB4的ODR寄存器一上电就为高。
怀疑是单片机内部做了什么配置,百度了一番发现STM32的PB3、PB4,分别是JTAG的JTDO和NJTRST引脚,在没关闭JTAG功能之前,在程序中是配置不了这些引脚的功能的。要配置这些引脚,首先要开启AFIO时钟,然后在AFIO的设置中,释放这些引脚。具体看STM32的参考手册中有关AFIO的部分。
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_AFIO_REMAP_SWJ_NOJTAG();
在cubeMx生成的代码中进行搜索发现 HAL_MspInit 函数中集中了相关代码,于是复制到board.c中,所有pwm正常输出。