STM32控制小车2个直流电机运动,直流电机的控制通过改变PWM波占空比而非频率,自然频率需要在驱动器合适的范围内。
头文件:
#ifndef __MOTORCONTROL_H #define __MOTORCONTROL_H #include "sys.h" // // #define Vacuumpump PCout(1)//开关控制 void Initialization(void);//初始化 void Motor_IO_Init(void);//初始化GPIO口 /****************************** * * ********************************/ /// /// //左右驱动器使能函数 //左驱动器DIR口控制 void dirleft1(void); void dirleft0(void); //右驱动器DIR口控制 void dirright1(void); void dirright0(void); void LEFTININ(void);//制动 void RIGHTININ(void);//制动 /// void pulleft(void);//左驱动器PUL脉冲输出 void pulright(void);//右驱动器PUL脉冲输出 /// /// // void forward(void);//前进定义 void backward(void);//后退定义 void turnleft(void);//左转定义 void turnright(void);//右转定义 void stop(void);//停止定义 void autoNavigation(void);//自主导航 void fastVel(void);//电机快速 void fast(void);//电机快速 void middVel(void);//电机慢速 void slow(void);//电机慢速 void slowVel(void);//电机慢速 /// /// // //PWM脉冲产生函数 void TIM11_PWM_Init(u32 arr,u32 psc); void TIM10_PWM_Init(u32 arr,u32 psc); #endif源文件:
#include "Motorcontrol.h" #include "delay.h" #include "usart.h" // // //全局变量 int motion;//电机停止 int arrp, pscp;//PWM频率调节参数 float comp1; float comp2; //初始化 void Initialization(void) { //全局变量 motion=0;//电机停止 Motor_IO_Init();//IO口初始化 /*系统时钟初始化函数 * * 未初始化钱时钟频率为15750000HZ * */ //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=50*arrp/100;//左轮 comp2=50*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; TIM_Cmd(TIM11, DISABLE); TIM_Cmd(TIM10, DISABLE); } //初始化GPIO口 void Motor_IO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOF时钟 //GPIOF9,F10初始化设置 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 } /****************************** * * ********************************/ // /// //左驱动器DIR口控制 //左驱动器DIR口控制 void dirleft1(void)//正转 { GPIO_ResetBits(GPIOC,GPIO_Pin_6);//0 GPIO_SetBits(GPIOC,GPIO_Pin_7);//1 } void dirleft0(void) { GPIO_SetBits(GPIOC,GPIO_Pin_6);//1 GPIO_ResetBits(GPIOC,GPIO_Pin_7);//0 } void LEFTININ(void)//制动 { GPIO_SetBits(GPIOC,GPIO_Pin_6);//1 GPIO_SetBits(GPIOC,GPIO_Pin_7);//1 } //右驱动器DIR口控制 void dirright1(void)//正转 { GPIO_ResetBits(GPIOC,GPIO_Pin_8);//0 GPIO_SetBits(GPIOC,GPIO_Pin_9);//1 } void dirright0(void) { GPIO_SetBits(GPIOC,GPIO_Pin_8);//1 GPIO_ResetBits(GPIOC,GPIO_Pin_9);//0 } void RIGHTININ(void)//制动 { GPIO_SetBits(GPIOC,GPIO_Pin_8);//1 GPIO_SetBits(GPIOC,GPIO_Pin_9);//1 } /// //左驱动器PUL脉冲输出 void pulleft(void) { TIM_Cmd(TIM11,ENABLE);//使能脉冲 } //右驱动器PUL脉冲输出 void pulright(void) { TIM_Cmd(TIM10,ENABLE); //使能脉冲 } /// /// // //前进定义 void forward(void) { stop(); delay_ms(25); dirleft0(); dirright1();//左右电机驱动器方向DIR设置 pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } //后退定义 void backward(void) { stop(); delay_ms(25); dirleft1(); dirright0();//左右电机驱动器方向DIR设置 pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } //左转定义 void turnleft(void) { stop(); delay_ms(25); dirleft1(); dirright1();//左右电机驱动器方向DIR设置 pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } //右转定义 void turnright(void) { stop(); delay_ms(25); dirleft0(); dirright0();//左右电机驱动器方向DIR设置 pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } //停止定义 void stop(void) { //停止发脉冲,则电机停止运行 TIM_Cmd(TIM11, DISABLE); TIM_Cmd(TIM10, DISABLE); LEFTININ();//制动 RIGHTININ();//制动 // } //自主导航 void autoNavigation(void) { forward(); delay_ms(50); turnleft(); delay_ms(50); forward(); delay_ms(50); turnright(); delay_ms(50); backward(); delay_ms(50); turnleft(); delay_ms(50); forward(); delay_ms(50); turnright(); delay_ms(50); } void fastVel(void)//电机快速 { //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=0*arrp/100;//左轮 comp2=0*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; if(motion==1) { pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } } void fast(void)//电机快速 { //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=10*arrp/100;//左轮 comp2=10*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; if(motion==1) { pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } } void middVel(void) { //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=20*arrp/100;//左轮 comp2=20*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; if(motion==1) { pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } } void slow(void) { //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=30*arrp/100;//左轮 comp2=30*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; if(motion==1) { pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } } void slowVel(void)//电机慢速 { //PWM频率调节参数 arrp=500-1; pscp=168-1; comp1=40*arrp/100;//左轮 comp2=40*arrp/100;//右轮 TIM11_PWM_Init(arrp,pscp); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz. TIM10_PWM_Init(arrp,pscp);//步进电机最大频率最大速度 //TIM_SetCompare1(TIM11,comp1); //修改比较值,修改占空比 //TIM_SetCompare1(TIM10,comp2); //修改比较值,修改占空比 TIM11->CCR1=comp1; TIM10->CCR1=comp2; if(motion==1) { pulleft(); pulright();//左右电机驱动器PUL脉冲发送 } } /****************************** * * PWM脉冲产生函数 * ********************************/ //TIM14 PWM部分初始化 //PWM输出初始化 //arr:自动重装值 //psc:时钟预分频数 void TIM11_PWM_Init(u32 arr,u32 psc) { //此部分需手动修改IO口设置 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE); //TIM14时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTF时钟 GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_TIM11); //GPIOF9复用为定时器14 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOB,&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(TIM11,&TIM_TimeBaseStructure);//初始化定时器14 //初始化TIM14 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低 TIM_OC1Init(TIM11, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1 TIM_OC1PreloadConfig(TIM11, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器 //TIM_ARRPreloadConfig(TIM11,ENABLE);//ARPE使能 // TIM_Cmd(TIM10,ENABLE); //使能TIM10 //TIM_Cmd(TIM11, DISABLE); } void TIM10_PWM_Init(u32 arr,u32 psc) { //此部分需手动修改IO口设置 GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE); //TIM14时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTF时钟 GPIO_PinAFConfig(GPIOB,GPIO_PinSource8,GPIO_AF_TIM10); //GPIOF9复用为定时器14 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOF9 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOB,&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(TIM10,&TIM_TimeBaseStructure);//初始化定时器14 //初始化TIM14 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低 TIM_OC1Init(TIM10, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1 TIM_OC1PreloadConfig(TIM10, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器 //TIM_ARRPreloadConfig(TIM10,ENABLE);//ARPE使能 // TIM_Cmd(TIM10,ENABLE); //使能TIM10 //TIM_Cmd(TIM10, DISABLE); }