pluto555 发表于 2024-5-18 11:51:30

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

使用STC15,IAPW4K58S4单片机,
通过输入0~99mm的距离, 控制pwm脉冲数量驱动控制步进电机到指定的位置,
请问各位大佬,这样的程序该怎么写
{:5_270:}

神农鼎 发表于 2024-5-19 08:48:37

步进电机控制,您跟指导老师打个招呼,
改成 STC8H8K64U, STC32G12K128 这样技术支持多


【新提醒】步进电机的相对位置&绝对位置控制, STC32G PWM加减速脉冲输出控制 - BLDC/144MHz-PWM-硬件移相/45路PWM+3路CCP/7组不同周期的PWM/DAC 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)




【新提醒】51开源 STC步进电机驱动 程序, 直接驱动, 或驱动步进电机驱动器 一共8个程序 - BLDC/144MHz-PWM-硬件移相/45路PWM+3路CCP/7组不同周期的PWM/DAC 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)


STC15W4K系列的 PWM 和 STC8G2K64S4的PWM高度相似

【新提醒】STC8G2K 两相步进电机, 增强型15位PWM实现SPWM细分驱动 - BLDC/144MHz-PWM-硬件移相/45路PWM+3路CCP/7组不同周期的PWM/DAC 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)


angmall 发表于 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);
}
/*
这个程序通过串口接收输入距离,然后控制步进电机移动到指定位置。根据你的具体硬件配置和需求,可以进一步调整和优化代码。



*/

嵌入式之路 发表于 2024-5-18 22:57:39

angmall 发表于 2024-5-18 20:56
要使用STC15IAPW4K58S4单片机通过输入0~99毫米的距离控制PWM脉冲数量,驱动步进电机到指定位置,可以参考以 ...

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

xiangzichen 发表于 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
(出处: 国芯技术交流网站)

angmall 发表于 2024-5-19 08:19:04

嵌入式之路 发表于 2024-5-18 22:57
佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线?

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





jwd 发表于 2024-5-19 08:22:39

一般外接驱动器,单片机负责发脉冲就行

嵌入式之路 发表于 2024-5-19 19:22:50

angmall 发表于 2024-5-19 08:19
简单一点,可以用这种接法。

我明白了大佬, 这个还是偏硬件 很多我都看不懂。 我去看看模电吧

五五开卡殿 发表于 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脉冲一圈

angmall 发表于 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脉冲时,可以增加一个微调延时来校正细微的偏差:



#include <STC8A8K64D4.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 假设传动机构每圈移动1毫米
#define STEPS_PER_MM 216 // 尝试调整这个值,找到合适的步数

// 定义步进电机引脚
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);
}

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




页: [1] 2
查看完整版本: 控制步进电机到指定的位置, 大学生毕业设计