课程设计课程名称微型计算机控制技术题目名称步进电机角度控制(1)学生学院自动化学院专业班级自动化(4)班学号学生姓名指导教师2012 年 6 月26日一、系统设计说明1.硬件设计本次设计要求通过键盘按键实现对步进电机的转动次数和每次转动的角度的控制,并通过数码管显示出来。
本方案中通过按键对步进电机的转动角度进行设定,给各个按键设置不同的键值。
按下按键时,给8255A一个信号设定步进电机下一步的动作。
8086通过8255A的数据总线读取该信号,并作出反应,通过给8255A一系列的指令驱动其工作,从而驱动步进电机和LED 显示器2.软件设计3.显示模块设计说明:为使显示程序具有通用性和灵活性,在8086内设置一个显示缓冲区,显示缓冲区的每个单元与LED的各位一一对应。
当主程序需要显示,只需将要显示的字符送入显示缓冲区,然后调用显示子程序。
显示子程序的任务则是逐一取出显示缓冲区中的字符、查字形表转换成相应字型码,然后通过字段口输出显示。
显示模块是用四位七段数码管来显示转动次数和每次转动的角度。
给八个按键设置不同的子程序,当按下按键时,根据事先设定好的各个按键对应的转动角度的值输出到数码管进行显示。
步进电机模块设计说明:在此设计中,采用的是八拍步进电机。
步进电机控制程序就是完成环形分配器的任务,从而控制电动机的转动,以达到控制转动角度和位移的目的。
控制模型可以以立即数的形式一一给出。
对于步进电机模块的程序设计采用循环程序设计方法。
先把转动的次数和角度的控制模型存放在内存单元中,然后再逐一从单元中取出控制模块并输出。
首先启动,按下按键选择步进电机的角度,然后读入转动的控制模型驱动步进电机转动。
二、程序设计流程图三、心得体会这是大学最后一次的单片机课程设计了,这一次我抽到的是86,用C语言去设计的。
从中我发现相对汇编语言,C语言有很多优点。
经过不断地去编程加载,我复习了C语言编程,同时懂得如何在单片机上实现C语言编程。
数码管,键盘和异步电动机,是三个不一样的模块,从实现的过程中,巩固了很多知识。
最重要的是,发现问题,去寻找问题的缘由,从而解决。
四、主要参考文献《计算机控制技术实验指导书》,李传芳等编。
《51单片机C语言教程》,郭天祥等编。
电子工业出版社。
《微型计算机原理及应用》,何小敏等编。
机械工业出版社。
任务一:编程控制步进电机,顺时针方向行走180度(角度显示在七段LED上)3秒后行走45度(显示角度)3秒后行走90度(显示角度)3秒后再次进入循环。
程序代码:STACK SEGMENT STACKDW 256 DUP()STACK ENDSDATA SEGMENTTABLE1 DB 10H,30H,20H,60H,40H,0C0H,80H,90H DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AXMAIN: MOV AL,81H,OUT 63H,ALMOV AH,30HMOV BX,0FF00HMOV DX,01HCALL DISPA0: MOV CX,0008HMOV SI,OFFSET TABLE1A1: MOV AL,[SI]OUT 60H,ALCALL DALLYINC SIDEC AHJNZ L1CALL DALLCMP BX,0FFHJNZ AMOV AH,30HXOR BX,0FFFFHMOV DX,01HJMP L1A: CMP BX,OFFOOHJNZ A8MOV AH,0CHXOR BX,0FF00HMOV DX,02HCALL DISPJMP L1A8: MOV AH,18HXOR BX,0FFHMOV DX,03HCALL DISPL1: LOOP A1JMP A0 DISP: CMP DX,01HJNZ D1MOV AL,0EFHOUT 62H,ALMOV AL,0FCHOUT 61H,ALCALL TIMEMOV AL,0DFHOUT 62H,ALMOV AL,0FEHOUT 61H,ALCALL TIMEMOV AL,0BFHOUT 62H,ALMOV AL,60HOUT 61H,ALCALL TIMERETD1: CMP DX,02HJNZ D2MOV AL,0EFHOUT 62H,ALMOV AL,0B6HOUT 61H,ALCALL TIMEMOV AL,0DFHOUT 62H,ALMOV AL,66HOUT 61H,ALCALL TIMERETD2: MOV AL,0FEHOUT 62H,ALMOV AL,0FCHOUT 61H,ALCALL TIMEMOV AL,0DFHOUT 62H,ALMOV AL,0F6HOUT 61H,ALCALL TIMERETTIME: PUSH AXPUSH CXTIME1: MOV AX,0010H TIME2 : DEC AXJNZ TIME2LOOP TIME1POP CXPOP AXRET DALLY: PUSH CXMOV CX,0100H A4: PUSH AXPOP AXLOOP A4POP CXRETDALLY1: PUSH AXPUSH CXMOV CX,0002HT1: MOV AX,0010HT2: DEC AXJNZ T2LOOP T1POP CXPOP AXRETDALL: PUSH CXPUSH AXMOV CX,0300HA6: MOV AX,056CHA7: DEC AXCALL DISPJNZ A7LOOP A6POP AXPOP CXRETCODE ENDSEND START任务二:完成A/D转换实验并把转换结果显示在七段LED上显示出来。
程序代码:STACK SEGMENT STACKDW 64 DUP()STACK ENDSDATA SEGMENTTAB1 DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0FEH,0F6H,0EFH,3EH,9CH,7AH,9EH,8EH DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,ALOUT 00H,ALCALL DALLYIN AL,00HMOV BX,OFFSET TAB1PUSH AXMOV AL,80HOUT 63H,ALPOP AXPUSH AXAND AX,000FHADD BX,AXMOV AL,[BX]OUT 61H,ALMOV AL,0FEHOUT 62H,ALCALL TIMEMOV AL,0FFHOUT 62H,ALPOP AXMOV BX,OFFSET TAB1PUSH AXAND AX,00F0HSHR AL,4ADD BX,AXMOV AL,[BX]OUT 61H,ALMOV AL,0DFHOUT 62H,ALCALL TIMEMOV AL,0FFHOUT 62H,ALPOP AXJMP STARTTIME: PUSH AXPUSH CXMOV CX,0020HT1: MOV AX,0030HT2: DEC AXJNZ T2LOOP T1POP CXPOP AXRETDALLY: PUSH CXPUSH AXMOV CX,0004HA5: MOV AX,005CHA6: DEC AXJNZ A6LOOP A5POP AXPOP CXRETCODE ENDSEND 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 charucharduan[]={0xfc,0x60,0xf2,0x66,0xb6,0xbe,0 xe0,0xfe,0xf6,0xef,0x3e,0x9c,0x7a,0x9e,0 x8e}uchar wei[]={0xef,0xdf,0xbf,0x7f};ucharmoto[]={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+bu ff[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) ;}}}}实验心得:这个实训非常需要耐性和细心,只要你一个不小心,出现一个错误,你就麻烦了。