326|2

240

帖子

0

TA的资源

纯净的硅(初级)

[航芯高性能MCU系列:ACM32F403开发板]2.熟悉高级定时器,实现对高精密步进电机的驱动 [复制链接]

1.硬件环境准备

    1.1.ACM32F403开发板

    1.2.高精密步进电机套装(高精密步进电机、光电旋转编码器、TB6600驱动器、限位开关等)

0.png

 

    1.3.接口板

    用于连接高精密步进电机套装与ACM32F403开发板的连接

    1.3.1.原理图

原理图.png

 

    1.3.2.接口板3D效果图

6.png

 

2.硬件环境连接

    ACM32F403开发板通过接口板与TB6600驱动器、光电旋转编码器、限位开关进行连接,将高精密步进电机与TB6600驱动器进行连接,接口板供12V电源。

3.png
5.png
4.png

 

3.TIM1定时器

高级控制定时器 TIM1 由一个 16 位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、 PWM、嵌入死区时间的互补 PWM 等)。使用定时器预分频器和系统时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器和通用定时器是完全独立的,它们不共享任何资源,但它们可以同步操作。主要特性如下:
    ⚫ 16 位向上、向下、向上/下自动装载计数器

    ⚫ 16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为 1~65536 之间的任意数值

    ⚫ 多达 4 个独立通道

        - 输入捕获

        - 输出比较

        - PWM 生成(边沿或中间对齐模式)

        - 单脉冲模式输出

    ⚫ 死区时间可编程的互补输出

    ⚫ 使用外部信号控制定时器和定时器互联的同步电路

    ⚫ 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器

    ⚫ 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态

    ⚫ 如下事件发生时产生中断/DMA:

        - 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

        - 触发事件: (计数器启动、停止、初始化或者由内部/外部触发计数)

        - 输入捕获

        - 输出比较

        - 刹车信号输入

    ⚫ 支持针对定位的增量(正交)编码器和霍尔传感器电路

    ⚫ 触发输入作为外部时钟或者按周期的电流管理

 

4.实现功能

    通过TIM1的通道1输出PWM作为TB6600驱动器的脉冲输入信号,控制电机转速;通过PC9控制TB6600的DIR输入,控制电机的转向;通过PC10和PC11作为限位开关的输入,当触发限位开关后,立即切换电机的运转方向。

 

5.程序实现

5.1.高精密电机驱动程序

#include "bsp_motor.h"

