找回密码
 立即注册
查看: 1662|回复: 12

控制步进电机到指定的位置, 大学生毕业设计

[复制链接]

3

主题

1

回帖

13

积分

新手上路

积分
13
发表于 2024-5-18 11:51:30 来自手机 | 显示全部楼层 |阅读模式
使用STC15,IAPW4K58S4单片机,
通过输入0~99mm的距离, 控制pwm脉冲数量驱动控制步进电机到指定的位置,
请问各位大佬,这样的程序该怎么写

{:5_270:}
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:60
  • 最近打卡:2025-05-07 11:01:36

718

主题

1万

回帖

1万

积分

管理员

积分
15682
发表于 2024-5-19 08:48:37 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:527
  • 最近打卡:2025-05-07 00:40:41

10

主题

1162

回帖

5197

积分

论坛元老

积分
5197
发表于 2024-5-18 20:56:32 | 显示全部楼层
要使用STC15IAPW4K58S4单片机通过输入0~99毫米的距离控制PWM脉冲数量,驱动步进电机到指定位置,可以参考以下步骤进行程序设计:

1. 确定步进电机的参数
首先,你需要知道步进电机的参数,比如每步的角度,以及步进电机的驱动模式(全步、半步或微步)。

假设步进电机每步角度为1.8度(即200步/圈),如果每个PWM脉冲让电机前进一步,则每转一圈需要200个PWM脉冲。

2. 确定每毫米需要多少步
假设步进电机的传动机构是螺杆传动,步进电机每转一圈(200步)对应的线性移动距离为x毫米。

则每毫米所需的步数为 200 / x。

3. 编写程序
以下是一个示例程序,用来根据输入的距离值,产生相应数量的PWM脉冲:

*/
#include <STC15F2K60S2.H>

// 假设传动机构每圈移动1毫米
#define STEPS_PER_MM 200  // 200步/毫米

// 定义步进电机引脚
sbit STEP_PIN = P1^0;
sbit DIR_PIN = P1^1;

// 延时函数,模拟PWM频率
void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 110; j > 0; j--);
}

// 产生PWM脉冲
void generate_pwm_pulse(unsigned int num_pulses) {
    unsigned int i;
    for (i = 0; i < num_pulses; i++) {
        STEP_PIN = 1;
        delay(1);  // 调整延时时间以改变PWM频率
        STEP_PIN = 0;
        delay(1);
    }
}

// 输入距离控制函数
void move_stepper_to_position(unsigned int distance_mm) {
    unsigned int steps = distance_mm * STEPS_PER_MM;
    generate_pwm_pulse(steps);
}

// 主函数
void main() {
    unsigned int distance_mm = 50;  // 设定目标距离为50毫米
   
    // 配置方向引脚,假设高电平为正转,低电平为反转
    DIR_PIN = 1;
   
    // 产生PWM脉冲,驱动步进电机
    move_stepper_to_position(distance_mm);
   
    while (1);
}
/*
4. 输入处理
如果你需要根据输入(比如通过键盘或串口输入)来控制距离,可以在主函数中加入输入处理的代码。

例如,通过串口输入控制距离:

*/
#include <stdio.h>
#include <STC15F2K60S2.H>

// 假设传动机构每圈移动1毫米
#define STEPS_PER_MM 200  // 200步/毫米

// 定义步进电机引脚
sbit STEP_PIN = P1^0;
sbit DIR_PIN = P1^1;

// 串口初始化函数
void uart_init(void) {
    SCON = 0x50;  // 配置串口工作模式1
    TMOD |= 0x20;  // 配置定时器1为8位自动重装载模式
    TH1 = 0xFD;  // 波特率9600
    TR1 = 1;  // 启动定时器1
    ES = 1;  // 使能串口中断
    EA = 1;  // 使能全局中断
}

// 串口接收中断服务程序
void uart_isr(void) interrupt 4 {
    if (RI) {
        unsigned char received_data = SBUF;  // 读取接收到的数据
        RI = 0;  // 清除接收中断标志
        // 将接收到的数据转换为距离值
        unsigned int distance_mm = received_data - '0';  // 简单的字符到数字转换
        // 移动步进电机到指定位置
        move_stepper_to_position(distance_mm);
    }
}

// 延时函数,模拟PWM频率
void delay(unsigned int ms) {
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 110; j > 0; j--);
}

// 产生PWM脉冲
void generate_pwm_pulse(unsigned int num_pulses) {
    unsigned int i;
    for (i = 0; i < num_pulses; i++) {
        STEP_PIN = 1;
        delay(1);  // 调整延时时间以改变PWM频率
        STEP_PIN = 0;
        delay(1);
    }
}

