大概思路就是:用TIM1和TIM4两个时钟共8个通道,用PWM来控制小车的4个轮子。 TIM1中的PA8 A9代表左前轮, A10 A11代表左后轮; TIM4中的PB6 B7代表右前轮,B8 B9代表右后轮 下面附上完整代码: timer.h #ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM4_PWM_Init(); void TIM1_PWM_Init(); void Prun(); //前进 void Nrun(); //后退 void Tleft(); //左转 void Trighet();//右转 #endif timer.c #include "timer.h" #include "led.h" //TIM4 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM4_PWM_Init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器4时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO //初始化TIM4 TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM4 Channel/2/3/4 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(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC1 TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC2 TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC3 TIM_OC4Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM4 OC4 TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR1上的预装载寄存器 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR2上的预装载寄存器 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR3上的预装载寄存器 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM4在CCR4上的预装载寄存器 TIM_ARRPreloadConfig(TIM4,ENABLE); TIM_Cmd(TIM4, ENABLE); //使能TIM4 } void TIM1_PWM_Init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO外设 //设置该引脚为复用输出功能,输出TIM1 PWM脉冲波形 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; //TIM_CHX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO //初始化TIM1 TIM_TimeBaseStructure.TIM_Period = 99; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =719; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM4 Channel/2/3/4 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OutputNState=TIM_OutputState_Disable;//高级定时器有一个输出N不使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCPolarity_High;// TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;//这三个是高级定时器要配置的 TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCIdleState_Reset;// //TIM_OCInitStructure.TIM_Pulse=10; TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC1 TIM_OC2Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC2 TIM_OC3Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC3 TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 OC4 TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR1上的预装载寄存器 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR2上的预装载寄存器 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR3上的预装载寄存器 TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //使能TIM1在CCR4上的预装载寄存器 TIM_ARRPreloadConfig(TIM1,ENABLE);//使能自动重装载值 TIM_CtrlPWMOutputs(TIM1,ENABLE);//主输出使能 TIM_Cmd(TIM1, ENABLE); //使能TIM1 } //TIM1中的PA8 A9代表左前轮, A10 A11代表左后轮; TIM4中的PB6 B7代表右前轮,B8 B9代表右后轮 void Prun() { TIM_SetCompare1(TIM1,10); //左前前进 TIM_SetCompare2(TIM1,0); TIM_SetCompare3(TIM1,10); //左后前进 TIM_SetCompare4(TIM1,0); TIM_SetCompare1(TIM4,10); //右前前进 TIM_SetCompare2(TIM4,0); TIM_SetCompare3(TIM4,10); //右后前进 TIM_SetCompare4(TIM4,0); } void Nrun() { TIM_SetCompare1(TIM1,0); //左前后退 TIM_SetCompare2(TIM1,10); TIM_SetCompare3(TIM1,0); //左后后退 TIM_SetCompare4(TIM1,10); TIM_SetCompare1(TIM4,0); //右前后退 TIM_SetCompare2(TIM4,10); TIM_SetCompare3(TIM4,0); //右后后退 TIM_SetCompare4(TIM4,10); } void Tleft() // 原地左转 左边的两个轮子往后转,右边的两个轮子往前转 { TIM_SetCompare1(TIM1,0); //左前后退 TIM_SetCompare2(TIM1,10); TIM_SetCompare3(TIM1,0); //左后后退 TIM_SetCompare4(TIM1,10); TIM_SetCompare1(TIM4,10); //右前前进 TIM_SetCompare2(TIM4,0); TIM_SetCompare3(TIM4,10); //右后前进 TIM_SetCompare4(TIM4,0); } void Trighet() { TIM_SetCompare1(TIM1,10); //左前前进 TIM_SetCompare2(TIM1,0); TIM_SetCompare3(TIM1,10); //左后前进 TIM_SetCompare4(TIM1,0); TIM_SetCompare1(TIM4,0); //右前后退 TIM_SetCompare2(TIM4,10); TIM_SetCompare3(TIM4,0); //右后后退 TIM_SetCompare4(TIM4,10); } 进行一些简单说明 上面的重装载值arr=99,预分频系数psc=719; T=arr * psc /72M,结果为1ms,也就是频率为1KHz; PWM模式设置为TIM_OCMode_PWM1,arr=99, 这样一来占空比调整比较方便: arr=10——占空比为10%; arr=20——占空比为20%; 上面的占空比我设置的是10%,电机转的比较慢(还可以),你可以根据你自己的情况进行自己更改。 main.c #include "delay.h" 实际调试的波形图: 希望对大家有帮助。 |
共5条
1/1 1 跳转至页
用STM32的PWM实现小电机的正反转(带源码)
关键词: STM32 电机 PWM
共5条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |