STM32驱动步进电机

2019-03-18来源: eefocus关键字:STM32  驱动步进电机

步进电机是将电脉冲信号转变为角位移或线位移,可以通过控制脉冲来控制,因此比一般的电机更精准。这篇文章将会讲述我对四线两项步进电机的调试经验。


1.步进电机以及THB7128的接线

THB7128步进电机驱动有两个接线口,J4口与stm32的IO口相接,J2口与步进电机和电源相接。


J2口有6个端子,从两个端口旁的接口定义可以看出,接口分别为B-,B+,A-,A+,V-,V+。其中V+与9~32V的电源相接,V-接电源地,其余的接口B+,B-一组,A+,A-一组与步进电机的两组同相线相接(注:想要判断步进电机哪两根线同相,只需用万用表测量,短接的即为同相)。


J4口同样可以从端口定义看出,分别有CP+,CP-,DIR+,DIR-,EN+,EN-6个端子。CP为脉冲信号输入端,DIR为电机正反转控制端,EN为电机脱机控制端。在J4端口有共阳极和共阴极两种接线方法。 


共阳极接法:分别将CP+,DIR+,EN+连接到STM32板子的输出电压上,脉冲输入信号通过CP-接入;此时,DIR,EN-在低电平有效。 


共阴极接法:分别将CP-,DIR-,EN-连接到控制系统的地端(与电源地隔离);此时脉冲输入信号通过CP+加入,U/D+,EN+在高电平有效。 


(注:我采用的是共阴极接法,所以之后只介绍共阴极的程序) 


J4端口共阴极接线


2. THB7128设置

TBH7128有6个拨盘开关(S1~S6),前3个开关控制细分设置,即控制电机每一步转动多少度,步距角=电机固有步距角/细分数。后三个S3~S6设置电流大小,设置的电流不要超过电机的额定电流。具体如何设置根据自己实际情况参考驱动芯片背后的说明表进行调节。说明表所示: 


Microstep-Set 
Current-Set


3.程序设计

(1)使步进电机稳定转动 

驱动接收到一个脉冲步进电机就动一步,所以我们可以用定时器中断将脉冲按一定的频率从STM32的IO口输入到驱动中,这样就可以使步进电机稳定转动起来 

(2)步进电机的开启、截止以及变向 

当THB7128使能端EN+接收到高电平时步进电机停止运转,接收到低电平时正常运转。因此改变与EN+相接的IO口的电平高低就可以控制电机的开启与截止。 

当正反控制端DIR+接收到高电平时步进电机改变转动方向,改变相应的IO口电平即可让步进电机变向。 

(3)步进电机变速 

我用的定时器中断来驱动电机转动,所以只要想办法改变定时器中断的参数就可以让电机改变速度


具体程序如下:


①定时器设置及IO口初始化


#include "dianji.h"

#include "led.h"


void TIM3_Int_Init(u16 arr,u16 psc)

{

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能


    //定时器TIM3初始化

    TIM_TimeBaseStructure.TIM_Period = arr;//自动重装载寄存器周期的值

    TIM_TimeBaseStructure.TIM_Prescaler = psc;//预分频值

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分割

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //使能指定的TIM3中断,允许更新中断


    //中断优先级NVIC设置

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//TIM3中断

    NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; 

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应优先级

    NVIC_Init(&NVIC_InitStructure);


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

}


void TIM3_IRQHandler(void)//TIM3中断函数

{

    if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)//检查TIM3更新中断发生与否

    {

        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除TIMx更新中断标志

        LED0=!LED0;

    }

}



void DJ_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStruct;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);//使能GPIOG


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_4;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB,&GPIO_InitStruct);

    GPIO_SetBits(GPIOB,GPIO_Pin_6);


    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOG,&GPIO_InitStruct);

    GPIO_SetBits(GPIOG,GPIO_Pin_9); 

}


②主函数(具体操作控制)


#include "stm32f10x.h"

#include "usart.h"

#include "led.h"

#include "delay.h"

#include "sys.h"

#include "timer.h"

#include "key.h"

#include "dianji.h"


#define up 1 

#define down 0



int main(void)

{

    vu8 key = 0;

    vu8 key1 = 0;

    vu8 num0 = 0;

    vu8 num1 = 0;

    vu8 num2 = 0;

    vu8 speed = 1;

    vu16 arrLowest = 189;

    vu16  arrMax= 409;

    vu16 arr =299;

    vu16 psc = 359;

    LED_Init();

    delay_init();

    KEY_Init();

    DJ_Init();

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    uart_init(115200);   //串口初始化为115200


    TIM3_Int_Init(arr,psc);//10Khz的计数频率,计数到100为10ms (arr+1)*(psc+1)/72  

    while(1)

    {   

        key = KEY_Scan(0);

        if(key == KEY0_PRES)

        {

            if(num0 == 0)

            {

                num0 = 1;

                LED1=0;

                GPIO_ResetBits(GPIOB,GPIO_Pin_6);

            }

            else

            {

                num0 = 0;

                LED1=1;

                GPIO_SetBits(GPIOB,GPIO_Pin_6);

            }

        }           

        if(key == KEY1_PRES)

        {

            if(num2 == 0)

            {

                GPIO_SetBits(GPIOG,GPIO_Pin_9);

                num2 = 1;

            }

            else

            {

                GPIO_ResetBits(GPIOG,GPIO_Pin_9);

                num2 = 0;

            }

        }

        while(key == WKUP_PRES)

        {                       

            if(speed == down)

            {               

                arr+=2;

                TIM3_Int_Init(arr,psc);                 

                delay_ms(50);

                key1 = KEY_Scan(0);

                if(arr > arrMax)

                {

                    speed = up;

                }

                if(key1 == WKUP_PRES)//关闭变速

                {

                    LED1 = 0;

                    key = 0;

                }

            }

            if(speed == up)

            {                   

                arr-=2;             

                TIM3_Int_Init(arr,psc);                 

                delay_ms(50);

                if(arr < arrLowest)

                {   

                    speed = down;

                }

                key1 = KEY_Scan(0);

                if(key1 == WKUP_PRES)

                {

                    LED1 = 0;

                    key = 0;

                }   

            }

        }       

    }

}


