步进电机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


相关文章

  • 工程部应急预案
  •   工程部应急预案   1总则   本程序对饭店内发生火灾、防汛、电梯困人、停水、停煤气、煤气泄漏、停电、触电、漏水、停蒸汽等紧急情况时,工程部采取的应急措施予以表述,为了规范应急事件的应对管理,特制定本程序。   2工程部火灾扑救预案   2.1在工程部管辖范围内的各机房或工作区域发生火灾,发现人 ...

  • 医院大面积停电应急预案
  • 一 制定目的 为应对医院突发性大面积停电事故,迅速有序地组织和恢复供电,确保病人生命安全和减少财产损失,保证医院用电畅通,促进事故应急工作的制度化和规范化,依据国家相关法律法规,结合我院实际情况,制定本预案。 二 适用范围 本预案所称“突发性大面积通电事故”(下称“大面积停电事故”)是指因严重自然灾 ...

  • 铆工技术工作总结
  • 一.思想觉悟的提高 在完成本职工作的同时,认真学习公司的文件精神和厂及车间下发的学习材料,时时了解公司及本厂的经营状况,认识存在的问题,明确努力的方向,协同各方做好思想工作,使自己的思想觉悟在不知不觉中得到提高. 二.专业技术工作 自参加工作以来,我工作在技术要求很强的调试组,负责维护棒材主轧线的电

  • 技术人员工作计划
  • 年末之际,对我的全年工作做一个简单的总结。 一.思想觉悟的提高 在完成本职工作的同时,认真学习公司的文件精神和厂及车间下发的学习材料,时时了解公司及本厂的经营状况,认识存在的问题,明确努力的方向,协同各方做好思想工作,使自己的思想觉悟在不知不觉中得到提高。 二.专业技术工作 自参加工作以来,我工作在 ...

  • 仓库管理制度
  • 仓库管理制度 为加强成本核算,提高公司的基础管理工作水平,进一步规范物资和成品流通、保管和控制程序,维护公司资产的安全完整,加速资金周转,特制定本制度: 一、 仓库日常管理 1、仓库保管员必须合理设置各类物资和产品的明细账簿和台账。原材料仓库必须根据实际情况和各类原材料的性质、用途、类型分明别类建立 ...

  • 电气工程及其自动化专业毕业实习报告
  • 按照老师的教学计划安排,本人200*年10月份开始到____公司进行实习,____是以水力发电机组安装、检修为主的一个经济实体,目前主要是对____发电厂提供检修服务,所以我的实习场所也是以____发电厂为主。经过这段时间的跟班实习,我对电厂的整个生产过程、发电厂的主要设备有了更进一步的了解。 __ ...

  • 电力科技企业实习报告
  •   姓名:xx   时间:2012年7月14日-----9月16日   一.概述   为期2个月的实习结束了,我在这两个月的实习中学到很多,都是学校和课堂所根本学不到的知识,受益非浅。xx集团中国领先的电力能源计量和系统供应商,学到的不只是知识更是职业精神和文化。感谢xx给我的这次机会。   二.学 ...

  • 汽车电器实习报告
  •   一、实习目的   在为期两周的实习当中感触最深的便是实践联系理论的重要性,当遇到实际问题时,只要认真思考,对就是思考,用所学的知识,再一步步探索,是完全可以解决遇到的一般问题的。这次的内容包括启动系、充电系、点火系、雨刮系、灯火系等。本次实习的目的主要是使我们对汽车元件及整机装配工艺有一定的感性 ...

  • 车间技术员个人年终总结
  • 自xx年7月我来到xx一园区工作现今,已有一年多的时间了。在这一年中,我一直在项目部工作,负责电气施工的现场管理及技术指导工作,凭借自己的努力和领导的提携,从一名普通的电气监理,进而又被提拔到兼任电仪车间技术员一职。在这期间,我除负责对南北厂区所属的车间进行电气施工监理的工作之外,还承担电仪车间技术 ...

  • 参观公司心得体会
  • 今天我们在老师的带领下参观了我们这次专业实习的第三站-固高科技(深圳)有限公司,通过公司相关人员的介绍,我详细地了解了该公司的整体运营状况.固高科技创立于1999年,以香港科技大学为依托,是目前亚太地区第一家拥有自主知识产权,专业从事高速.高精度运动控制器产品及其相关产品的设计.制造.营销以及技术服 ...