最近做了一個使用STM32F429的TIM4和TIM14產生的PWM波來驅動兩個步進電機的項目。
看到有不少新入行的同學們在找TIM產生PWM方波的例程代碼,就在這里放一份,供大家參考。
經過親測,唯一需要注意的是TIM4和TIM14產生占空比的方式稍有不同:
TIM14使用
TIM_SetCompare1(TIM14,625); 但是這個辦法對TIM4行不通。
TIM4使用
TIM_OCInitStructure.TIM_Pulse = dutyCycle;
廢話不多說了,Talk is easy,show me the code. 直接上代碼了。這段代碼是我自己親測可用的。
//TIM14 PWM初始化 //PWM輸出初始化 //arr:自動重裝值 psc:時鍾預分頻數。
void TIM14_PWM_Init(u32 arr,u32 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14時鍾使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //是能 PORTF時鍾
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GF9復用為TIM14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //復用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定時器分頻
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseStructure.TIM_Period=arr; //自動重裝載值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定時器14 //初始化TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM調制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出是能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //初始化外設 TIM1 4OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能預裝載寄存器
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
TIM_Cmd(TIM14, ENABLE); //關閉使能TIM14
} void TIM4_PWM_Init(u32 arr,u32 psc, u32 dutyCycle) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //TIM4時鍾使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //是能 PORTD時鍾
GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4); //GD14復用為TIM4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; //GPIO D14
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //復用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //初始化PD14
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定時器分頻
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseStructure.TIM_Period=arr; //自動重裝載值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化定時器14 //初始化TIM4 Channel3 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM調制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出是能
TIM_OCInitStructure.TIM_Pulse = dutyCycle; //配置占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性低
TIM_OC3Init(TIM4, &TIM_OCInitStructure); //初始化外設 TIM4 OC3 通道3
TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能預裝載寄存器
TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE使能
TIM_Cmd(TIM4, ENABLE); //使能TIM14
} //PF9 -->TIM14 Channel_1
void StepMotor_Init(void) { TIM14_PWM_Init(1250-1,84-1); //定時器時鍾為84M,分頻系數為84,所以計數頻率為84M/84=1Mhz,重裝載值1250,所以PWM頻率為 1M/1250=800hz.
TIM_SetCompare1(TIM14,625); //占空比50%. PWM每一個周期為1s/800hz=1.25ms=1250us.設置低電平時間為625us. //升降電機撥碼為1600步每圈。一圈6cm。 現在每秒800步,所以速度為3cm/s
GPIO_InitTypeDef GPIO_InitStructure; /*時鍾使能*/
//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
/* 引腳設置 */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; GPIO_Init(GPIOF, &GPIO_InitStructure); PFout(7)=1; //打開使能
PFout(8)=1; //確定方向 0為向上 1為向下 //PD14 PD15 TIM4
/// 必須按照廠商給定的配置來設置,控制器對應的橫向電機的噪音才會很小。 /// 廠商給定配置控制器撥碼為 800步每圈。PWM給定頻率為每秒2000個脈沖 /// 定時器時鍾為84M,分頻系數為84,所以計數頻率為84M/84=1Mhz,重裝載值500,所以PWM頻率為 1M/5000=2000hz. /// 占空比50%. PWM每一個周期為1s/2000hz=0.5ms=500us.設置低電平時間為250us.
// TIM4 對應水平的滑桿:控制器的撥碼,800步前進一圈,一圈為1.2cm。每秒鍾中有2000步,所以速度為3cm/s
TIM4_PWM_Init(500-1,84-1,250); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_Init(GPIOD, &GPIO_InitStructure); //PDout(14)=1;
PDout(15)=1; //1 為朝左 0為朝右
}