1、概要
在一个项目中,使用STM32F103RCT6单片机,定时器引脚使用的PC6,PC6默认复用定时器为TIM8_CH1,但是由于其他原因,不能使用TIM8_CH1,因此需要使用其重定义功能TIM3_CH1,本文分享了本人在该项目中定时器TIM3引脚复用功能重定义的一些问题及解决过程,希望对大家能有帮助。
2、背景
在一个激光器产品控制项目中,需要一个占空比和频率均可调的PWM对激光进行调制,硬件工程师选用的单片机为STM32F103RCT6,将该PWM端口设计为PC6,在做程序设计时发现,该端口的默认复用定时器为TIM8_CH1,但是TIM8有其他用途,不能使用,好在PC6有引脚重定义功能,可将TIM3_CH1重定义到该引脚使用。
3、解决过程
本人一直使用HAL库开发STM32单片机程序,之前未使用过引脚重定义功能,因此上网查了些资料,使用引脚重定义功能时,使用HAL库的引脚重定义功能使能函数即可,TIM3的全部引脚重定义功能函数为stm32f1xx_hal_gpio_ex.h头文件内宏定义的__HAL_AFIO_REMAP_TIM3_ENABLE(),具体如下:
/**
* @brief Enable the remapping of TIM3 alternate function channels 1 to 4
* @note ENABLE: Full remap (CH1/PC6, CH2/PC7, CH3/PC8, CH4/PC9)
* @note TIM3_ETR on PE0 is not re-mapped.
* @retval None
*/
#define __HAL_AFIO_REMAP_TIM3_ENABLE() do{ CLEAR_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP); \
SET_BIT(AFIO->MAPR, AFIO_MAPR_TIM3_REMAP_FULLREMAP); \
}while(0U)
但是在定时器引脚配置函数中调用该函数,配置后还是不能使用,具体的GPIO配置如下,(只列出GPIO配置,PWM配置未列出)
/**
* @brief 定时器GPIO外设配置
* @param 无
* @retval 无
*/
static void TIMx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* 通用定时器GPIO外设时钟使能 */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*TIM3_CH1使用的PC6引脚,需重定义引脚功能*/
__HAL_AFIO_REMAP_TIM3_ENABLE();
/*TIM3_CH1功能引脚IO初始化*/
GPIO_InitStruct.Pin = GPIO_PIN_6; //引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; //模式为复用推挽输出
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); //PC6初始化
/*TIM4_CH1功能引脚IO初始化*/
GPIO_InitStruct.Pin = GPIO_PIN_6; //引脚
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //PB6初始化
}
这样配置之后,TIM3_CH1还是无法正常使用,即PC6引脚无响应配置PWM输出,但是一起配置的默认复用功能的PB6引脚的TIM4_CH1引脚PWM正常。
后来又改变__HAL_AFIO_REMAP_TIM3_ENABLE()位置等等,折腾了好多次,还是不行,后来甚至怀疑是不是芯片的内部硬件故障,重新更换板子,还是不行。
再后来也网上查了查,还是没有解决,然后就重头来,重新翻看STM32F1的参考手册,终于找到了问题原因。
引脚重定义功能配置的是复用重映射和调试I/O配置寄存器(AFIO_MAPR),而手册中明确注明,对寄存器 AFIO_EVCR , AFIO_MAPR 和 AFIO_EXTICRX 进行读写操作前,应当首先打开 AFIO
的时钟。
因此在HAL库中找到开启AFIO时钟的函数__HAL_RCC_AFIO_CLK_ENABLE(),在__HAL_AFIO_REMAP_TIM3_ENABLE()之前开启时钟,重新配置后PC6输出PWM正常,最终的TIM3_CH1的GPIO配置如下:
/**
* @brief 定时器GPIO外设配置
* @param 无
* @retval 无
*/
static void TIMx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* 通用定时器GPIO外设时钟使能 */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*使用重定义引脚功能之前需打开AFIO时钟*/
__HAL_RCC_AFIO_CLK_ENABLE();
/*TIM3_CH1使用的PC6引脚,需重定义引脚功能*/
__HAL_AFIO_REMAP_TIM3_ENABLE();
/*TIM3_CH1功能引脚IO初始化*/
GPIO_InitStruct.Pin = GPIO_PIN_6; //引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; //模式为复用推挽输出
GPIO_InitStruct.Pull = GPIO_PULLDOWN; //下拉
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); //PC6初始化
/*TIM4_CH1功能引脚IO初始化*/
GPIO_InitStruct.Pin = GPIO_PIN_6; //引脚
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //PB6初始化
}
4、小结
遇到问题上网查,如果有同样的问题可能会比较快速解决,但是如果找不到同样的问题,翻翻数据手册和参考手册可能更有利于问题快速解决。文章来源:https://www.toymoban.com/news/detail-496107.html
官方资料是个好东西,后续还是要多翻翻参考手册和HAL库使用说明,加深印象,温故而知新。文章来源地址https://www.toymoban.com/news/detail-496107.html
到了这里,关于STM32F103定时器引脚重定义功能问题处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!