4.总结

通过以上过程的调试,我实现了用按键控制步进电机的启动、截止、变向以及加减速这些功能。 

可能我的电机驱动和大家的不一样, 希望能让读者起到参考作用。

关键字:STM32  驱动步进电机 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/2019/ic-news031843529.html

上一篇:STM32之SystemInit()函数的探讨
下一篇:CanFestival移植到STM32F103

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32项目(三)——通用LIN控制器
需求:LIN马达控制器:AFS(DHL+AFL)——弯道辅助照明系统DHL:上极限,下极限,零位,马达老化循环;AFL:左极限,右极限,零位,马达老化循环;所有参数可配置:上极限,下极限,零位,左极限,右极限,马达循环上极限,马达循环下极限,马达循环次数,马达循环等待时间;保存至少30款产品的配置,配置界面需要有添加,读取,查找,删除功能。方案:STM32 + LIN + 串口(使用NXP的串口屏,TJA系列的LIN芯片)STM32的LIN接口作为主节点,马达作为从节点。系统设计:RTX多任务设计,串口处理任务,显示屏处理任务,LIN发送任务;(1)、串口处理任务:点击串口屏会获取到点击的坐标值,串口中断接受到数据加入到队列;任务
发表于 2020-12-09
STM32项目(二) —— 车灯测试台架
需求:(1)、点灯控制器:在线节拍,离线节拍;(2)、PWM控制盒:在线PWM,离线PWM;(3)、电流测试模块:检测车灯电流校准系数;方案:点灯控制器:STM32 + CAN + GPIO节拍:比如亮多长时间,灭多长时间;大节拍中嵌套多个小节拍,每个灯对应相同或者不同的节拍。上位机下发控制指令,表明此时是在线还是离线。(离线跑的节拍是在在线模式下下载的)在线模式:如果是直接输出,按照指定格式下发CAN消息,MCU接受消息并解析,切继电器点灯;如果是存储节拍,MCU内部Flash存储上位机通过CAN下发的点灯节拍。离线模式:从内部Flash中读取节拍,并控制继电器点灯;模式切换按钮:不仅可以通过上位机控制在线/离线模式,还可
发表于 2020-12-09
STM32项目(一) —— 展示车座椅
功能:模拟人开车时,ACR和ABL的变化。 主控制器:STM32(CAN,串口,网口,输入,输出)上位机:LibView ACR:卷收器(座椅上面的安全带)ABL:电机(座椅右下角接安全带的插孔)PUMA:控制器发送CAN给PUMA,PUMA控制ACR和ABL(DBC文件的解析);ACR通过CAN控制,ABL通过PWM控制电机。 STM32硬件接口:按键盒8路输入,网口与工控机软件通信,CAN1直接控制ACR,CAN2给PUMA信号控制ACR,串口与上位机软件通信(控制方向盘震动)。 主要有两块功能:静态模式和游戏模式。 静态模式:UC-WinRoad没工作时,STM32检测
发表于 2020-12-09
STM32——GPIO(2)
, GPIO_InitTypeDef* GPIO_InitStruct){  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;  uint32_t tmpreg = 0x00, pinmask = 0x00;  /* 断言,用于检查输入的参数是否正确 */  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));  assert
发表于 2020-12-09
Octonion全新AI工业状态监测扩展软件包可在STM32 MCU完美运行
专业开发工业设备诊断边缘人工智能(AI)的深度技术软件公司Octonion 发布了一个STM32Cube扩展软件包。该软件包是针对来自横跨多重电子应用领域的全球领先的半导体供应商意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)的工业级STM32L4 +微控制器开发板的优化过的状态监测解决方案。 Octonions的新软件包支持意法半导体在快速增长的工业状态监测和预测性维护市场上发起的使用STM32微控制器和微处理器开发人工智能应用的市场活动。Octonion的I-CUBE-OCTMI 软件包是一个运行在STM32 超低功耗MCU上的自我维护系统,系统
发表于 2020-12-09
STM32——流水灯
stm32f10x_conf.h:打开stm32f10x_gpio.h和stm32f10x_rcc.h;stm32f10x_gpio.c 和 stm32f10x_rcc.c加入工程模板中,只说重点。【stm32f10x_rcc.c用于配置系统时钟 和外设时钟,由于每个外设都要配置时钟,所以它是每个外设都需要用到的库文件。】// 新建led.h  led.c#ifndef  _LED_H_#define  _LED_H_ #include "stm32f10x.h" #define ON  0#define OFF 1 #define LED1
发表于 2020-12-08
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved