步进电机c程序

步进电机控制程序

(2008-06-05 19:07:55)

转载

标签: 分类: 程序设计

it

步进电机(键盘控制可调速)

#include

#define uchar unsigned char

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void ddelay(void); //键盘扫描延时函数

void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒

void gorun(); //步进电机控制步进函数

sbit P10=P2^0 ; //电机端口定义

sbit P11=P2^1 ;

sbit P12=P2^2;

sbit P13=P2^3 ;

void ddelay(void)

{

uchar i;

for (i=300;i>0;i--);

}

uchar keyscan(void)

{

uchar scancode;

uchar tmpcode;

P1 = 0xf8; // 发全0行扫描码

if ((P1&0xf8)!=0xf8) // 若有键按下

{

ddelay(); // 延时去抖动

if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响

{

scancode = 0xfe;

while((scancode&0x08)!=0) // 逐行扫描

{

P1 = scancode; // 输出行扫描码

if ((P1&0xf8)!=0xf8) // 本行有键按下

tmpcode = (P1&0xf8)|0x07;

return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列

}

else scancode = (scancode

}

}

}

return(0); // 无键按下,返回值为0

}

void main(void)

{

uchar key;

count = 0;

step_index = 0;

spcount = 0;

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFc;

TL0 = 0x18; //设定时每隔1ms中断一次

TR0 = 1; //开始计数

stop_flag = 0;

turn=0;

speedlevel = 20;

while(1)

{

key = keyscan();

switch(key)

{

case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn = 0;

speedlevel =10;

gorun();

delay(1000);

break;

case 0x0c: //按键*, 停止 2000*0.5MS=0.5S

stop_flag=1;

break;

case 0x0a: //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn=1;

speedlevel =10;

gorun();

delay(1000);

break;

case 0x11: // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S

stop_flag=0;

if (speedlevel==1)

{ speedlevel=1;}

else { --speedlevel;}

gorun();

delay(1000);

break;

case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S

stop_flag=0;

++speedlevel;

gorun();

delay(1000);

break;

}

}

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFc;

TL0=0x18; //设定时每隔1ms中断一次

count++;

spcount--;

if(spcount

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒

{

count=0;

do{}

while(count

void gorun()

{

if (stop_flag==1)

{

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

return;

}

switch(step_index)

{

case 0: //0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 0;

break;

case 1: //0、1

P10 = 1;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 2: //1

P10 = 0;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 3: //1、2

P10 = 0;

P11 = 1;

P12 = 1;

P13 = 0;

break;

case 4: //2

P10 = 0;

P11 = 0;

P12 = 1;

P13 = 0;

break;

case 5: //2、3

P10 = 0;

P11 = 0;

P12 = 1;

P13 = 1;

break;

case 6: //3

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 1;

break;

case 7: //3、0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 1;

}

if (turn==0) //正转

{

step_index++;

if (step_index>7)

step_index=0;

}

else

{ //反转

step_index--;

if (step_index

step_index=7;

}

}

步进电机(键盘控制可调速加显示)

#include

#define uchar unsigned char

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void ddelay(void); //键盘扫描延时函数

void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒

void gorun(); //步进电机控制步进函数

void Delay400Ms(void);

void LCMInit(void); //LCM初始化

void WriteCommandLCM(unsigned char WCLCM,BuysC); //BuysC为0时忽略忙检测 void DisplayOneChar(uchar X, uchar Y, uchar DData);

void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n);

sbit P10=P3^0 ; //电机端口定义

sbit P11=P3^1 ;

sbit P12=P3^2;

sbit P13=P3^3 ;

uchar code speed[]={ 0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30};

uchar code stop[] = {"stop"};

uchar code go[] = {"go:"};

uchar code back[] = {"back:"};

uchar code max[] = {"max:8"};

void ddelay(void)

{

uchar i;

for (i=300;i>0;i--);

}

uchar keyscan(void)

{

uchar scancode;

uchar tmpcode;

P1 = 0xf8; // 发全0行扫描码

if ((P1&0xf8)!=0xf8) // 若有键按下

{

ddelay(); // 延时去抖动

if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响

{

scancode = 0xfe;

while((scancode&0x08)!=0) // 逐行扫描

{

P1 = scancode; // 输出行扫描码

if ((P1&0xf8)!=0xf8) // 本行有键按下

{

tmpcode = (P1&0xf8)|0x07;

return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列

}

else scancode = (scancode

}

}

}

return(0); // 无键按下,返回值为0

}

void main(void)

{

uchar key;

count = 0;

step_index = 0;

spcount = 0;

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFc;

TL0 = 0x18; //设定时每隔1ms中断一次

TR0 = 1; //开始计数

P0=0XFF;

P3 &=0XEF; //573片选

LCMInit(); //LCM初始化

Delay400Ms();

stop_flag = 0;

turn=0;

speedlevel = 5;

DisplayListChar(0,0,3,go,1); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

while(1)

{

key = keyscan();

switch(key)

{

case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn = 0;

speedlevel =5;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x0c: //按键*, 停止 2000*0.5MS=0.5S

stop_flag=1;

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,4,stop,0); //每次扫描键盘显示更新一次

break;

case 0x0a: //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn=1;

speedlevel =5;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x11: // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S

stop_flag=0;

if (speedlevel==2)

{ speedlevel=2;}

else { speedlevel--;}

gorun();

if(speedlevel==2)

{ DisplayListChar(0,1,5,max,0);}

else {DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S

stop_flag=0;

speedlevel++;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

if(turn==0)

{DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次

else {DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次

DisplayOneChar(0,1,speed[speedlevel]);} //每次扫描键盘显示更新一次

delay(1000);

break;

}

}

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFc;

TL0=0x18; //设定时每隔1ms中断一次

count++;

spcount--;

if(spcount

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒

{

count=0;

do{}

while(count

}

void gorun()

{

if (stop_flag==1)

{

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

return;

}

switch(step_index)

{

case 0: //0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 0;

break;

case 1: //0、1

P10 = 1;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 2: //1

P10 = 0;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 3: //1、2 P10 = 0;

P11 = 1;

P12 = 1;

P13 = 0;

break;

case 4: //2 P10 = 0;

P11 = 0;

P12 = 1;

P13 = 0;

break;

case 5: //2、3 P10 = 0;

P11 = 0;

P12 = 1;

P13 = 1;

break;

case 6: //3

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 1;

break;

case 7: //3、0 P10 = 1;

P11 = 0;

P12 = 0;

P13 = 1;

}

if (turn==0) //正转 {

step_index++; if (step_index>7) step_index=0; }

else

{ //反转 step_index--; if (step_index

step_index=7;

}

}

步进电机(自动循环调速)

#include

sbit P00=P2^0 ;

sbit P01=P2^1 ;

sbit P02=P2^2;

sbit P03=P2^3 ;

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越快,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒

void gorun(); //步进电机控制步进函数

void main(void)

{

count = 0;

step_index = 0;

spcount = 0;

stop_flag = 0;

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFE;

TL0 = 0x0C; //设定时每隔0.5ms中断一次

TR0 = 1; //开始计数

turn = 0;

do{

speedlevel =4;

delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1S

speedlevel =4;

delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1S

stop_flag=1;

delay(6000);//停止,2000*0.5MS=3S

stop_flag=0;

}while(1);

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFE;

TL0=0x0C; //设定时每隔0.5ms中断一次

count++;

spcount--;

if(spcount

{

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)

{

count=0;

do{}while(count

}

void gorun()

{

if (stop_flag==1)

{

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 0;

return;

}

switch(step_index)

{

case 0: //0

P00 = 1;

P01 = 0;

P02 = 0;

P03 = 0;

break;

case 1: //0、1

P00 = 1;

P01 = 1;

P02 = 0;

P03 = 0;

break;

case 2: //1

P00 = 0;

P01 = 1;

P02 = 0;

P03 = 0;

break;

case 3: //1、2

P00 = 0;

P01 = 1;

P02 = 1;

P03 = 0;

break;

case 4: //2

P00 = 0;

P01 = 0;

P02 = 1;

P03 = 0;

break;

case 5: //2、3

P00 = 0;

P01 = 0;

P02 = 1;

P03 = 1;

break;

case 6: //3

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 1;

break;

case 7: //3、0

P00 = 1;

P01 = 0;

P02 = 0;

P03 = 1;

}

if (turn==0)

{

step_index++;

if (step_index>7)

step_index=0;

}

else

{

step_index--;

if (step_index

step_index=7;

}

}

步进电机控制

Link - Thu, 17 Jan 2008 12:41:32 +0800

Description:

本设计采用的步进电机为35BYJ46型四相八拍电机,电压为DC12V。

工作原理:利用INTER 8255A对四相步进电机进行控制。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)等。

35BYJ46步进电机为四相八拍,其相序表如下:

步序 PA3 PA2 PA1 PA0 对应A口输出值

1 0 0 0 1 01H

2 0 0 1 1 03H

3 0 0 1 0 02H

4 0 1 1 0 06H

5 0 1 0 0 04H

6 1 1 0 0 0CH

7 1 0 0 0 08H

8 1 0 0 1 09H

实验程序如下:

;FILENAME: 步进电机控制.ASM

;内容: 步进电机控制

STACK SEGMENT STACK

DW 256 DUP(?)

STACK ENDS

P55A EQU 60H ;8255A口输出

P55C EQU 62H ;8255C口输入

P55CTL EQU 63H ;8255控制口

DATA SEGMENT

BUF DB 0

MES DB 'K0-K6 ARE SPEED CONTROL', 0DH, 0AH

DB 'K6 IS THE LOWEST SPEED', 0DH, 0AH

DB 'K0 IS THE HIGHEST SPEED', 0DH, 0AH

DB 'K7 IS THE DIRECTION CONTROL', 0DH, 0AH, '$'

TABLE DB 01H,03H,02H,06H,04H,0CH,08H,09H

TABLE1 DB 01H,09H,08H,0CH,04H,06H,02H,03H

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA

START: MOV AX, CS

MOV DS, AX

MOV AX, DATA

MOV DS, AX

MOV DX, OFFSET MES

MOV AH, 09 ; dos调用,在显示器上显示以$为结

束符的字符串,

INT 21H ; 若显示字符串要求回车换行则在其

后加入0dh,0ah。

MOV DX, P55CTL

MOV AL, 8BH ;10001011B

OUT DX, AL ;8255C输入, A输出

MOV BUF, 33H

OUT1: MOV AL, BUF

MOV DX, P55A

OUT DX, AL ;从A口输出00110011

PUSH DX

MOV AH, 06H

MOV DL, 0FFH ;DOS调用,直接控制台读写,DL=0FF 输入,DL=字符 输出;

INT 21H ;检查有无键按下

POP DX

JE IN1 ;ZF=1,则跳转

MOV AH, 4CH ;带返回码结束,AL=返回码

INT 21H

IN1: MOV DX, P55C

IN AL,DX ;读开关状态,则跳转至相应开关处

TEST AL, 01H

JNZ K0

TEST AL, 02H

JNZ K1

TEST AL, 04H

JNZ K2

TEST AL, 08H

JNZ K3

TEST AL, 10H

JNZ K4

TEST AL, 20H

JNZ K5

TEST AL, 40H

JNZ K6

STOP: MOV DX, P55A

MOV AL, 0FFH

JMP OUT1

K0: MOV BL, 10H

SAM: TEST AL, 80H ;K7是否为1,是则步进电机正转,否则反转 JZ ZX0

JMP NX0

K1: MOV BL, 18H

JMP SAM

K2: MOV BL, 20H

JMP SAM

K3: MOV BL, 40H

JMP SAM

K4: MOV BL, 80H

JMP SAM

K5: MOV BL, 0C0H

JMP SAM

K6: MOV BL, 0FFH

JMP SAM

ZX0:

MOV BX,OFFSET TABLE

MOV CX,0008H

ZX1: MOV AL,[BX]

OUT 61H,AL

CALL DELAY

INC BX

LOOP ZX1

JMP OUT1

NX0:

MOV BX,OFFSET TABLE1

MOV CX,0008H

NX1: MOV AL,[BX]

OUT 61H,AL

CALL DELAY

INC BX

LOOP NX1

JMP OUT1

DELAY PROC NEAR ;延时子程序 DELAY1:

MOV CX, 05A4H

DELAY2:

LOOP DELAY2

DEC BL

JNZ DELAY1

RET

DELAY ENDP

CODE ENDS

END START

步进电机控制程序

(2008-06-05 19:07:55)

转载

标签: 分类: 程序设计

it

步进电机(键盘控制可调速)

#include

#define uchar unsigned char

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void ddelay(void); //键盘扫描延时函数

void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒

void gorun(); //步进电机控制步进函数

sbit P10=P2^0 ; //电机端口定义

sbit P11=P2^1 ;

sbit P12=P2^2;

sbit P13=P2^3 ;

void ddelay(void)

{

uchar i;

for (i=300;i>0;i--);

}

uchar keyscan(void)

{

uchar scancode;

uchar tmpcode;

P1 = 0xf8; // 发全0行扫描码

if ((P1&0xf8)!=0xf8) // 若有键按下

{

ddelay(); // 延时去抖动

if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响

{

scancode = 0xfe;

while((scancode&0x08)!=0) // 逐行扫描

{

P1 = scancode; // 输出行扫描码

if ((P1&0xf8)!=0xf8) // 本行有键按下

tmpcode = (P1&0xf8)|0x07;

return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列

}

else scancode = (scancode

}

}

}

return(0); // 无键按下,返回值为0

}

void main(void)

{

uchar key;

count = 0;

step_index = 0;

spcount = 0;

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFc;

TL0 = 0x18; //设定时每隔1ms中断一次

TR0 = 1; //开始计数

stop_flag = 0;

turn=0;

speedlevel = 20;

while(1)

{

key = keyscan();

switch(key)

{

case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn = 0;

speedlevel =10;

gorun();

delay(1000);

break;

case 0x0c: //按键*, 停止 2000*0.5MS=0.5S

stop_flag=1;

break;

case 0x0a: //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn=1;

speedlevel =10;

gorun();

delay(1000);

break;

case 0x11: // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S

stop_flag=0;

if (speedlevel==1)

{ speedlevel=1;}

else { --speedlevel;}

gorun();

delay(1000);

break;

case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S

stop_flag=0;

++speedlevel;

gorun();

delay(1000);

break;

}

}

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFc;

TL0=0x18; //设定时每隔1ms中断一次

count++;

spcount--;

if(spcount

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒

{

count=0;

do{}

while(count

void gorun()

{

if (stop_flag==1)

{

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

return;

}

switch(step_index)

{

case 0: //0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 0;

break;

case 1: //0、1

P10 = 1;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 2: //1

P10 = 0;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 3: //1、2

P10 = 0;

P11 = 1;

P12 = 1;

P13 = 0;

break;

case 4: //2

P10 = 0;

P11 = 0;

P12 = 1;

P13 = 0;

break;

case 5: //2、3

P10 = 0;

P11 = 0;

P12 = 1;

P13 = 1;

break;

case 6: //3

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 1;

break;

case 7: //3、0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 1;

}

if (turn==0) //正转

{

step_index++;

if (step_index>7)

step_index=0;

}

else

{ //反转

step_index--;

if (step_index

step_index=7;

}

}

步进电机(键盘控制可调速加显示)

#include

#define uchar unsigned char

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void ddelay(void); //键盘扫描延时函数

void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒

void gorun(); //步进电机控制步进函数

void Delay400Ms(void);

void LCMInit(void); //LCM初始化

void WriteCommandLCM(unsigned char WCLCM,BuysC); //BuysC为0时忽略忙检测 void DisplayOneChar(uchar X, uchar Y, uchar DData);

void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n);

sbit P10=P3^0 ; //电机端口定义

sbit P11=P3^1 ;

sbit P12=P3^2;

sbit P13=P3^3 ;

uchar code speed[]={ 0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30};

uchar code stop[] = {"stop"};

uchar code go[] = {"go:"};

uchar code back[] = {"back:"};

uchar code max[] = {"max:8"};

void ddelay(void)

{

uchar i;

for (i=300;i>0;i--);

}

uchar keyscan(void)

{

uchar scancode;

uchar tmpcode;

P1 = 0xf8; // 发全0行扫描码

if ((P1&0xf8)!=0xf8) // 若有键按下

{

ddelay(); // 延时去抖动

if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响

{

scancode = 0xfe;

while((scancode&0x08)!=0) // 逐行扫描

{

P1 = scancode; // 输出行扫描码

if ((P1&0xf8)!=0xf8) // 本行有键按下

{

tmpcode = (P1&0xf8)|0x07;

return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列

}

else scancode = (scancode

}

}

}

return(0); // 无键按下,返回值为0

}

void main(void)

{

uchar key;

count = 0;

step_index = 0;

spcount = 0;

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFc;

TL0 = 0x18; //设定时每隔1ms中断一次

TR0 = 1; //开始计数

P0=0XFF;

P3 &=0XEF; //573片选

LCMInit(); //LCM初始化

Delay400Ms();

stop_flag = 0;

turn=0;

speedlevel = 5;

DisplayListChar(0,0,3,go,1); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

while(1)

{

key = keyscan();

switch(key)

{

case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn = 0;

speedlevel =5;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x0c: //按键*, 停止 2000*0.5MS=0.5S

stop_flag=1;

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,4,stop,0); //每次扫描键盘显示更新一次

break;

case 0x0a: //按键0, 反转以speedlevel = 1的速度转1000*0.5MS=0.5S

stop_flag=0;

turn=1;

speedlevel =5;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次

DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x11: // 按键9, 以--speedlevel的加速转1000*0.5MS=0.5S

stop_flag=0;

if (speedlevel==2)

{ speedlevel=2;}

else { speedlevel--;}

gorun();

if(speedlevel==2)

{ DisplayListChar(0,1,5,max,0);}

else {DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次

delay(1000);

break;

case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5S

stop_flag=0;

speedlevel++;

gorun();

WriteCommandLCM(0x01,1);//显示清屏,

if(turn==0)

{DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[]

DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次

else {DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次

DisplayOneChar(0,1,speed[speedlevel]);} //每次扫描键盘显示更新一次

delay(1000);

break;

}

}

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFc;

TL0=0x18; //设定时每隔1ms中断一次

count++;

spcount--;

if(spcount

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒

{

count=0;

do{}

while(count

}

void gorun()

{

if (stop_flag==1)

{

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 0;

return;

}

switch(step_index)

{

case 0: //0

P10 = 1;

P11 = 0;

P12 = 0;

P13 = 0;

break;

case 1: //0、1

P10 = 1;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 2: //1

P10 = 0;

P11 = 1;

P12 = 0;

P13 = 0;

break;

case 3: //1、2 P10 = 0;

P11 = 1;

P12 = 1;

P13 = 0;

break;

case 4: //2 P10 = 0;

P11 = 0;

P12 = 1;

P13 = 0;

break;

case 5: //2、3 P10 = 0;

P11 = 0;

P12 = 1;

P13 = 1;

break;

case 6: //3

P10 = 0;

P11 = 0;

P12 = 0;

P13 = 1;

break;

case 7: //3、0 P10 = 1;

P11 = 0;

P12 = 0;

P13 = 1;

}

if (turn==0) //正转 {

step_index++; if (step_index>7) step_index=0; }

else

{ //反转 step_index--; if (step_index

step_index=7;

}

}

步进电机(自动循环调速)

#include

sbit P00=P2^0 ;

sbit P01=P2^1 ;

sbit P02=P2^2;

sbit P03=P2^3 ;

static unsigned int count; //计数

static int step_index; //步进索引数,值为0-7

static bit turn; //步进电机转动方向

static bit stop_flag; //步进电机停止标志

static int speedlevel; //步进电机转速参数,数值越大速度越快,最小值为1,速度最慢 static int spcount; //步进电机转速参数计数

void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒

void gorun(); //步进电机控制步进函数

void main(void)

{

count = 0;

step_index = 0;

spcount = 0;

stop_flag = 0;

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 0;

EA = 1; //允许CPU中断

TMOD = 0x11; //设定时器0和1为16位模式1

ET0 = 1; //定时器0中断允许

TH0 = 0xFE;

TL0 = 0x0C; //设定时每隔0.5ms中断一次

TR0 = 1; //开始计数

turn = 0;

do{

speedlevel =4;

delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1S

speedlevel =4;

delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1S

stop_flag=1;

delay(6000);//停止,2000*0.5MS=3S

stop_flag=0;

}while(1);

}

//定时器0中断处理

void timeint(void) interrupt 1

{

TH0=0xFE;

TL0=0x0C; //设定时每隔0.5ms中断一次

count++;

spcount--;

if(spcount

{

spcount = speedlevel;

gorun();

}

}

void delay(unsigned int endcount)

{

count=0;

do{}while(count

}

void gorun()

{

if (stop_flag==1)

{

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 0;

return;

}

switch(step_index)

{

case 0: //0

P00 = 1;

P01 = 0;

P02 = 0;

P03 = 0;

break;

case 1: //0、1

P00 = 1;

P01 = 1;

P02 = 0;

P03 = 0;

break;

case 2: //1

P00 = 0;

P01 = 1;

P02 = 0;

P03 = 0;

break;

case 3: //1、2

P00 = 0;

P01 = 1;

P02 = 1;

P03 = 0;

break;

case 4: //2

P00 = 0;

P01 = 0;

P02 = 1;

P03 = 0;

break;

case 5: //2、3

P00 = 0;

P01 = 0;

P02 = 1;

P03 = 1;

break;

case 6: //3

P00 = 0;

P01 = 0;

P02 = 0;

P03 = 1;

break;

case 7: //3、0

P00 = 1;

P01 = 0;

P02 = 0;

P03 = 1;

}

if (turn==0)

{

step_index++;

if (step_index>7)

step_index=0;

}

else

{

step_index--;

if (step_index

step_index=7;

}

}

步进电机控制

Link - Thu, 17 Jan 2008 12:41:32 +0800

Description:

本设计采用的步进电机为35BYJ46型四相八拍电机,电压为DC12V。

工作原理:利用INTER 8255A对四相步进电机进行控制。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A。。。),双(双相绕组通电)四拍(AB-BC-CD-DA-AB-。。。),八拍(A-AB-B-BC-C-CD-D-DA-A。。。)等。

35BYJ46步进电机为四相八拍,其相序表如下:

步序 PA3 PA2 PA1 PA0 对应A口输出值

1 0 0 0 1 01H

2 0 0 1 1 03H

3 0 0 1 0 02H

4 0 1 1 0 06H

5 0 1 0 0 04H

6 1 1 0 0 0CH

7 1 0 0 0 08H

8 1 0 0 1 09H

实验程序如下:

;FILENAME: 步进电机控制.ASM

;内容: 步进电机控制

STACK SEGMENT STACK

DW 256 DUP(?)

STACK ENDS

P55A EQU 60H ;8255A口输出

P55C EQU 62H ;8255C口输入

P55CTL EQU 63H ;8255控制口

DATA SEGMENT

BUF DB 0

MES DB 'K0-K6 ARE SPEED CONTROL', 0DH, 0AH

DB 'K6 IS THE LOWEST SPEED', 0DH, 0AH

DB 'K0 IS THE HIGHEST SPEED', 0DH, 0AH

DB 'K7 IS THE DIRECTION CONTROL', 0DH, 0AH, '$'

TABLE DB 01H,03H,02H,06H,04H,0CH,08H,09H

TABLE1 DB 01H,09H,08H,0CH,04H,06H,02H,03H

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA

START: MOV AX, CS

MOV DS, AX

MOV AX, DATA

MOV DS, AX

MOV DX, OFFSET MES

MOV AH, 09 ; dos调用,在显示器上显示以$为结

束符的字符串,

INT 21H ; 若显示字符串要求回车换行则在其

后加入0dh,0ah。

MOV DX, P55CTL

MOV AL, 8BH ;10001011B

OUT DX, AL ;8255C输入, A输出

MOV BUF, 33H

OUT1: MOV AL, BUF

MOV DX, P55A

OUT DX, AL ;从A口输出00110011

PUSH DX

MOV AH, 06H

MOV DL, 0FFH ;DOS调用,直接控制台读写,DL=0FF 输入,DL=字符 输出;

INT 21H ;检查有无键按下

POP DX

JE IN1 ;ZF=1,则跳转

MOV AH, 4CH ;带返回码结束,AL=返回码

INT 21H

IN1: MOV DX, P55C

IN AL,DX ;读开关状态,则跳转至相应开关处

TEST AL, 01H

JNZ K0

TEST AL, 02H

JNZ K1

TEST AL, 04H

JNZ K2

TEST AL, 08H

JNZ K3

TEST AL, 10H

JNZ K4

TEST AL, 20H

JNZ K5

TEST AL, 40H

JNZ K6

STOP: MOV DX, P55A

MOV AL, 0FFH

JMP OUT1

K0: MOV BL, 10H

SAM: TEST AL, 80H ;K7是否为1,是则步进电机正转,否则反转 JZ ZX0

JMP NX0

K1: MOV BL, 18H

JMP SAM

K2: MOV BL, 20H

JMP SAM

K3: MOV BL, 40H

JMP SAM

K4: MOV BL, 80H

JMP SAM

K5: MOV BL, 0C0H

JMP SAM

K6: MOV BL, 0FFH

JMP SAM

ZX0:

MOV BX,OFFSET TABLE

MOV CX,0008H

ZX1: MOV AL,[BX]

OUT 61H,AL

CALL DELAY

INC BX

LOOP ZX1

JMP OUT1

NX0:

MOV BX,OFFSET TABLE1

MOV CX,0008H

NX1: MOV AL,[BX]

OUT 61H,AL

CALL DELAY

INC BX

LOOP NX1

JMP OUT1

DELAY PROC NEAR ;延时子程序 DELAY1:

MOV CX, 05A4H

DELAY2:

LOOP DELAY2

DEC BL

JNZ DELAY1

RET

DELAY ENDP

CODE ENDS

END START


相关内容

  • 可编程控制器课程设计报告
  • 可编程控制器课程设计报告 题目:PLC实现步进电机正反转调速控制 班 级 姓 名 杨振华 学 号 200708214 指导教师 王庆贤 设计时间 目录 目录........................................................................ ...

  • 单片机两种方式控制步进电机旋转
  • 单片机课程设计说明书 设计题目 两种方式控制步进电机控制 指导教师: 设计者: 系 别: 机械工程学院 班 级: 学 号: 目 录 序言„„„„„„„„„„„„„„„„„„„„„„„„„„3 一.步进电机介绍„„„„„„„„„„„„„„„„„„„„4 1.1步进电机的概念„„„„„„„„„„„„„„ ...

  • 从永磁式步进电机看单片机对步进电机的控制
  • 摘 要 本文利用一个常用的永磁式步进电机,介绍了如何使用单片机进行步进电机的控制,通过对电路图.程序设计和程序分析对这个系统进行了全面解释. 关键词 单片机:步进电机:控制 中图分类号:TP393 文献标识码:A 文章编号:1671-7597(2013)021-092-01 这里采用常见的永磁式步进 ...

  • [matlab编程代做]步进电机控制器设计
  • 步进电机控制器设计报告 1.绪言 在本次EDA课程设计中,我们组选择了做一个步进电机驱动程序的课题.对于步进电机我们以前并未接触过,它的工作原理是什么,它是如何工作的,我们应该如何控制它的转停,这都是我们迫切需要了解的. 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件.在非超载的情况下,电 ...

  • 三菱PLC控制的机械手系统
  • 作者:洪玉红 自动化系自0101班 摘 要:本文介绍了如何利用PLC (可编程控制器)的自动控制和逻辑运算的优点改变PLC 的程序及参数,达到灵活控制设备运行的目的, 从而使设备操作变得更方便,更富有人性化.它充分体现了工控自动化在实际生产中的重要作用.通过对物料搬运机械手装置结构与功能的介绍,给出 ...

  • 基于单片机控制的步进电机调速系统的设计
  • 前 言 步进电机最早是在1920年由英国人所开发.1950年后期晶体管的发明也逐渐应用在步进电机上,这对于数字化的控制变得更为容易.以后经过不断改良,使得今日步进电机已广泛运用在需要高定位精度.高分解性能.高响应性.信赖性等灵活控制性高的机械系统中.在生产过程中要求自动化.省人力.效率高的机器中.步 ...

  • 直流电机转速控制方案
  • 直流电机控制系统 SPCE061A应用方案 V1.0 – 2005.11.30 凌阳科技大学计划教育推广中心 北京海淀上地信息产业基地中黎科技园1号楼3层 TEL: 010-62981113 FAX: 010-62986660-2992 E-mail:[email protected] http ...

  • 单片机课程设计报告--单片机控制步进电机
  • 单片机原理及应用课程设计报告 江西农大 单片机原理及应用 课程设计报告 设计课题: 专业班级:学生姓名: 指导教师: 2012 年 5 月 单片机原理及应用课程设计报告 目 录 目 录 ························································· ...

  • 步进电机滑台PLC控制课程设计报告
  • 大连民族学院机电信息工程学院 自动化系 PLC 课程设计报告 题 目: 专 业: 班 级: 学生姓名: 卢真伊.谭潏.潘竹馨 指导教师: 张涛 步进电机滑台PLC 控制 自动化 自动化122,123,124 谭今文.周鸿儒.唐海涛. 设计完成日期: 2015年 5月7日 目 录 1任务分析和性能指标 ...

  • BLDC直流无刷电机驱动
  • 目 录 第1章 无刷直流电机驱动实验指导···············································································2 1.1 1.2 1.3 1.4 1.5 概述··························· ...