完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
功能
通过模拟脉冲实现对两路电机的控制 可电机进行使能、方向、速度的调节 一、简介 整个设计的思路比较巧妙,通过一个基本定时器实现不仅可以实现对两路电机的进行控制,还能对步进电机实现加减速控制,具体的实现过程见代码。 二、具体的代码 bsp_motor.h #ifndef _BSP_MOTOR_H #define _BSP_MOTOR_H /*********************************** 引入头文件 start *************************************/ #include “stm32f4xx.h” /************************************ 引入头文件 end *************************************/ /************************************* 宏定义 start *************************************/ #define PULSE_HIGH GPIO_SetBits(GPIOB,GPIO_Pin_13) //脉冲引脚置低 #define PULSE_LOW GPIO_ResetBits(GPIOB,GPIO_Pin_13) //脉冲引脚置高 #define PULSE_TOGGLE PBout(13) //脉冲引脚反转 #define ENA_HIGH GPIO_SetBits(GPIOG,GPIO_Pin_0) //使能引脚置高 --失能 #define ENA_LOW GPIO_ResetBits(GPIOG,GPIO_Pin_0) //使能引脚置低 --使能 #define DIR_HIGH GPIO_SetBits(GPIOF,GPIO_Pin_14) //方向引脚 --前进 #define DIR_LOW GPIO_ResetBits(GPIOF,GPIO_Pin_14) //方向引脚 --后退 /************************************* 宏定义 end **************************************/ typedef struct { uint8_t channel; GPIO_TypeDef* PULSE_GPIOx; //脉冲端口 uint32_t PULSE_GPIO_Pin; //脉冲引脚 GPIO_TypeDef* ENA_GPIOx; //使能端口 uint32_t ENA_GPIO_Pin; //使能引脚 GPIO_TypeDef* DIR_GPIOx; //方向端口 uint32_t DIR_GPIO_Pin; //方向引脚 }Motor_InitTypeDef; /*********************************** 函数声明 start ************************************/ void Motor_InitTypeDef_Init(Motor_InitTypeDef* motor_InitTypeDef); void motor_dir(uint8_t dir); void motor_ena(uint8_t ena); /************************************ 函数声明 end *************************************/ #endif bsp_motor.c #include “bsp_motor.h” uint8_t motor1_flag = 1; //脉冲标志位 1:使能 0:失能 uint8_t motor2_flag = 1; //脉冲标志位 1:使能 0:失能 uint8_t channel1 = 0; //电机1通道使能 uint8_t channel2 = 0; //电机2通道使能 Motor_InitTypeDef* motor1_InitTypeDef; //电机1结构体 Motor_InitTypeDef* motor2_InitTypeDef; //电机结构体 /************************************************************************************** * name : void Motor_GPIO_COnfig(void) * Function : 电机相关引脚的配置 * Parameters : void * Returns : NULL * Author : 那些你很冒险的梦 * Check : * Date : 2021/3/20 **************************************************************************************/ void Motor_GPIO_Config(Motor_InitTypeDef* motor_InitTypeDef) { GPIO_InitTypeDef GPIO_InitStructure; //打开时钟 //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOG|RCC_AHB1Periph_GPIOF, ENABLE); if(motor_InitTypeDef-》PULSE_GPIOx == GPIOA | motor_InitTypeDef-》PULSE_GPIOx == GPIOA | motor_InitTypeDef-》DIR_GPIOx == GPIOA) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOB | motor_InitTypeDef-》PULSE_GPIOx == GPIOB | motor_InitTypeDef-》DIR_GPIOx == GPIOB) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOC | motor_InitTypeDef-》PULSE_GPIOx == GPIOC | motor_InitTypeDef-》DIR_GPIOx == GPIOC) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOD | motor_InitTypeDef-》PULSE_GPIOx == GPIOD | motor_InitTypeDef-》DIR_GPIOx == GPIOD) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOE | motor_InitTypeDef-》PULSE_GPIOx == GPIOE | motor_InitTypeDef-》DIR_GPIOx == GPIOE) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOF | motor_InitTypeDef-》PULSE_GPIOx == GPIOF | motor_InitTypeDef-》DIR_GPIOx == GPIOF) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); } if(motor_InitTypeDef-》PULSE_GPIOx == GPIOG | motor_InitTypeDef-》PULSE_GPIOx == GPIOG | motor_InitTypeDef-》DIR_GPIOx == GPIOG) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); } /*************************************** 脉冲引脚 start **************************************/ GPIO_InitStructure.GPIO_Pin = motor_InitTypeDef-》PULSE_GPIO_Pin; //引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(motor_InitTypeDef-》PULSE_GPIOx, &GPIO_InitStructure); PULSE_LOW; /*************************************** 脉冲引脚 end **************************************/ /************************************** 使能引脚 start ************************************/ GPIO_InitStructure.GPIO_Pin = motor_InitTypeDef-》ENA_GPIO_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(motor_InitTypeDef-》PULSE_GPIOx, &GPIO_InitStructure); /************************************** 使能引脚 end *************************************/ /**************************** 方向引脚 START**************************/ GPIO_InitStructure.GPIO_Pin = motor_InitTypeDef-》DIR_GPIO_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(motor_InitTypeDef-》DIR_GPIOx, &GPIO_InitStructure); /************************************** 方向引脚 end *************************************/ } /************************************************************************************** * name : void Motor_InitTypeDef_Init(Motor_InitTypeDef* motor_InitTypeDef) * Function : 电机初始化 * Parameters : motor_InitTypeDef:电机配置结构体 * Returns : NULL * Author : 那些你很冒险的梦 * Check : * Date : 2021/3/20 **************************************************************************************/ void Motor_InitTypeDef_Init(Motor_InitTypeDef* motor_InitTypeDef) { if(motor_InitTypeDef-》channel == 1) { channel1 = 1; motor1_InitTypeDef = motor_InitTypeDef; } if(motor_InitTypeDef-》channel == 2) { channel2 = 1; motor2_InitTypeDef = motor_InitTypeDef; } Motor_GPIO_Config(motor_InitTypeDef); } /************************************************************************************** * name : void Motor_GPIO_COnfig(void) * Function : 方向控制 * Parameters : 1:使能 0:失能 * Returns : NULL * Author : 那些你很冒险的梦 * Check : * Date : 2021/3/20 **************************************************************************************/ void motor_dir(uint8_t dir) { if(dir==1) { GPIO_ResetBits(GPIOF,GPIO_Pin_14); }else{ GPIO_SetBits(GPIOF,GPIO_Pin_14); } } /************************************************************************************** * name : void Motor_GPIO_COnfig(void) * Function : 使能控制 * Parameters : start 1:顺时针 0:逆时针 * Returns : NULL * Author : 那些你很冒险的梦 * Check : * Date : 2021/3/20 **************************************************************************************/ void motor_ena(uint8_t ena) { if(ena==1) { motor1_flag=0; }else{ motor1_flag=1; } } timer.c #include “timer.h” #include “led.h” #include “bsp_motor.h” extern uint8_t motor1_flag; //产生脉冲标志位 1:表示产生脉冲 0表示不产生脉冲 extern uint8_t motor2_flag; //产生脉冲标志位 1:表示产生脉冲 0表示不产生脉冲 extern uint8_t channel1; extern uint8_t channel2; extern Motor_InitTypeDef* motor1_InitTypeDef; //电机控制结构体1 extern Motor_InitTypeDef* motor2_InitTypeDef; //电机控制结构体2 int speed1=0; //速度控制变量1 int speed2=0; //速度控制变量2 /************************************************************************************** * name : TIM3_Int_Init(u16 arr,u16 psc) * Function : 定时器3配置函数 * Parameters : arr:自动重装载值 psc:预分频系数 * Returns : NULL * Note : * Author : 那些你很冒险的梦 * Check : **************************************************************************************/ void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; NVIC_InitTypeDef NVIC_InitStructure; /********************************* 定时器配置 start *********************************/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启定时器3的时钟 TIM_TimeBaseInitStructure.TIM_Period = arr; //重装载寄存器的值 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频系数 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //中断使能 TIM_Cmd(TIM3,ENABLE); //定时器使能 /********************************* 定时器配置 end *********************************/ /*************************** 中断优先级结构体配置 start ***************************/ NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //配置中断源 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); /**************************** 中断优先级结构体配置 end ***************************/ } /************************************************************************************** * name : TIM3_IRQHandler(void) * Function : 定时器3中断服务函数 * Parameters : void * Returns : NULL * Note : * Author :那些你很冒险的梦 * Check : **************************************************************************************/ int temp1=0; int temp2=0; void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) { //判定通道1是否开启 if(channel1==1) { //将脉冲进行反转 if(motor1_flag==1) { if(temp1《speed1) { temp1++; }else if(temp1==speed1 && speed1 != 0) { motor1_InitTypeDef-》PULSE_GPIOx-》ODR ^= motor1_InitTypeDef-》PULSE_GPIO_Pin;//脉冲引脚电平反转 temp1=0; }else if(temp1》speed1) { temp1=0; } } } //判定通道2是否开启 if(channel2==1) { //将脉冲进行反转 if(motor2_flag==1) { if(temp2《speed2) { temp2++; }else if(temp2==speed1 && speed2 != 0) { motor2_InitTypeDef-》PULSE_GPIOx-》ODR ^= motor2_InitTypeDef-》PULSE_GPIO_Pin;//脉冲引脚电平反转 temp2=0; }else if(temp2》speed2) { temp2=0; } } } } TIM_ClearITPendingBit(TIM3,TIM_IT_Update); } main.c #include “sys.h” #include “delay.h” #include “usart.h” #include “led.h” #include “timer.h” #include “bsp_motor.h” #include “bsp_hmi.h” extern uint8_t isFinish; //1:数据接收完成 0:表示数据接收未完成 extern HMI_Struct hmi_Struct; extern int speed1; int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断配置 delay_init(168); //延时配置 LED_Init(); //LED配置 TIM3_Int_Init(10,6400-1); //打开定时器配置 uart_init(115200); //打开串口配置 //配置电机结构体 Motor_InitTypeDef motor_InitTypeDef; motor_InitTypeDef.channel = 1; //使能通道 motor_InitTypeDef.PULSE_GPIOx = GPIOF; motor_InitTypeDef.PULSE_GPIO_Pin = GPIO_Pin_3; motor_InitTypeDef.ENA_GPIOx = GPIOG; motor_InitTypeDef.ENA_GPIO_Pin = GPIO_Pin_0; motor_InitTypeDef.DIR_GPIOx = GPIOF; motor_InitTypeDef.DIR_GPIO_Pin = GPIO_Pin_14; Motor_InitTypeDef_Init(&motor_InitTypeDef); hmi_Struct.com = USART1; // speed1 = 1; // HMI_WriteBuf(&hmi_Struct,01); // HMI_WriteBuf(&hmi_Struct,02); // HMI_SendCode(&hmi_Struct); // Set_Motor_Speed(16); // ENA_LOW; //使能 // speed1 = 1; while(1) { //HMI_Decode(&hmi_Struct,isFinish); } } |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
2435 浏览 0 评论
9100 浏览 4 评论
36773 浏览 19 评论
5026 浏览 0 评论
24745 浏览 34 评论
1531浏览 2评论
1747浏览 1评论
2196浏览 1评论
1556浏览 0评论
526浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 05:03 , Processed in 1.486313 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号