📄 main.c
字号:
//步进电机驱动测试程序,用于测试步进电机每相最短时间和最长时间,单位毫秒
//硬件环境:Atmel 89C2051 晶振频率 7.3728MHz
//硬件系统描述: 步进电机采用TOSHIBA 的 ULN2803A驱动,
// 步进电机 1 -- 电源
// 2 -- 1相 -- ULN2803 14脚 -- 5脚 -- 2051 19脚 P1.7
// 3 -- 2相 -- ULN2803 13脚 -- 6脚 -- 2051 18脚 P1.6
// 4 -- 3相 -- ULN2803 12脚 -- 7脚 -- 2051 17脚 P1.5
// 5 -- 4相 -- ULN2803 11脚 -- 8脚 -- 2051 16脚 P1.4
// 按键: 2051 6脚 P3.2 INT0 -- 增加步长 UP_KEY
// 2051 7脚 P3.3 INT1 -- 减小步长 DOWN_KEY
// 2051 9脚 P3.5 -- 改变电机旋转方向 DIR_KEY
//设计描述: 定时器0产生驱动电机的脉冲,宽度可以通过2个按键以SETP_LEN为步长改变,电机旋转方向可按DIR_KEY来切换.
// 步进电机分8拍,每相高电平占3拍,低电平占5拍;
// 步进电机8个状态依次为(P1.7 -- P1.4): 1001(0x90) --> 1000(0x80) --> 1100(0xc0) --> 0100(0x40) --> 0110(0x60) --> 0010(0x20) --> 0011(0x30) --> 0001(0x10)
// 以上8个状态应取反,取反后依次为: 0110(0x60) --> 0111(0x70) --> 0011(0x30) --> 1011(0xb0) --> 1001(0x90) --> 1101(0xd0) --> 1100(0xc0) --> 1110(0xe0)
// 单4拍: 1000(0x80) --> 0100(0x40) --> 0010(0x20) --> 0001(0x10)
// 双4拍: 1001(0x90) --> 1100(0xc0) --> 0110(0x60) --> 0011(0x30)
//测试结论:8拍,每拍时长最低3ms,低于3ms电机无法旋转.
// 双4拍,每拍时长最低2ms,低于2ms电机无法旋转.
// 单4拍,每拍时长最低3ms,低于3ms电机旋转不稳定,2ms有时能转,但不稳定.
#include <reg52.h> //包括一个52标准内核的头文件
#define STEP_LEN 1 //步进电机驱动脉冲改变步长
#define MIN_STEP 3 //最小拍长
#define STEP_NUM 4 //拍数
#define TIMER_TIME 1 //定时器中断时间,取值范围为1,10,100ms
#define uchar unsigned char //定义一下方便使用
#define uint unsigned int
#define ulong unsigned long
#define MOTOR_PORT P1
sbit Phase1 = P1^7; //步进电机1相
sbit Phase2 = P1^6; //步进电机2相
sbit Phase3 = P1^5; //步进电机3相
sbit Phase4 = P1^4; //步进电机4相
sbit DirKey = P3^5; //旋转方向控制键
sbit KeyUp = P3^2; //拍长加一个步长STEP_LEN
sbit KeyDown= P3^3; //拍长减一个步长STEP_LEN
uchar CurrStatus = 0; //步进电机当前状态,共STEP_NUM个,0 -- STEP_NUM-1
//uchar MotorStatus[STEP_NUM] = {0x60,0x70,0x30,0xb0,0x90,0xd0,0xc0,0xe0}; //8拍
//uchar MotorStatus[STEP_NUM] = {0x80,0x40,0x20,0x10}; //单4拍
uchar MotorStatus[STEP_NUM] = {0x90,0xc0,0x60,0x30}; //双4拍
uchar phase_width = MIN_STEP;//每拍脉冲宽度
uchar dir = 1; //电机旋转方向 1 -- 逆时针 0 -- 顺时针
unsigned int LedCount; //led亮灭计数,保证led亮灭的时间大于500ms.
sbit LED = P1^2; //定时器指示LED
uchar TimerCount = 0; //定时溢出计数器
void Delay(unsigned int utime);
void main(void) // 主程序
{
MOTOR_PORT = 0xff; //初始状态,关闭所有驱动口线
//Timer0采用模式1,即16位计数器,时钟模式,10ms中断一次
TMOD = 0x01;
#if TIMER_TIME == 1
//1ms
TH0 = 0xFD;
TL0 = 0x99;
LedCount = 500;
#endif
#if TIMER_TIME == 10
//10ms
TH0 = 0xE8;
TL0 = 0x0;
LedCount = 50;
#endif
#if TIMER_TIME == 100
//100ms
TH0 = 0x10;
TL0 = 0x0;
LedCount = 5;
#endif
EA = 1; //开中断
ET0 = 1; //T/C0中断开放
TR0 = 1; //T/C0启动定时
EX0 = 0; //外部中断0关闭
EX1 = 0; //外部中断1关闭
LED = 0; //点亮LED
while (1)
{
if (DirKey == 0)
dir = 1 - dir; //方向改变
if (KeyUp == 0)
{
Delay(1330);
if (KeyUp == 0)
if ((phase_width + STEP_LEN) <250 )
phase_width += STEP_LEN;
}
if (KeyDown == 0)
{
Delay(1330);
if (KeyDown == 0)
if ((phase_width - STEP_LEN) > MIN_STEP)
phase_width -= STEP_LEN;
}
}
}
//定时器0中断,根据pluse_width产生驱动电机的脉冲
void timer0() interrupt 1 using 1
{
//Timer0采用模式1,即16位计数器,时钟模式,10ms中断一次
#if TIMER_TIME == 1
//1ms
TH0 = 0xFD;
TL0 = 0x99;
#endif
#if TIMER_TIME == 10
//10ms
TH0 = 0xE8;
TL0 = 0x0;
#endif
#if TIMER_TIME == 100
//100ms
TH0 = 0x10;
TL0 = 0x0;
#endif
if (LedCount == 0)
{
#if TIMER_TIME == 1
//1ms
LedCount = 500;
#endif
#if TIMER_TIME == 10
//10ms
LedCount = 50;
#endif
#if TIMER_TIME == 100
//100ms
LedCount = 5;
#endif
LED = !LED; //LED取反
}
else
LedCount--;
if (++TimerCount >= phase_width)
{
TimerCount = 0;
if (CurrStatus > STEP_NUM - 1) //如果当前状态处于错误状态:不在0 -- STEP_NUM 之间,则置为初始状态:0
CurrStatus = 0;
MOTOR_PORT = (MOTOR_PORT & 0x0f) | MotorStatus[CurrStatus];
if (dir)
CurrStatus = ++CurrStatus % STEP_NUM;
else
CurrStatus = (CurrStatus == 0 ? (STEP_NUM - 1) : CurrStatus-1);
}
}
//调用一次的时间为20uS,执行一次循环的时间为15uS,精确延时的计算公式是:(15*N+20)uS 10ms:665
void Delay(unsigned int utime)
{
unsigned int t;
t = utime;
while(t--)
{};
}
/*
//外部中断int0,步进电机拍长增加一个步长值
void key_up() interrupt 0 using 2
{
// phase_width++;
if ((phase_width + STEP_LEN) <250 )
phase_width += STEP_LEN;
Delay(1330);
}
//外部中断int1,步进电机拍长减少一个步长值
void key_down() interrupt 2 using 3
{
// phase_width--;
if ((phase_width - STEP_LEN)> 3)
phase_width -= STEP_LEN;
Delay(1330);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -