控制步进电机到指定的位置, 大学生毕业设计
使用STC15,IAPW4K58S4单片机,通过输入0~99mm的距离, 控制pwm脉冲数量驱动控制步进电机到指定的位置,
请问各位大佬,这样的程序该怎么写
{:5_270:}
步进电机控制,您跟指导老师打个招呼,
改成 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)
要使用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);
}
/*
这个程序通过串口接收输入距离,然后控制步进电机移动到指定位置。根据你的具体硬件配置和需求,可以进一步调整和优化代码。
*/
angmall 发表于 2024-5-18 20:56
要使用STC15IAPW4K58S4单片机通过输入0~99毫米的距离控制PWM脉冲数量,驱动步进电机到指定位置,可以参考以 ...
佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线? 本帖最后由 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
(出处: 国芯技术交流网站)
嵌入式之路 发表于 2024-5-18 22:57
佬,我有个问题, 像 5v单片机驱动大功率电机的时候, 这个该怎么接线?
简单一点,可以用这种接法。
一般外接驱动器,单片机负责发脉冲就行 angmall 发表于 2024-5-19 08:19
简单一点,可以用这种接法。
我明白了大佬, 这个还是偏硬件 很多我都看不懂。 我去看看模电吧 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: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