stm32使用定时器1(高级定时器产生pwm)
前言:
通过江科大视频的学习,我们可以轻易地写出定时器2,3,4产生pwm,因为它们都是通用定时器,在代码的基础上把GPIO的初始化做修改,以及把TIMx全都写成我们想要用的定时器即可,我也实践过,确实是能用的
问题:
但用这种方法修改代码,想使用定时器1产生pwm波时,却没有效果
原因:
定时器1是高级定时器,和通用定时器有一些区别
修改方法:
在江科大源代码的基础上,对GPIO的初始化修改为TIM1对应的通道,所有的TIMx修改为TIM1
然后,关键部分是:
1.开启TIM1的时钟时,它的总线和2,3,4的不同,正确代码:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM1在2总线,TIM2,3,4在1总线
2.需要在初始化函数的最后一行加上一句代码,如下:
//使能输出通道
TIM_CtrlPWMOutputs(TIM1, ENABLE); //此代码为高级定时器专属
是的,注意这两处就可以了
代码:
下面附上我的代码,以供参考(发出去后,系统可能会把代码的符号全部改为中文符号,请自行验证):
#include "pwm.h"
//A8-A11
void pwmInit(void){
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM1在2总线,TIM2,3,4在1总线
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启GPIO的时钟 因为CH1复用的端口是A0,所以要配置AO
//选择时基单元的时钟 对应关系是确定的,需要查表
TIM_InternalClockConfig(TIM1); //内部时钟 (不写的话也会默认选择内部时钟)
//配置GPIO
GPIO_InitTypeDef gg;
gg.GPIO_Mode=GPIO_Mode_AF_PP; //复用推广输出
gg.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
gg.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gg);
//配置时基单元
TIM_TimeBaseInitTypeDef tt; //定义结构体变量
tt.TIM_ClockDivision=TIM_CKD_DIV1; //分频,选择1 (比较随意)
tt.TIM_CounterMode=TIM_CounterMode_Up; //计数模式选择向上计数
tt.TIM_Period=100-1; //周期,多长时间溢出一次,不超过65535 (单位:微秒) //ARR
tt.TIM_Prescaler=50*72-1; //自动重装寄存器设置,溢出多少次发起中断,分频是72,所以要×72,不超过65535 //PSC
//外部写10-1 1-1 //最后,定时时间为 10000*100=1000000微秒 = 1秒
tt.TIM_RepetitionCounter=0; //高级计数器才有,我们这里设置的是通用定时器,用不到,直接给0
TIM_TimeBaseInit(TIM1,&tt); //初始化
//初始化输出比较通道
TIM_OCInitTypeDef oo;
TIM_OCStructInit(&oo); //赋初始值,有一些参数只有高级定时器才用到,赋初始值避免出现一些错误
oo.TIM_OCMode=TIM_OCMode_PWM1; //输出比较模式
oo.TIM_OCNPolarity=TIM_OCPolarity_High;
oo.TIM_OutputState=TIM_OutputState_Enable;
oo.TIM_Pulse=0; //CCR 占空比为CCR/ARR
TIM_OC1Init(TIM1,&oo); //不同的口,使用的初始化函数不同.需要根据对应关系调用 //这里开启的是TIM2的CH1通道
TIM_OC2Init(TIM1,&oo);
TIM_OC3Init(TIM1,&oo);
TIM_OC4Init(TIM1,&oo);
//开启定时器
TIM_Cmd(TIM1,ENABLE);
//使能输出通道
TIM_CtrlPWMOutputs(TIM1, ENABLE); //此代码为高级定时器专属
//TIM_SetCompare1(TIM2,n); 可以单独修改CH1通道的CCR值
//启动重映射,和取消调试端口的操作
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //打开AFIO时钟
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //取消那三个调试端口
//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE); //开启映射,改变引脚
}
void pwmSetA1(u8 a){
TIM_SetCompare1(TIM1,a);
}
void pwmSetA2(u8 a){
TIM_SetCompare2(TIM1,a);
}
void pwmSetB1(u8 a){
TIM_SetCompare3(TIM1,a);
}
void pwmSetB2(u8 a){
TIM_SetCompare4(TIM1,a);
}
作者:乐于助人-杰小韦