提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
器件
stm32f407zgt6芯片,tb6600驱动器
植树机代码,可以驱动四路42步进电机,以下是只驱动1路。
实物
:
接线
红线接B+(TB6600), 蓝线接B-, 绿线接A-, 黑线接A+
该图片是转载的。根据本文代码:Signal的-统一接开发板的GND(解法看实物照片),而PUL+接PC6(开发板)——控制脉冲,即距离和转速、DIR+接PE5(开发板)——控制转向,ENA+空着。TB6600驱动板的GND和VCC外接电源(不要用单纯的杜邦线)。
TB6600拨码卡关
1区:一个脉冲,电机转动1.8度,而1区的NC可以控制单位转角,即1.8/NC,挡位越大则转动的角度越小,可以做到精度越高。
2区:控制电流。
3、4区:即拨码开关,通过拨动右侧的六个开关即可以调到相应挡位。向上拨,是OFF。
代码说明
:极简版的代码是只能驱动步进电机进行调试而已,而完整版(植树机)有比较多的函数可以用来参考。文章来源:https://www.toymoban.com/news/detail-437493.html
main.c 代码如下(示例):
#include "sys.h"
#include "delay.h"
//#include "usart.h"
//#include "led.h"
//#include "pwm.h"
#include "step_motor.h"
//#include "uart3.h"
//#include "hongwai.h"
#include "stdlib.h"
//#include "oled.h"
//int num=81;
int shengyu_num=98;
int last_num=1;
//int s_flag=1;
//extern u16 step_speed;
//extern u16 step_angle;
//extern u32 Toggle_Pulse[4];
//extern unsigned char BMP2[];
//extern unsigned char BMP3[];
//extern unsigned char BMP4[];
//extern unsigned char BMP5[];
u8 h_num=0;
//void show_qiang()
//{
// OLED_ShowCHinese(0,4,0);
// OLED_ShowCHinese(18,4,1);
// OLED_ShowCHinese(36,4,2);
// OLED_ShowCHinese(54,4,3);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(72,4,". ");
// OLED_ShowNum(54,0,num,2,16);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(90,4,". ");
// OLED_ShowNum(54,0,num,2,16);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(108,4,". ");
// OLED_ShowNum(54,0,num,2,16);
// delay_ms(3000);
//}
//void show_zhong()
//{
// OLED_ShowCHinese(0,4,0);
// OLED_ShowCHinese(18,4,1);
// OLED_ShowCHinese(36,4,2);
// OLED_ShowCHinese(54,4,3);
//
// delay_ms(3000);
// OLED_ShowString(72,4,". ");
//
// delay_ms(3000);
// num++;
// OLED_ShowString(90,4,". ");
// OLED_ShowNum(54,0,num,2,16);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(108,4,". ");
// OLED_ShowNum(54,0,num,2,16);
// delay_ms(3000);
//}
//void show_ruo()
//{
// OLED_ShowCHinese(0,4,0);
// OLED_ShowCHinese(18,4,1);
// OLED_ShowCHinese(36,4,2);
// OLED_ShowCHinese(54,4,3);
//
// delay_ms(3000);
// OLED_ShowString(72,4,". ");
//
// delay_ms(3000);
// OLED_ShowString(90,4,". ");
//
// delay_ms(3000);
// num++;
// OLED_ShowString(108,4,". ");
// OLED_ShowNum(54,0,num,2,16);
// delay_ms(3000);
//}
//void show_wu()
//{
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_ShowCHinese(0,0,14);
// OLED_ShowCHinese(18,0,15);
// OLED_ShowCHinese(36,0,16);
// if(num>=100){
// num=100;
// OLED_ShowNum(54,0,num,3,16);
// }
// else OLED_ShowNum(54,0,num,2,16);
// OLED_ShowString(81,0,"%");
OLED_ShowCHinese(54,0,17);
OLED_ShowCHinese(72,0,18);
delay_ms(200);
//
// OLED_ShowCHinese(0,2,25);//已
// OLED_ShowCHinese(18,2,26);
// OLED_ShowCHinese(36,2,27);
// OLED_ShowCHinese(54,2,30);
// OLED_ShowCHinese(72,2,31);
// OLED_ShowCHinese(90,2,32);
// OLED_ShowNum(108,2,last_num,1,16);
//
// OLED_ShowCHinese(0,4,33);
// OLED_ShowCHinese(18,4,34);
// OLED_ShowCHinese(36,4,35);
// OLED_ShowCHinese(54,4,36);
// OLED_ShowCHinese(72,4,37);
// OLED_ShowCHinese(90,4,38);
// OLED_ShowNum(108,4,shengyu_num,2,16);
//
// OLED_ShowCHinese(0,6,39);
// OLED_ShowCHinese(18,6,40);
// OLED_ShowCHinese(36,6,41);
// OLED_ShowCHinese(54,6,42);
//
// OLED_ShowString(72,6,". ");
// OLED_ShowString(90,6,". ");
// OLED_ShowString(108,6,". ");
//}
//void show_ele()
//{
// int i;
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_Fill(1,5,110,10,1);
// OLED_Fill(1,50,110,55,1);
// OLED_Fill(0,5,5,55,1);
// OLED_Fill(110,5,115,55,1);
// OLED_Fill(115,20,120,40,1);
// for(i=0;i<5;i++)
// {
// OLED_Fill(9+i*20,14,25+i*20,46,1);
// delay_ms(1000);
// }
// //OLED_Fill(9,14,110,46,0);
// delay_ms(500);
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_ShowCHinese(0,0,14);
// OLED_ShowCHinese(18,0,15);
// OLED_ShowCHinese(36,0,16);
// if(num>=100)
// {
// num=100;
// OLED_ShowNum(54,0,num,3,16);
// OLED_ShowCHinese(0,2,18);//停
// OLED_ShowCHinese(18,2,19);
// OLED_ShowCHinese(36,2,20);
// OLED_ShowCHinese(54,2,21);
// OLED_ShowCHinese(0,4,20);
// OLED_ShowCHinese(18,4,21);
// OLED_ShowCHinese(36,4,22);
// OLED_ShowCHinese(54,4,23);
// OLED_ShowCHinese(72,4,16);
// OLED_ShowCHinese(90,4,24);
// while(1);
// }
// else OLED_ShowNum(54,0,num,2,16);
// OLED_ShowString(81,0,"%");
OLED_ShowCHinese(54,0,17);
OLED_ShowCHinese(72,0,18);
delay_ms(200);
//
// OLED_ShowCHinese(0,2,8);
// OLED_ShowCHinese(18,2,9);
// OLED_ShowCHinese(36,2,10);
// OLED_ShowCHinese(54,2,11);
// OLED_ShowCHinese(72,2,12);
//
// switch(s_flag%3)
// {
// case 1: OLED_ShowCHinese(90,2,13);
// show_qiang();
// break;
// case 2: OLED_ShowCHinese(90,2,4);
// show_zhong();
// break;
// case 0: OLED_ShowCHinese(90,2,17);
// show_ruo();
// break;
// default: break;
// }
// s_flag++;
//}
//void show_ele2()
//{
// int i;
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_Fill(1,5,110,10,1);
// OLED_Fill(1,50,110,55,1);
// OLED_Fill(0,5,5,55,1);
// OLED_Fill(110,5,115,55,1);
// OLED_Fill(115,20,120,40,1);
// for(i=0;i<5;i++)
// {
// OLED_Fill(9+i*20,14,25+i*20,46,1);
// delay_ms(1000);
// }
// //OLED_Fill(9,14,110,46,0);
// delay_ms(500);
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_ShowCHinese(0,0,14);
// OLED_ShowCHinese(18,0,15);
// OLED_ShowCHinese(36,0,16);
// if(num>=100)
// {
// num=100;
// OLED_ShowNum(54,0,num,3,16);
// OLED_ShowCHinese(0,2,18);//停
// OLED_ShowCHinese(18,2,19);
// OLED_ShowCHinese(36,2,20);
// OLED_ShowCHinese(54,2,21);
// OLED_ShowCHinese(0,4,20);
// OLED_ShowCHinese(18,4,21);
// OLED_ShowCHinese(36,4,22);
// OLED_ShowCHinese(54,4,23);
// OLED_ShowCHinese(72,4,16);
// OLED_ShowCHinese(90,4,24);
// while(1);
// }
// else OLED_ShowNum(54,0,num,2,16);
// OLED_ShowString(81,0,"%");
OLED_ShowCHinese(54,0,17);
OLED_ShowCHinese(72,0,18);
delay_ms(200);
//
// OLED_ShowCHinese(0,2,8);
// OLED_ShowCHinese(18,2,9);
// OLED_ShowCHinese(36,2,10);
// OLED_ShowCHinese(54,2,11);
// OLED_ShowCHinese(72,2,12);
// OLED_ShowCHinese(90,2,17);
// show_ruo();
//
//}
int main(void)
{
// int i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
step_motor_1_Init(); //电机1初始化
step_motor_2_Init(); //电机2初始化
step_motor_3_Init(); //电机3初始化
step_motor_4_Init(); //电机4初始化
TIM8_OPM_RCR_Init(1000-1,168-1);
// TIM4_PWM_Init(1000-1,84-1);
// TIM13_PWM_Init(1999,84-1);
// TIM14_PWM_Init(1999,84-1);
// USART3_Init(9600);
// HONGWAI_Init();
// OLED_Show_main();
// show_wu();
// while(1)
// {
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_Fill(1,5,110,10,1);
// OLED_Fill(1,50,110,55,1);
// OLED_Fill(0,5,5,55,1);
// OLED_Fill(110,5,115,55,1);
// OLED_Fill(115,20,120,40,1);
// for(i=0;i<5;i++)
// {
// OLED_Fill(9+i*20,14,25+i*20,46,1);
// delay_ms(1000);
// }
// //OLED_Fill(9,14,110,46,0);
// delay_ms(500);
// OLED_Clear();
// OLED_Refresh_Gram();
// OLED_ShowCHinese(0,0,14);
// OLED_ShowCHinese(18,0,15);
// OLED_ShowCHinese(36,0,16);
// OLED_ShowNum(54,0,num,2,16);
// OLED_ShowString(72,0,"%");
OLED_ShowCHinese(54,0,17);
OLED_ShowCHinese(72,0,18);
delay_ms(200);
//
// OLED_ShowCHinese(0,2,8);
// OLED_ShowCHinese(18,2,9);
// OLED_ShowCHinese(36,2,10);
// OLED_ShowCHinese(54,2,11);
// OLED_ShowCHinese(72,2,12);
// switch(s_flag%3)
// {
// case 1: OLED_ShowCHinese(90,2,13);
// show_qiang();
// break;
// case 2: OLED_ShowCHinese(90,2,4);
// show_zhong();
// break;
// case 0: OLED_ShowCHinese(90,2,17);
// show_ruo();
// break;
// default: break;
// }
//OLED_ShowCHinese(90,2,13);//显示强字,13:强 4:中 17:弱
// OLED_ShowCHinese(0,4,0);
// OLED_ShowCHinese(18,4,1);
// OLED_ShowCHinese(36,4,2);
// OLED_ShowCHinese(54,4,3);
//
// delay_ms(3000);
// num++;
OLED_ShowCHinese(72,4,5);
// OLED_ShowString(72,4,". ");
// OLED_ShowNum(54,0,num,2,16);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(90,4,". ");
OLED_ShowCHinese(90,4,6);
// OLED_ShowNum(54,0,num,2,16);
//
// delay_ms(3000);
// num++;
// OLED_ShowString(108,4,". ");
// OLED_ShowNum(54,0,num,2,16);
// delay_ms(3000);
// s_flag++;
// OLED_ShowCHinese(108,4,7);
// }
// OLED_ShowCHinese(0,6,0);
// OLED_ShowCHinese(18,6,1);
// OLED_ShowCHinese(36,6,2);
// OLED_ShowCHinese(54,6,3);
// OLED_ShowCHinese(72,6,5);
// OLED_ShowCHinese(90,6,6);
// OLED_ShowCHinese(108,6,7);
// delay_ms(500);
// OLED_ShowLogo(0,0,64,64,BMP4);
// OLED_DrawBMP1(0,0,64,64,BMP4);
// OLED_Refresh_Gram();
// SUM_1=0;
// SUM_2=0;
// SUM_3=0;
// SUM_4=0;
// delay_ms(1000);
// TIM_SetCompare1(TIM14,800);//解锁
// TIM_SetCompare1(TIM13,800);
// delay_ms(1000);
// motor_left();
// motor_right();
// Locate_Rle_3(11500,1);//三电机一个行程11000个
// delay_ms(12000);//M3一个行程的时间
// Locate_Rle_3(11500,0);//三电机一个行程11000个
// delay_ms(12000);//M3一个行程的时间
while(1)
{
Locate_Rle_1(10000,1);//下降,电机1
delay_ms(16000);
Locate_Rle_1(10000,0);//上升,电机1
delay_ms(16000);
// switch(step_flag)
// {
// case 0:move(1,1);break;
// case 1:move(2,0);break;
// case 2:move(2,0);move(1,1);break;
// case 3:move(3,1);break;
// case 4:move(3,0);break;
// case 5:move(4,1);break;
// case 6:move(4,0);break;
// case 7:show_ele2(); break;
// case 8:motion();break;
// case 9: show_wu();
// delay_ms(10000);
// break;
// default:break;
// }
}
}
main.c 代码(极简版)
#include "sys.h"
#include "delay.h"
#include "step_motor.h"
#include "stdlib.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
step_motor_1_Init(); //电机1初始化
step_motor_2_Init(); //电机2初始化
step_motor_3_Init(); //电机3初始化
step_motor_4_Init(); //电机4初始化
TIM8_OPM_RCR_Init(1000-1,168-1);
while(1)
{
Locate_Rle_1(10000,1);//下降,电机1
delay_ms(16000);
Locate_Rle_1(10000,0);//上升,电机1
delay_ms(16000);
}
}
step_motor.c 代码如下(示例):
#include "step_motor.h"
#include "delay.h"
#include "usart.h"
long SUM_1;
long SUM_2;
long SUM_3;
long SUM_4;
u32 Toggle_Pulse[4]={900,500,500,100};
u32 pulse=0;
u8 step_flag=9;
//电机两个引脚
extern last_num,shengyu_num;
void step_motor_1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR1_ENA=0;
STEPMOTOR1_DIR=1;
}
void step_motor_2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR2_ENA=0;
STEPMOTOR2_DIR=1;
}
void step_motor_3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR3_ENA=0;
STEPMOTOR3_DIR=1;
}
void step_motor_4_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR4_ENA=0;
STEPMOTOR4_DIR=1;
}
//电机PWM信号生成口
void TIM8_OPM_RCR_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTC时钟
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8); //复用为定时器8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 |GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
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_DOWN; //下拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比较输出2N失能 *******/
TIM_OCInitStructure.TIM_Pulse = arr>>1; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
//CH1
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH2
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH3
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH4
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE); //TIM8 使能或者失能指定的TIM中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn; //TIM8中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ClearITPendingBit(TIM8, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
TIM_Cmd(TIM8, ENABLE); //使能TIM8
}
/******* TIM8更新中断服务程序 *********/
void TIM8_UP_TIM13_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//更新中断
{
TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中断标志位
if(SUM_1==0)//重复计数器未设置完成
{
TIM_SetCompare1(TIM8,0);
}
else
{
TIM_SetCompare1(TIM8,800);
SUM_1--;
}
if(SUM_2==0)//重复计数器未设置完成
{
TIM_SetCompare2(TIM8,0);
}
else
{
TIM_SetCompare2(TIM8,800);
SUM_2--;
}
if(SUM_3==0)//重复计数器未设置完成
{
TIM_SetCompare3(TIM8,0);
}
else
{
TIM_SetCompare3(TIM8,800);
SUM_3--;
}
if(SUM_4==0)//重复计数器未设置完成
{
TIM_SetCompare4(TIM8,0);
}
else
{
TIM_SetCompare4(TIM8,800);
SUM_4--;
}
}
}
/***************** 启动TIM8 *****************/
void Locate_Rle_1(long num,int dir) //相对定位函数
{
STEPMOTOR1_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR1_DIR=0;
}
else//逆时针
{
STEPMOTOR1_DIR=1;
}
SUM_1=num;
TIM_SetCompare1(TIM8,800);
}
void Locate_Rle_2(long num,int dir) //相对定位函数
{
STEPMOTOR2_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR2_DIR=0;
}
else//逆时针
{
STEPMOTOR2_DIR=1;
}
SUM_2=num;
TIM_SetCompare2(TIM8,800);
}
void Locate_Rle_3(long num,int dir) //相对定位函数
{
STEPMOTOR3_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR3_DIR=0;
}
else//逆时针
{
STEPMOTOR3_DIR=1;
}
SUM_3=num;
TIM_SetCompare3(TIM8,800);
}
void Locate_Rle_4(long num,int dir) //相对定位函数
{
STEPMOTOR4_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR4_DIR=0;
}
else//逆时针
{
STEPMOTOR4_DIR=1;
}
SUM_4=num;
TIM_SetCompare4(TIM8,800);
}
void motion()
{
Locate_Rle_4(30000,1);
jidianqi_open();
delay_ms(31000);//M4一个行程的时间
Locate_Rle_4(30000,0);
delay_ms(30000);
jidianqi_close();
Locate_Rle_3(11300,1);
delay_ms(12000);//M3一个行程的时间
while(Hongwai_flag())
{
Locate_Rle_1(900,1);
Locate_Rle_2(900,0);
delay_ms(100);
}
Locate_Rle_1(3000,1);
Locate_Rle_2(900,0);
delay_ms(4000);
Locate_Rle_3(11300,0);
last_num++;
shengyu_num--;
step_flag=9;
}
void move(int n,int t)
{
switch(n)
{
case 1: Locate_Rle_1(90,t);break;
case 2: Locate_Rle_2(90,t);break;
case 3: Locate_Rle_3(90,t);break;
case 4: Locate_Rle_4(90,t);break;
}
}
step_motor.c 代码(极简版)
#include "step_motor.h"
#include "delay.h"
#include "usart.h"
long SUM_1;
long SUM_2;
long SUM_3;
long SUM_4;
void step_motor_1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR1_ENA=0;
STEPMOTOR1_DIR=1;
}
void step_motor_2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR2_ENA=0;
STEPMOTOR2_DIR=1;
}
void step_motor_3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE5,6
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR3_ENA=0;
STEPMOTOR3_DIR=1;
}
void step_motor_4_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14; //DRIVER_DIR DRIVER_OE对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIOE5,6
STEPMOTOR4_ENA=0;
STEPMOTOR4_DIR=1;
}
//电机PWM信号生成口
void TIM8_OPM_RCR_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTC时钟
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8); //复用为定时器8
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8); //复用为定时器8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 |GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
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_DOWN; //下拉
GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出2使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; /****** 比较输出2N失能 *******/
TIM_OCInitStructure.TIM_Pulse = arr>>1; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
//CH1
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH2
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH3
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
//CH4
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH2预装载使能
TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能
TIM_ITConfig(TIM8, TIM_IT_Update ,ENABLE); //TIM8 使能或者失能指定的TIM中断
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn; //TIM8中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级1级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_ClearITPendingBit(TIM8, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
TIM_Cmd(TIM8, ENABLE); //使能TIM8
}
/******* TIM8更新中断服务程序 *********/
void TIM8_UP_TIM13_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_FLAG_Update)!=RESET)//更新中断
{
TIM_ClearITPendingBit(TIM8,TIM_FLAG_Update);//清除更新中断标志位
if(SUM_1==0)//重复计数器未设置完成
{
TIM_SetCompare1(TIM8,0);
}
else
{
TIM_SetCompare1(TIM8,800);
SUM_1--;
}
if(SUM_2==0)//重复计数器未设置完成
{
TIM_SetCompare2(TIM8,0);
}
else
{
TIM_SetCompare2(TIM8,800);
SUM_2--;
}
if(SUM_3==0)//重复计数器未设置完成
{
TIM_SetCompare3(TIM8,0);
}
else
{
TIM_SetCompare3(TIM8,800);
SUM_3--;
}
if(SUM_4==0)//重复计数器未设置完成
{
TIM_SetCompare4(TIM8,0);
}
else
{
TIM_SetCompare4(TIM8,800);
SUM_4--;
}
}
}
/***************** 启动TIM8 *****************/
void Locate_Rle_1(long num,int dir) //相对定位函数
{
STEPMOTOR1_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR1_DIR=0;
}
else//逆时针
{
STEPMOTOR1_DIR=1;
}
SUM_1=num;
TIM_SetCompare1(TIM8,800);
}
void Locate_Rle_2(long num,int dir) //相对定位函数
{
STEPMOTOR2_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR2_DIR=0;
}
else//逆时针
{
STEPMOTOR2_DIR=1;
}
SUM_2=num;
TIM_SetCompare2(TIM8,800);
}
void Locate_Rle_3(long num,int dir) //相对定位函数
{
STEPMOTOR3_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR3_DIR=0;
}
else//逆时针
{
STEPMOTOR3_DIR=1;
}
SUM_3=num;
TIM_SetCompare3(TIM8,800);
}
void Locate_Rle_4(long num,int dir) //相对定位函数
{
STEPMOTOR4_ENA = 0;
if(TIM8->CR2&0x01)//上一次脉冲还未发送完成 直接返回
{
return;
}
if(dir==1)//顺时针
{
STEPMOTOR4_DIR=0;
}
else//逆时针
{
STEPMOTOR4_DIR=1;
}
SUM_4=num;
TIM_SetCompare4(TIM8,800);
}
step_motor.h 代码
#ifndef _STEP_MOTOR_H
#define _STEP_MOTOR_H
#include "sys.h"
#include "stm32f4xx_tim.h"
#define STEPMOTOR8_DIR PCout(6)
//motor1
#define STEPMOTOR1_DIR PEout(5)
#define STEPMOTOR1_ENA PEout(6)
//motor2
#define STEPMOTOR2_DIR PEout(3)
#define STEPMOTOR2_ENA PEout(4)
//motor3
#define STEPMOTOR3_DIR PEout(2)
#define STEPMOTOR3_ENA PGout(12)
//motor4
#define STEPMOTOR4_DIR PGout(13)
#define STEPMOTOR4_ENA PGout(14)
extern u32 Toggle_Pulse[4];
extern long SUM_1;
extern long SUM_2;
extern long SUM_3;
extern long SUM_4;
extern u8 step_flag;
void step_motor_1_Init(void);
void step_motor_2_Init(void);
void step_motor_3_Init(void);
void step_motor_4_Init(void);
void TIM8_OPM_RCR_Init(u16 arr,u16 psc);
void Locate_Rle_1(long num,int dir);
void Locate_Rle_2(long num,int dir);
void Locate_Rle_3(long num,int dir);
void Locate_Rle_4(long num,int dir);
void motion(void);
void move(int n,int t);
#endif
step_motor.h 代码(极简版)
#ifndef _STEP_MOTOR_H
#define _STEP_MOTOR_H
#include "sys.h"
#include "stm32f4xx_tim.h"
#define STEPMOTOR8_DIR PCout(6)
//motor1
#define STEPMOTOR1_DIR PEout(5)
#define STEPMOTOR1_ENA PEout(6)
//motor2
#define STEPMOTOR2_DIR PEout(3)
#define STEPMOTOR2_ENA PEout(4)
//motor3
#define STEPMOTOR3_DIR PEout(2)
#define STEPMOTOR3_ENA PGout(12)
//motor4
#define STEPMOTOR4_DIR PGout(13)
#define STEPMOTOR4_ENA PGout(14)
extern long SUM_1;
extern long SUM_2;
extern long SUM_3;
extern long SUM_4;
void step_motor_1_Init(void);
void step_motor_2_Init(void);
void step_motor_3_Init(void);
void step_motor_4_Init(void);
void TIM8_OPM_RCR_Init(u16 arr,u16 psc);
void Locate_Rle_1(long num,int dir);
void Locate_Rle_2(long num,int dir);
void Locate_Rle_3(long num,int dir);
void Locate_Rle_4(long num,int dir);
#endif
说明
本文只是用来学习42步进电机,后期的功能还需要设计,结合植树机代码和极简版代码进行设计。文章来源地址https://www.toymoban.com/news/detail-437493.html
到了这里,关于STM32F4驱动42步进电机(采用驱动器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!