通用定时器的输出比较部分:
开始写代码:
PWM初始化:
- RCC开启时钟,把我们要用的TIM外设和GPIO外设的时钟打开
- 配置时基单元(包括前面的时钟源选择)
- 配置输出比较单元(里面包括这个CCR的值、输出比较模式、极性选择、输出使能这些参数)
- 配置GPIO
- 运行控制,启动PWM
介绍库函数
配置输出比较单元,输出比较单元有四个,一个函数一个单元(重要)
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
给输出比较结构体赋一个默认值
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
配置强制输出模式(不需要掌握)
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
配置快速使能(不需要掌握)
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
外部事件时清除REF信号
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
单独设置输出比较的极性
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
选择输出比较模式,单独更改输出比较模式
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
单独更改CCR寄存器值的函数 (重要)
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
这个函数仅高级定时器使用在使用高级定时器输出PWM时需要调用这个函数,使能主输出否则PWM将不能正常输出
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
- RCC开启时钟,把我们要用的TIM外设和GPIO外设的时钟打开
- 配置时基单元(包括前面的时钟源选择)
//ÅäÖÃʱÖÓ
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//Ñ¡Ôñʱ»ùµ¥ÔªµÄʱÖÓ
TIM_InternalClockConfig(TIM2);//ÄÚ²¿Ê±ÖÓ
//ÅäÖÃʱ»ùµ¥Ôª
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
// ¶¨Ê±Æ÷×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseInitStructure.TIM_Period=10000-1;
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
//ÊÖ¶¯Çå³ýһϸüÐÂÖжϱê־λ
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
//ʹÄܸüÐÂÖжÏ
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
//Æô¶¯¶¨Ê±Æ÷
TIM_Cmd(TIM2,ENABLE);
- 配置输出比较单元(里面包括这个CCR的值、输出比较模式、极性选择、输出使能这些参数)
- 配置GPIO
- 运行控制,启动PWM
PWM.c全部代码
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
//ÅäÖÃʱÖÓ
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
// ÅäÖÃʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
// ³õʼ»¯GPIO¿Ú
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//Ñ¡Ôñʱ»ùµ¥ÔªµÄʱÖÓ
TIM_InternalClockConfig(TIM2);//ÄÚ²¿Ê±ÖÓ
//ÅäÖÃʱ»ùµ¥Ôª
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
// ¶¨Ê±Æ÷×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseInitStructure.TIM_Period=100-1;//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;//PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
// ÉèÖÃÊä³ö±È½ÏµÄģʽ
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
// ÉèÖÃÊä³ö±È½ÏµÄ¼«ÐÔ
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
// ÉèÖÃÊä³öʹÄÜ
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
// ÉèÖÃCCR
TIM_OCInitStructure.TIM_Pulse=0;//CCR
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
//ÊÖ¶¯Çå³ýһϸüÐÂÖжϱê־λ
/* TIM_ClearFlag(TIM2,TIM_FLAG_Update);
//ʹÄܸüÐÂÖжÏ
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
*/
//Æô¶¯¶¨Ê±Æ÷
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare);
}
因为这些注释粘贴到上面就乱码了,所以再粘一下截屏
重映射:
可以看出,TIM2的CH1可以从PA0挪到PA15上 ,要用到AFIO,此时就要开启AFIO的时钟
引脚重映射配置
有四种重映射方式,我们可以选择其中两种
什么都不写是没有重映射,因此:
重映射代码
JTDI是调试端口,所以如果想让他作为普通的GPIO或者复用定时器的通道,需要先关闭调试端口的复用
第一个:解除JTRST的调试功能 ,PB4变成正常的GPIO口,其他不变
第二个:解除JTAG调试端口的复用功能,即PA15,PB3,PB4变成正常的GPIO口
第三个:都变成正常的GPIO口
总结: