正点原子学习小组
直播中

yinwuqing

11年用户 2364经验值
擅长:MEMS/传感技术,嵌入式技术,接口/总线/驱动
私信 关注
[经验]

【正点原子STM32精英V2开发板体验】简易驱动四线两相步进电机

步进电机在我们日常生活应用比较常见,比如打印机,数码相机,电梯,传送带,机器手臂等产品上,都可以看到步进电机的身影。
步进电机是一种无刷机电设备,它将施加在其励磁绕组上的电脉冲序列转换为精确定义的逐步机械轴旋转。对于每个离散脉冲,电机的轴旋转一个固定的角度。这种旋转可以是线性的或角度的。对于单个脉冲输入,它会移动一步。当施加一系列脉冲时,它会转动一定角度。每个脉冲步进电机轴转过的角度称为步距角,通常以度数表示。
今天我们在精英板上简单驱动一下一款常见的42步进电机。由于上述特性,驱动42步进电机需要使用电机驱动器,这里笔者采用“TB5128FTG两相步进驱动器”,如下图所示:
电机驱动器.png

连接该款驱动器有两种接法,用户可根据需要采用共阳极接法或共阴极接法。
接线方式.png

常见的步进电机接线如下图所示:
常见电机接线示意图.png

这里采用共阴极接法,借助正点原子提供PWM参考例程,加入按键控制功能,进而实现控制42步进电机的转速,LED与按键电路原理图:
原理图.png

参考部分代码:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/TIMER/gtim.h"

extern TIM_HandleTypeDef g_timx_pwm_chy_handle;     /* 定时器x句柄 */
int main(void)
{
    uint16_t i = 300; 
    uint8_t key;
    
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    delay_init(72);                         /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    key_init();                             /* 初始化按键 */
    gtim_timx_pwm_chy_init(2000 - 1, 72 - 1);/* 1Mhz的计数频率,2Khz的PWM. */

    while (1)
    {
       key = key_scan(0);              			
       if (key)
        {
	    if(i>3000) i=10;
            switch (key)
            {
                case KEY1_PRES:             
		DIR_TOGGLE();
		delay_ms(10);		       
           __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, i);
		break;
                case KEY0_PRES:             											                                       
                i=i+200;		
		HAL_TIM_PWM_Stop(&g_timx_pwm_chy_handle, TIM_CHANNEL_2);//停止PWM										             
                gtim_timx_pwm_chy_init(i, 72 - 1);
           __HAL_TIM_SET_COMPARE(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY, i);
		break;
	     } 
	}
    }
}
void key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    KEY0_GPIO_CLK_ENABLE();                                     /* KEY0时钟使能 */
    KEY1_GPIO_CLK_ENABLE();                                     /* KEY1时钟使能 */

    gpio_init_struct.Pin = KEY0_GPIO_PIN;                       /* KEY0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct);           /* KEY0引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY1_GPIO_PIN;                       /* KEY1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct);           /* KEY1引脚模式设置,上拉输入 */
}

uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1;  /* 按键按松开标志 */
    uint8_t keyval = 0;

    if (mode) key_up = 1;       /* 支持连按 */
    if (key_up && (KEY0 == 0 || KEY1 == 0 ))  /* 按键松开标志为1, 且有任意一个按键按下了 */
    {
        delay_ms(10);           /* 去抖动 */
        key_up = 0;

        if (KEY0 == 0)  keyval = KEY0_PRES;
        if (KEY1 == 0)  keyval = KEY1_PRES;
    }
    else if (KEY0 == 1 && KEY1 == 1) /* 没有任何按键按下, 标记按键松开 */
    {
        key_up = 1;
    }
    return keyval;              /* 返回键值 */
}

将工程编译完成后,下载到精英板上验证其效果展示如下视频所示,此次评测到此结束,后续有时间再完善控制代码啦,如有建议欢迎回复,非常感谢。

电机控制

更多回帖

发帖
×
20
完善资料,
赚取积分