void bsp_MotorInitGPIO(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    System_Module_Enable(EN_GPIOCD);

    /* Direction */
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.Pin       = GPIO_PIN_9;
    GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_WriteBit(GPIOC, GPIO_PIN_9, Bit_SET);

    /* Limit Switch */
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.Pin       = GPIO_PIN_10 | GPIO_PIN_11;
    GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull      = GPIO_PULLUP;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;
    GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void bsp_MotorInitTIM1(void)
{
    GPIO_InitTypeDef     GPIO_InitStruct;
    TIM_Base_InitTypeDef TIM_Base_InitStruct;
    TIM_OC_InitTypeDef   TIM_OC_InitStruct;
    uint32_t             TIM_Clock;

    System_Module_Enable(EN_GPIOCD);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.Pin       = GPIO_PIN_8;
    GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull      = GPIO_NOPULL;
    GPIO_InitStruct.Alternate = GPIO_FUNCTION_2;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    System_Module_Enable(EN_TIM1);

    if (System_Get_SystemClock() == System_Get_APBClock())
    {
        TIM_Clock = System_Get_APBClock();
    }
    else
    {
        TIM_Clock = System_Get_APBClock() * 2;
    }

    TIM_Base_InitStruct.Prescaler         = (TIM_Clock / 1000000) - 1;
    TIM_Base_InitStruct.Period            = 1000 - 1;
    TIM_Base_InitStruct.RepetitionCounter = 0;
    TIM_Base_InitStruct.CounterMode       = TIM_COUNTERMODE_UP;
    TIM_Base_InitStruct.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
    TIM_TimeBase_Init(TIM1, &TIM_Base_InitStruct);

    TIM_OC_InitStruct.OCMode       = OUTPUT_MODE_PWM1;
    TIM_OC_InitStruct.Pulse        = (TIM_Base_InitStruct.Period + 1) / 2;
    TIM_OC_InitStruct.OCPolarity   = OUTPUT_POL_ACTIVE_HIGH;
    TIM_OC_InitStruct.OCNPolarity  = OUTPUT_POL_ACTIVE_HIGH;
    TIM_OC_InitStruct.OCFastMode   = OUTPUT_FAST_MODE_DISABLE;
    TIM_OC_InitStruct.OCIdleState  = OUTPUT_IDLE_STATE_0;
    TIM_OC_InitStruct.OCNIdleState = OUTPUT_IDLE_STATE_0;
    TIM_OC1Init(TIM1, &TIM_OC_InitStruct);

    TIM_CCxCmd(TIM1, TIM_CHANNEL_1, TIM_CCx_Enable);

    TIM_Cmd(TIM1, ENABLE);
}

void bsp_MotorInit(void)
{
    bsp_MotorInitGPIO();

    bsp_MotorInitTIM1();

    bsp_MotorRunning();
}

void bsp_MotorRunning(void)
{
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

void bsp_MotorSuspend(void)
{
    TIM_CtrlPWMOutputs(TIM1, DISABLE);
}

void bsp_MotorSwitchDirection(void)
{
    bsp_MotorSuspend();

    if (GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_9) == RESET)
    {
        GPIO_WriteBit(GPIOC, GPIO_PIN_9, Bit_SET);
    }
    else
    {
        GPIO_WriteBit(GPIOC, GPIO_PIN_9, Bit_RESET);
    }

    bsp_MotorRunning();
}

uint8_t bsp_MotorReadLimitSwitchPinLevel(uint8_t Index)
{
    uint8_t PinLevel = 0;

    switch (Index)
    {
        case 1:
            PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_10);
            break;

        case 2:
            PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_PIN_11);
            break;

        default:
            break;
    }

    return (PinLevel);
}

 

5.2.限位开关逻辑控制程序

#include "key.h"
#include "bsp_key.h"
#include "bsp_motor.h"
#include "multi_button.h"

struct Button keyUser;
struct Button keyMotorRight;
struct Button keyMotorLeft;

volatile uint8_t KeyRegisterFlag = 0;

void KEY_UserHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    if (handle->button_id == 0)
    {
        printf("\r\n%s", __FUNCTION__);
    }
}

void KEY_MotorHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    if ((handle->button_id == 1) || (handle->button_id == 2))
    {
        bsp_MotorSwitchDirection();
    }
}

void KEY_Init(void)
{
    bsp_KeyInit();

    button_init(&keyUser, bsp_KeyReadPinLevel, RESET, 0);
    button_attach(&keyUser, PRESS_DOWN, KEY_UserHandler);
    button_start(&keyUser);

    button_init(&keyMotorRight, bsp_MotorReadLimitSwitchPinLevel, RESET, 1);
    button_attach(&keyMotorRight, PRESS_DOWN, KEY_MotorHandler);
    button_start(&keyMotorRight);

    button_init(&keyMotorLeft, bsp_MotorReadLimitSwitchPinLevel, RESET, 2);
    button_attach(&keyMotorLeft, PRESS_DOWN, KEY_MotorHandler);
    button_start(&keyMotorLeft);

    KeyRegisterFlag = 1;
}

 

6.运行效果

Motor Running

 

7.工程源码

Project.zip (1.31 MB, 下载次数: 0)

最新回复

这个运行非常平稳,有没有准备搞个加速的算法我们学习学习。   详情 回复 发表于 2025-3-11 18:03

赞赏

1

查看全部赞赏

个人签名We are a team and we work as a team !

回复
举报

7185

帖子

11

TA的资源

版主

这个运行非常平稳,有没有准备搞个加速的算法我们学习学习。

点评

有的,后面准备了……  详情 回复 发表于 2025-3-11 20:23

回复

240

帖子

0

TA的资源

纯净的硅(初级)

lugl4313820 发表于 2025-3-11 18:03 这个运行非常平稳,有没有准备搞个加速的算法我们学习学习。

有的,后面准备了……

个人签名We are a team and we work as a team !

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 13

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表