stm32 pwm 控制电机正反转

STM32 的通用 TIMx (TIM2~TIM5 和 TIM9~TIM14):

stm32f405rgt6(LQFP 64) 通用定时器对应的io口映射:

注意,使用时发现,表格的语句上一行必须为空行,不然表格不生效。

| TIM x | CH x | io pin
|:-:|:-:|:-:|
| TIM2 | CH2 | PA1 PB3 |
| TIM2 | CH3 | PA2 PB10 |
| TIM2 | CH4 | PA3 PB11 |
| TIM3 | CH1 | PC6 PB4 PA6 |
| TIM3 | CH2 | PC7 PB5 PA7 |
| TIM3 | CH3 | PC8 PB0 |
| TIM3 | CH4 | PC9 PB1 |
| TIM5 | CH1 | PA0 |
| TIM5 | CH2 | PA1 |
| TIM5 | CH3 | PA2 |
| TIM5 | CH4 | PA3 |
| TIM4 | CH1 | PB6 |
| TIM4 | CH2 | PB7 |
| TIM4 | CH3 | PB8 |
| TIM4 | CH4 | PB9 |
| TIM10 | CH1 | PB8 |
| TIM11 | CH1 | PB9 |
| TIM12 | CH1 | PB14 |
| TIM12 | CH2 | PB15 |
| TIM13 | CH1 | PA6 |
| TIM14 | CH1 | PA7 |

补充:定时器中单服务函数名

可以在 startup_stm32f40_41xxx.s 文件中搜索

1
2
3
4
5
6
7
8
9
10
11
12
TIM2_IRQHandler                   ; TIM2                                            
TIM3_IRQHandler ; TIM3
TIM4_IRQHandler ; TIM4
TIM5_IRQHandler ; TIM5
TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors
TIM7_IRQHandler ; TIM7
TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14

timer

代码实现

使用PA6 PA7( TIM3的1 2 通道)产生两路pwm波,实现电机的正反转

定时器初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//TIM3 PWM 初始化 PA6 TIM3CH1 PA7 TIM3 CH2  
//arr 自动重装值
//psc 时钟预分频系数
void TIM3_PWM_Init(u32 arr,u32 psc)
{
//io口配置

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3 时钟初始化
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //GPIO口初始化

GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //GPIO复用为定时器功能
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //GPIO
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(GPIOA,&GPIO_InitStructure);

//定时器配置
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(TIM3,&TIM_TimeBaseStructure);//TIM3

//定时器pwm输出配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // pwm 脉宽调制1模式 即计数器值小于比较值时高电平大于时低电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出比较极性高
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable; //N??????
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset ; // 必须加,否则只有一路输出
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //tim3 ch1 初始化


TIM_OC2Init(TIM3, &TIM_OCInitStructure); //tim3 ch2 初始化

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能tim3 ch1 预装载寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能tim3 ch2 预装载寄存器

TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能

TIM_Cmd(TIM3, ENABLE); //使能TIM3


}

void Prun(u32 c1,u32 c2)
{
TIM_SetCompare1(TIM3,c1); // TIM3 CH1 比较,大于c1反转
TIM_SetCompare2(TIM3,c2);
}

主函数

所用芯片时钟频率为84Mhz,预分频系数84,最大计数值为1000,则pwm频率为 f=84MHz/(84*1000) = 1KHz

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main(void)
{
u16 PWM_HZ = 1000; // pwm运行频率 1kHz 1ms
u16 PSC = 84 ; //时钟预分频系数
u32 CLK_CNT = 84000000;
u32 TOTAL_CLK_HZ = CLK_CNT/PSC; // 1s 的计数次数 84M/84 = 1M hz
u32 TOTAL_CNT = TOTAL_CLK_HZ/PWM_HZ; //定时器的最大计数值,决定了pwm的频率
u8 dir=1;
u32 ms_delay = 500; // 10ms/doublerate
u32 cnt_cmp = 80; //高电平持续8%
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组初始化
delay_init(168); //延时初始化
// uart_init(115200);//串口波特率初始化
TIM3_PWM_Init(TOTAL_CNT-1,PSC-1); //pwm初始化
while(1) //主循环
{
delay_ms(ms_delay); //每0.5s反转一次
if(dir)
{
dir = 0;
Prun(cnt_cmp,0);//dir==1 正转
}
else
{
dir = 1;
Prun(0,cnt_cmp); //dir==0 反转
}
}
}

部分踩坑

TIM5 在四路pwm输出测试中(PA0 1 2 3), PA1持续输出不受控制的方波, 其他三路正常,暂时未找到原因,待调试.
TIM3 (PC 6-9)四路pwm输出正常
TIM4 (PB6-9)四路PWM输出正常

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×