ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【开源-Proteus8.9仿真】基于51单片机的四相步进电机控制(ULN2003 + StepMotor + LCD1602) - 少年

2026/8/9 1:24:50 拓冰建站 浏览量
【开源-Proteus8.9仿真】基于51单片机的四相步进电机控制(ULN2003 + StepMotor + LCD1602) - 少年

项目开源链接以及作者信息

参数
VX公众号 少年潜行(可关注回复 A003步进电机 在对应文中获得网盘链接免费开源
Proteus8.9 链接:https://pan.baidu.com/s/1kkgFmRBlh268m_ESl83weg 提取码:9bde 复制这段内容后打开百度网盘手机App,操作更方便哦

📖 欢迎交流 如果对你有帮助,希望可以帮我点个赞👍和收藏,谢谢

📖 有问题请于公众号后台回复,博客不常查看

V1.1 (2025_07_05更新)

更新内容

1、在V1.0基础上优化了LCD显示延时,使得LCD的显示更加迅速。
2、如果有问题,大家可以继续提出。大家就不要去下资源绑定里面的内容了,那个不能实时更新。

LCD显示优化

在实际仿真使用的时候LCD刷新会比较慢,使用实物的时候可以用原来的代码,仿真的时候可以把延时注释了,使用下面的函数,开头要加个1ms的延时,因为没有忙检测。

void LcdWriteCom(uint8_t com)	  //写入命令
{Lcd1602_Delay1ms(1);LCD1602_E = 0;     //使能LCD1602_RS = 0;	   //选择发送命令LCD1602_RW = 0;	   //选择写入LCD1602_DATAPINS = com;     //放入命令
//	Lcd1602_Delay1ms(1);		//等待数据稳定LCD1602_E = 1;	          //写入时序
//	Lcd1602_Delay1ms(5);	  //保持时间LCD1602_E = 0;
}void LcdWriteData(uint8_t dat)			//写入数据
{Lcd1602_Delay1ms(1);LCD1602_E = 0;	//使能清零LCD1602_RS = 1;	//选择输入数据LCD1602_RW = 0;	//选择写入LCD1602_DATAPINS = dat; //写入数据
//	Lcd1602_Delay1ms(1);LCD1602_E = 1;   //写入时序
//	Lcd1602_Delay1ms(5);   //保持时间LCD1602_E = 0;
}	

V1.0 基础内容

项目说明

该设计是一个简易的基于51单片机的四相步进电机控制系统,功能说明:

  1. 使用LCD1602实时显示当前的步进电机的转动方式。
  2. 可以通过按键调节步进电机的转动1步进的时间,可以调节正转和反转的。

硬件设计

image

硬件设计如图,主要使用LCD屏幕展示电机正反转的模式以及步进一步的毫秒数。可以使用按键控制是正转还是反转,可以控制步进一次的时间。

软件设计

按键的扫描在while中实现,界面显示放置在while循环中,使用的晶振是12MHz。使用定时器定时了1ms的时间,然后在定时器中确定每次步进需要的时间,计数值到了后再清零。

#include "reg52.h"
#include "step_motor.h"
#include "bsp_key.h"
#include "LCD1602.h"
#include "stdio.h"void Timer0_Init(void);u8  MotorRunMode = STOP;
int StepMs       = 100;int main()
{u8 keyValue = 0;u8 lcdShowBuff[16] = {0};EA = 0;   // 失能全部中断Timer0_Init();KeyInit();LcdInit();sprintf((char*)lcdShowBuff,"Mode : STOP  ");LcdShowStr(0,0,lcdShowBuff);sprintf((char*)lcdShowBuff,"StepMs : %4d  ",StepMs);LcdShowStr(0,1,lcdShowBuff);EA = 1;   // 使能全部中断while (1){keyValue = KeyScan(0);if( keyValue == 1 ){MotorRunMode = CW;sprintf((char*)lcdShowBuff,"Mode : CW  ");LcdShowStr(0,0,lcdShowBuff);}else if( keyValue == 2 ){MotorRunMode = CCW;sprintf((char*)lcdShowBuff,"Mode : CCW ");LcdShowStr(0,0,lcdShowBuff);}else if( keyValue == 3 ){StepMs += 100;if(StepMs > 1000)StepMs = 1000;sprintf((char*)lcdShowBuff,"StepMs : %4d  ",StepMs);LcdShowStr(0,1,lcdShowBuff);}else if( keyValue == 4 ){StepMs -= 100;if(StepMs < 0)StepMs = 0;sprintf((char*)lcdShowBuff,"StepMs : %4d  ",StepMs);LcdShowStr(0,1,lcdShowBuff);}	}
}void Timer0_Init(void)		//1毫秒@12.000MHz
{TMOD &= 0xF0;			//设置定时器模式TMOD |= 0x01;			//设置定时器模式TL0 = 0x18;				//设置定时初始值TH0 = 0xFC;				//设置定时初始值TF0 = 0;				//清除TF0标志TR0 = 1;				//定时器0开始计时ET0 = 1;                //使能定时器0
}// 1ms定时器中断
void Timer0() interrupt 1
{static int counts = 0;TL0 = 0x18; //设置定时0初始值TH0 = 0xFC; //设置定时0初始值counts++;if (counts > StepMs) // 定时大于指定MS数的时候,运动一步进{MotorTurn(MotorRunMode);counts = 0;}
}

调试效果

1、显示当前的转动方式和电机转动

image

2、电机按键调节转动速度

image