This post was last edited by 1nnocet- on 2019-7-23 14:50
《PWM Control of DC Motor Acceleration, Deceleration, Forward and Reverse Rotation》
Since I am quite busy recently, I will give a brief introduction here: This article uses TIM3 channel 3 and channel 4 to output two PWMs. The duty cycle can be controlled by touching the buttons.
The following is the main block diagram of the system:
The whole system is composed of the above parts. Ufun is the main control module to control the motor drive circuit. The duty cycle of the output PWM wave is set by the touch keyboard to control the speed of the motor rotation. Two GPIO ports are set to determine whether to output PWM wave and control the direction of motor rotation.
Next, I will briefly introduce the program: I will not repeat the timer and button initialization here, as they are explained in the previous learning section. The point to note in the program is that you cannot let two channels output PWM at the same time, one channel controls forward rotation and the other controls reverse rotation. There is some code at the end of the article. If you want to practice but can't write it, you can share it in a private message if you need the source file
Operation effect:
1. Oscilloscope measurement of duty cycle: Duty cycle adjustable from 1% to 100%
2. Motor drive effect
3. In addition, an interface expansion board was made for easy testing. The motor driver module was bought from Taobao before. The driver module is an H-bridge motor driver topology.
The interface expansion board's main expansion interface
Motor driver board
This content is created by EEWORLD forum user 1nnocet- . If you need to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the source
#include "stm32f10x.h"
#include "stdio.h"
#include "main.h"
#include "LED.h"
#include "PWM.h"
#include "DELAY.h"
#include "TOUCH_KEY.h"
#include "stdlib.h"
#define Arr 500
#define Psc 5
extern int channel;
int main()
{
int key_value,Duty_num=Arr/2; //占空比默认50%
int mode=0;
PwmGPIO_Init();
TIM3_PWM2_Init(Arr,Psc); //pwm初始化
TIM3_PWM1_Init(Arr,Psc);
TK_GPIO_Init(); //触摸按键初始化
//初始化捕获比较值输出PWM
TIM_SetCompare2(TIM3,Duty_num);
TIM_SetCompare1(TIM3,Duty_num);
while (1)
{
key_value=Key_Scan(mode); //获取键值
if(key_value==1) //检测到touch0被按下 进行加速操作
{
if(channel==1) //判断通道
{
Duty_num+=Psc;
if(Duty_num>=Arr)
{
Duty_num=Psc;
}
TIM_SetCompare1(TIM3,Duty_num); //通过改变占空比改变速度
}
if(channel==2)
{
Duty_num+=Psc;
if(Duty_num>=Arr)
{
Duty_num=Psc;
}
TIM_SetCompare2(TIM3,Duty_num); //通过改变占空比改变速度
}
}
if(key_value==2) //检测到touch1被按下 进行减速操作
{
if(channel==1)
{
Duty_num-=Psc;
if(Duty_num<=Psc)
{
Duty_num=Arr;
}
TIM_SetCompare1(TIM3,Duty_num); //通过改变占空比改变速度
}
if(channel==2)
{
Duty_num-=Psc; //亮度上升
if(Duty_num<=Psc)
{
Duty_num=Arr;
}
TIM_SetCompare2(TIM3,Duty_num); //通过改变占空比改变速度
}
}
if(key_value==4) //检测到touch3被按下 切换通道(正反转切换)
{
if(channel==1)
{
TIM3_PWM2_Init(Arr,Psc);
TIM_SetCompare2(TIM3,Duty_num);
}
else if(channel==2)
{
TIM3_PWM1_Init(Arr,Psc);
TIM_SetCompare1(TIM3,Duty_num);
}
}
if(key_value==3) //检测到touch2被按下
{
if(mode==0) //按键模式切换,mode=0为关闭连续按键,mode=1位开启连续按键
{
mode=1;
while(TOUCH2);
}
else
mode=0;
}
}
}
void TIM3_PWM1_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器2时钟
//初始化TIM
TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM Channe PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
// TIM_OC1Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM2 OC1
// TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器
//
// TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM2 OC2
// TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM2在CCR2上的预装载寄存器
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM2 OC3
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM2在CCR3上的预装载寄存器
//初始化TIM Channe PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM2 OC4
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM2在CCR3上的预装载寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM2
TIM_ARRPreloadConfig(TIM3, ENABLE);//使能或者失能 TIM2 在 ARR 上的预装载寄存器
TIM_CtrlPWMOutputs(TIM3, ENABLE);//
channel=1;
}