您的当前位置:首页正文

步进电机角度控制(1)

2020-03-26 来源:榕意旅游网


课 程 设 计

课程名称 微型计算机控制技术 题目名称 步进电机角度控制(1) 学生学院 自动化学院 专业班级 自动化(4)班 学 号 学生姓名 指导教师

2012 年 6 月

26 日

一、 系统设计说明

1. 硬件设计

本次设计要求通过键盘按键实现对步进电机的转动次数和每次转动的角度的控制,并通

过数码管显示出来。

本方案中通过按键对步进电机的转动角度进行设定,给各个按键设置不同的键值。按下按键时,给8255A一个信号设定步进电机下一步的动作。8086通过8255A的数据总线读取该信号,并作出反应,通过给8255A一系列的指令驱动其工作,从而驱动步进电机和LED显示器

2. 软件设计

显示模块设计说明:

为使显示程序具有通用性和灵活性,在8086内设置一个显示缓冲区,显示缓冲区的每个单元与LED的各位一一对应。当主程序需要显示,只需将要显示的字符送入显示缓冲区,然后调用显示子程序。显示子程序的任务则是逐一取出显示缓冲区中的字符、查字形表转换成相应字型码,然后通过字段口输出显示。显示模块是用四位七段数码管来显示转动次数和每次转动的角度。给八个按键设置不同的子程序,当按下按键时,根据事先设定好的各个按键对应的转动角度的值输出到数码管进行显示。

步进电机模块设计说明:

在此设计中,采用的是八拍步进电机。步进电机控制程序就是完成环形分配器的任务,从而控制电动机的转动,以达到控制转动角度和位移的目的。控制模型可以以立即数的形式一一给出。对于步进电机模块的程序设计采用循环程序设计方法。先把转动的次数和角度的控制模型存放在内存单元中,然后再逐一从单元中取出控制模块并输出。首先启动,按下按键选择步进电机的角度,然后读入转动的控制模型驱动步进电机转动。

二、 程序设计流程图

开始 是否按键 实现键的功能 数码显示 结束

三、 心得体会

这是大学最后一次的单片机课程设计了,这一次我抽到的是86,用C语言去设计的。从中我发现相对汇编语言,C语言有很多优点。经过不断地去编程加载,我复习了C语言编程,同时懂得如何在单片机上实现C语言编程。数码管,键盘和异步电动机,是三个不一样的模块,从实现的过程中,巩固了很多知识。最重要的是,发现问题,去寻找问题的缘由,从而解决。

四、 主要参考文献

《计算机控制技术实验指导书》,李传芳等编。

《51单片机C语言教程》,郭天祥等编。电子工业出版社。 《微型计算机原理及应用》,何小敏等编。机械工业出版社。

任务一:

编程控制步进电机,顺时针方向行走180度(角度显示在七段LED上)3秒后行走45度(显示角度)3秒后行走90度(显示角度)3秒后再次进入循环。

程序代码:

STACK SEGMENT STACK DW 256 DUP(?)

STACK ENDS DATA SEGMENT TABLE1 DB 10H,30H,20H,60H,40H,0C0H,80H,90H DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MAIN: MOV AL,81H, OUT 63H,AL MOV AH,30H MOV BX,0FF00H MOV DX,01H CALL DISP A0: MOV CX,0008H

MOV SI,OFFSET TABLE1 A1: MOV AL,[SI] OUT 60H,AL CALL DALLY INC SI DEC AH JNZ L1

CALL DALL CMP BX,0FFH JNZ A

MOV AH,30H XOR BX,0FFFFH MOV DX,01H JMP L1

A: CMP BX,OFFOOH JNZ A8

MOV AH,0CH XOR BX,0FF00H MOV DX,02H CALL DISP JMP L1

A8: MOV AH,18H XOR BX,0FFH MOV DX,03H CALL DISP L1: LOOP A1 JMP A0

DISP: CMP DX,01H

JNZ D1

MOV AL,0EFH OUT 62H,AL MOV AL,0FCH OUT 61H,AL CALL TIME MOV AL,0DFH OUT 62H,AL MOV AL,0FEH

OUT 61H,AL CALL TIME MOV AL,0BFH OUT 62H,AL MOV AL,60H OUT 61H,AL CALL TIME RET

D1: CMP DX,02H JNZ D2

MOV AL,0EFH OUT 62H,AL MOV AL,0B6H OUT 61H,AL CALL TIME MOV AL,0DFH OUT 62H,AL MOV AL,66H OUT 61H,AL CALL TIME RET

D2: MOV AL,0FEH

OUT 62H,AL MOV AL,0FCH OUT 61H,AL CALL TIME MOV AL,0DFH OUT 62H,AL MOV AL,0F6H OUT 61H,AL CALL TIME RET

TIME: PUSH AX PUSH CX

TIME1: MOV AX,0010H

TIME2 : DEC AX JNZ TIME2 LOOP TIME1 POP CX POP AX RET

DALLY: PUSH CX

MOV CX,0100H A4: PUSH AX POP AX LOOP A4 POP CX RET

DALLY1: PUSH AX PUSH CX

MOV CX,0002H T1: MOV AX,0010H T2: DEC AX JNZ T2 LOOP T1 POP CX POP AX RET

DALL: PUSH CX PUSH AX

MOV CX,0300H A6: MOV AX,056CH A7: DEC AX CALL DISP JNZ A7 LOOP A6 POP AX POP CX RET CODE ENDS

END START

任务二:

完成A/D转换实验并把转换结果显示在七段LED上显示出来。

程序代码:

STACK SEGMENT STACK DW 64 DUP(?)