// 输入距离控制函数
void move_stepper_to_position(unsigned int distance_mm) {
    unsigned int steps = distance_mm * STEPS_PER_MM;
    generate_pwm_pulse(steps);
}

// 主函数
void main() {
    uart_init();  // 初始化串口
   
    // 配置方向引脚,假设高电平为正转,低电平为反转
    DIR_PIN = 1;
   
    while (1);
}
/*
这个程序通过串口接收输入距离,然后控制步进电机移动到指定位置。根据你的具体硬件配置和需求,可以进一步调整和优化代码。



*/

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:450
  • 最近打卡:2025-05-06 04:24:11

17

主题

533

回帖

1330

积分

金牌会员

积分
1330
发表于 2024-5-18 22:57:39 | 显示全部楼层
angm*** 发表于 2024-5-18 20:56
要使用STC15IAPW4K58S4单片机通过输入0~99毫米的距离控制PWM脉冲数量,驱动步进电机到指定位置,可以参考以 ...

佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线?

点评

直接控制话,你做自己做H桥,然后PWM驱动,要求不高可以不细分,直接按照三相六拍(三相) 两相四拍(两相)去开启管子 本坛子里有梁工写的步进电机驱动,搜一下,可以参考,简单的方式就是购置独立的驱动器,你只负责方向,脉冲  详情 回复 发表于 2024-5-19 01:55
自信就会温和,温和就会坚定!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:340
  • 最近打卡:2025-05-06 19:09:22
已绑定手机

14

主题

600

回帖

2215

积分

荣誉版主

积分
2215
发表于 2024-5-19 01:55:27 | 显示全部楼层
本帖最后由 xiangzichen 于 2024-5-19 01:56 编辑
嵌入*** 发表于 2024-5-18 22:57
佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线?

直接控制话,你要自己外接mos管,做H桥,然后PWM驱动
要求不高可以不细分,直接按照三相六拍(三相) 两相四拍(两相)去开启管子
不过简单的方式就是购置独立的驱动器,你只负责方向,脉冲就好了

本坛子里梁工写的步进电机驱动可以参考:
51开源 STC步进电机驱动 程序, 直接驱动, 或驱动步进电机驱动器 一共8个程序
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=2160
(出处: 国芯技术交流网站)

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:527
  • 最近打卡:2025-05-07 00:40:41

10

主题

1162

回帖

5197

积分

论坛元老

积分
5197
发表于 2024-5-19 08:19:04 | 显示全部楼层
嵌入*** 发表于 2024-5-18 22:57
佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线?

简单一点,可以用这种接法。

StepMotorDrive.png



回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:524
  • 最近打卡:2025-05-07 07:52:10
已绑定手机

46

主题

1724

回帖

2674

积分

金牌会员

积分
2674
发表于 2024-5-19 08:22:39 | 显示全部楼层
一般外接驱动器,单片机负责发脉冲就行
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:450
  • 最近打卡:2025-05-06 04:24:11

17

主题

533

回帖

1330

积分

金牌会员

积分
1330
发表于 2024-5-19 19:22:50 | 显示全部楼层
angm*** 发表于 2024-5-19 08:19
简单一点,可以用这种接法。

我明白了大佬, 这个还是偏硬件 很多我都看不懂。 我去看看模电吧
自信就会温和,温和就会坚定!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-06-30 21:44:42

0

主题

3

回帖

58

积分

注册会员

积分
58
发表于 2024-6-19 20:35:52 来自手机 | 显示全部楼层
angmall 发表于 2024-5-18 20:56
要使用STC15IAPW4K58S4单片机通过输入0~99毫米的距离控制PWM脉冲数量,驱动步进电机到指定位置,可以参考以 ...

#include <STC8A8K64D4.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 假设传动机构每圈移动1毫米
#define STEPS_PER_MM 216// 200步/毫米

// 定义步进电机引脚
sbit STEP = P2^6;
sbit DIR = P2^7;

void Delay1ms(void)        //@24.000MHz
{
        unsigned char data i, j;

        _nop_();
        i = 32;
        j = 40;
        do
        {
                while (--j);
        } while (--i);
}



// 产生PWM脉冲
void generate_pwm_pulse(uint num_pulses)
{
         uint i;
        for (i = 0; i < num_pulses; i++)
{
        STEP = 1;
        Delay1ms();// 调整延时时间以改变PWM频率
        STEP = 0;
        Delay1ms();
}
}
// 输入距离控制函数
void move_stepper_to_position(uint distance_mm)
{
        uint steps = distance_mm * STEPS_PER_MM;
// 产生PWM脉冲
        generate_pwm_pulse(steps);
}

// 主函数
void main()
{
         uint distance_mm = 1;// 设定目标距离为1毫米
             P2M0 |= 0xc0;
                 P2M1 &= ~0xc0;

         // 配置方向引脚,假设高电平为正转,低电平为反转
         DIR = 0;
       
         // 产生PWM脉冲,驱动步进电机
         move_stepper_to_position(distance_mm);

while (1);
}
请教大佬 这个200步 转不了一圈 需要215/218
左右 因为没有刻度盘 每次复位 转动的位置都有细微偏差  这问题具体出在哪里
驱动细分也检查了 200脉冲一圈
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:527
  • 最近打卡:2025-05-07 00:40:41

10

主题

1162

回帖

5197

积分

论坛元老

积分
5197
发表于 2024-6-20 08:33:59 | 显示全部楼层
本帖最后由 angmall 于 2024-6-20 08:37 编辑
五五*** 发表于 2024-6-19 20:35
#include
#include
#define uchar unsigned char

在使用步进电机控制时,如果你已经确认步进电机的步数是200步每转,并且驱动器也设置正确,那么问题可能出在以下几个方面:


1. **步进电机的细分设置**:即使你已经检查了驱动器的细分设置,确保它确实被正确配置为200步每转(全步模式)。不同的驱动器有不同的配置方法,确保设置正确。


2. **机械结构误差**:在实际应用中,传动机构和机械结构可能会引入一些误差。即使步进电机步数和驱动器设置正确,机械传动部分的误差也会影响最终位置。


3. **电机和驱动器的兼容性**:确保步进电机和驱动器的规格和设置是匹配的。如果电机和驱动器不兼容,可能会导致控制精度的问题。


4. **电源电压和电流设置**:确保给步进电机和驱动器提供合适的电源电压和电流。电源不足或者电流设置不当会导致步进电机的转动不稳定。


下面是一些调试和改进的建议:


### 调试步骤


1. **检查驱动器细分设置**:
   - 确保驱动器细分设置正确,按照手册检查并配置为全步模式(200步每转)。


2. **确认步进电机参数**:
   - 确认步进电机的步数为200步每转。


3. **机械结构检查**:
   - 检查传动机构是否有松动或者磨损,确保机械传动部分的精度。


4. **电源和电流设置**:
   - 确保电源电压和电流符合步进电机和驱动器的要求。


### 代码调整


如果确认硬件没有问题,试着在软件中做一些微调。比如,在生成PWM脉冲时,可以增加一个微调延时来校正细微的偏差:


  1. #include <STC8A8K64D4.H>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. // 假设传动机构每圈移动1毫米
  6. #define STEPS_PER_MM 216 // 尝试调整这个值,找到合适的步数
  7. // 定义步进电机引脚
  8. sbit STEP = P2^6;
  9. sbit DIR = P2^7;
  10. void Delay1ms(void)        //@24.000MHz
  11. {
  12.         unsigned char data i, j;
  13.         _nop_();
  14.         i = 32;
  15.         j = 40;
  16.         do
  17.         {
  18.                 while (--j);
  19.         } while (--i);
  20. }
  21. // 产生PWM脉冲
  22. void generate_pwm_pulse(uint num_pulses)
  23. {
  24.          uint i;
  25.         for (i = 0; i < num_pulses; i++)
  26. {
  27.         STEP = 1;
  28.         Delay1ms(); // 调整延时时间以改变PWM频率
  29.         STEP = 0;
  30.         Delay1ms();
  31. }
  32. }
  33. // 输入距离控制函数
  34. void move_stepper_to_position(uint distance_mm)
  35. {
  36.         uint steps = distance_mm * STEPS_PER_MM;
  37.         // 产生PWM脉冲
  38.         generate_pwm_pulse(steps);
  39. }
  40. // 主函数
  41. void main()
  42. {
  43.          uint distance_mm = 1; // 设定目标距离为1毫米
  44.          P2M0 |= 0xc0;
  45.          P2M1 &= ~0xc0;
  46.          // 配置方向引脚,假设高电平为正转,低电平为反转
  47.          DIR = 0;
  48.       
  49.          // 产生PWM脉冲,驱动步进电机
  50.          move_stepper_to_position(distance_mm);
  51.          while (1);
  52. }
复制代码

在上述代码中,可以尝试调整`STEPS_PER_MM`的值以找到一个适合你机械系统的值。此外,确保每次复位后,机械位置都尽量一致。如果可能,可以增加一个位置传感器来辅助校正初始位置。




回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-7 12:28 , Processed in 0.153964 second(s), 129 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表