STACK ENDS DATA SEGMENT TAB1 DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,

POP AX JMP START TIME: PUSH AX PUSH CX

MOV CX,0020H T1: MOV AX,0030H 0FEH,0F6H,0EFH,3EH,9CH,7AH,9EH,8EH

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AL OUT 00H,AL CALL DALLY IN AL,00H

MOV BX,OFFSET TAB1 PUSH AX MOV AL,80H OUT 63H,AL POP AX PUSH AX

AND AX,000FH ADD BX,AX MOV AL,[BX] OUT 61H,AL MOV AL,0FEH OUT 62H,AL CALL TIME MOV AL,0FFH OUT 62H,AL POP AX

MOV BX,OFFSET TAB1 PUSH AX

AND AX,00F0H SHR AL,4 ADD BX,AX MOV AL,[BX] OUT 61H,AL MOV AL,0DFH OUT 62H,AL CALL TIME MOV AL,0FFH OUT 62H,AL

T2: DEC AX JNZ T2 LOOP T1 POP CX POP AX RET

DALLY: PUSH CX PUSH AX

MOV CX,0004H A5: MOV AX,005CH A6: DEC AX JNZ A6 LOOP A5 POP AX POP CX RET CODE ENDS

END START

任务三:实现:

(1)定义键盘按键:3个功能键:设置SET、清零CLR,开始START;

(2)显示器上三位显示每次行走的角度;

(3)通过键盘按键,设置步进电机行走的最大角度值:按SET键后,使用键盘设置角度,再按一次START置入;按CLR清零返回原位。

(4)转动电位器启动步进电机跟随转动,到位后停止;电位器回原位步进电机也回原位。步进电机角度能显示分辨率为15度。

程序代码: #include #define pa 0x60 #define pb 0x61 #define pc 0x62 #define com 0x63

#define uint unsigned int #define uchar unsigned char uchar

duan[]={0xfc,0x60,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xef,0x3e,0x9c,0x7a,0x9e,0x8e}

uchar wei[]={0xef,0xdf,0xbf,0x7f}; uchar

moto[]={0x90,0x80,0xc0,0x40,0x60,0x20,0x30,0x10};

uchar buff[]={0,0,0,0}; int flag=1;

int dushu,max=0;

Void delay(int t) {

Int a,b;

For(a=t;a>0;a--) For(b=110; b>0:b--); }

Void dis(int a,int b,int c,int d) {

Outp(pc,wei[3]); Outp(pb,duan[a]); Depaly(15)

Outp(pc,wei[2]); Outp(pb,duan[b]); Depaly(15)

Outp(pc,wei[1]); Outp(pb,duan[c]); Depaly(15)

Outp(pc,wei[0]); Outp(pb,duan[d]); Depaly(15) }

Void keyscan1() {

Uchar temp,i; Outp(pc,0x7f);

Temp=inp(pc); Temp=temp&0x0c; If(temp==0x08) {dushu=1; Buff[0]=buff[0]+1;

If(buff[0]>9){buff[0]=0;} }

If(temp==0x04){dushu=5; Buff[1]=buff[1]+1; If (buff[1]>9){buff[1]=0;} }

Outp(pc,0xbf); Temp=inp(pc);

If(temp==0x88){dushu=2;flag=3;} If(temp==0x04){dushu=6;

Buff[2]=buff[2]+1; If(buff[2]>9) {buff[2]=0;}

} Outp(pc,0xdf); Temp=inp(pc); Temp=temp&0x0c;

If(temp==0x08){dushu=3;}

If(temp==0x04){dushu=7;flag=1;}

Outp(pc,0xef); Temp=inp(pc); Temp=temp&0x0c;

If(temp==0x08){dushu=4;flag=2;} If(temp==0x04){dushu=8;

Buff[3]=buff[3]+1;

If(buff[3]>9){buff[3]=0;}

} delay(150); }

Void keyscan() {

Uchar temp; Outp(pc,0x00); Temp=inp(pc); Temp=temp&0x0c; If(temp!=0x0c)

{delay(2);

If (temp!=0x0c) Keyscan1(); } }

Void main()

{signed int y=0,step=0,x,dian,i; Uchar temp; Outp(com,0x81); While(1) {

Keyscan(); If(flag==1)

{dis(buff[3],buff[2],buff[1],buff[0]); }

If(flag==2)

{buff[0]=0;buff[1]=0;,buff[2]=0;buff[3]=0;max=0; If(y>0) {

If(step==8){step=0;} For(i=4;i>0;i--)

(outp(pa,moto[8-step]); Step++; Delay(10); }

Y=y-15; }

Dis(0,0,0,0); }

If(flag==3)

{outp(com,0x81); Outp(0x00,1) Doam=inp(0x00);

Max=buff[0]+buff[1]*10+buff[2]*100+buff[3]*1000;

X=max/15*dian/255*15; If(x>y) {

If(step==8){step=0;} For(i=4;i>0;i--) {

Outp(pa,moto[step]);

Step++; Delay(10); }

Y=y+15; }

If((y-x)>0) {

If(step==8){step=0;} For(i=4;i>0;i--) {

Outp(pa,moto[8-step]); Step++ Delay(10); }

Y=y-15; }

For(i=5;i>0;i--)

{dis(x/1000,x%1000/100,x%100/10,x%10);} } } }

实验心得:

这个实训非常需要耐性和细心,只要你一个不小心,出现一个错误,你就麻烦了。所以它教会我们做事一定要严谨,细心,坚持就是胜利。

完成之后也使更加熟悉了c和汇编语言,获益良多。

因篇幅问题不能全部显示,请点此查看更多更全内容