微机课程设计报告-风扇控制

目录

1、         设计的题目名称及要求…………………………………   2

2、         实验设备…………………………………………………  2

3、         设计思想、实施方案和硬件电路图………………………  2

4、         典型程序模块及典型编程技巧分析………………………… 7

5、         课程设计中遇到的问题及解决方法………………………… 9

6、    实验程序的流程图…………………………………………… 10

7、    程序清单及程序注释………………………………………… 16

8、    收获与体会…………………………………………………… 42

9、    参考文献……………………………………………………… 42

一、课程设计的题目名称及要求

设计题目:家用电扇控制实验与驱动电路设计

基本设计要求:

    1. 编程语言为汇编语言和C语言;

    2. 控制硬件电路基于80x86微机接口电路;

    3. 驱动电路(主回路)仅需设计;

    4. 控制器功能包括:按钮三个,分别为风速、类型和停止,LED指示灯六个,指示风速强、中、弱,类型为睡眠、自然和正常。

指标如下:

 1) 电扇处于停转状态时,所有指示灯不亮,只有按下“风速”键时,才会响应,进入起始工作状态;电扇在任何状态,只要按停止键,则进入停转状态。

 2) 处于工作状态时,有:

初始状态为:风速-“弱”,类型-“正常”

按“风速”键,其状态由“弱”®“中”®“强” ®“弱” …… 往复循环改变,每按一下按键改变一次;

按“类型”键,其状态由“正常”®“睡眠”®“自然”®“正常” …… 往复循环改变;

3) 风速的弱、中、强对应于电扇的转动由慢到快。

4) 类型的不同选择,分别为:正常 电扇连续运转;自然   电扇模拟自然风,即转4s,停8s;睡眠    电扇慢转,产生轻柔的微风,运转 8s,停转8s;

5) 按照风速与类型的设置输出相应的控制信号。

附加功能扩展:根据控制性能要求,在“睡眠”和“自然”类型下仍可选择不同的“风速”,工作时总共有“3*3”种不同的模式,而且通过按键的分时复用可在“停止”与“工作”两种状态间反复切换而不必重载程序。

二、实验设备

PC机一台(装有TDPIT软件)、唐都TD-Pit实验箱。

三、设计的思想和实施方案

由于本次课程设计控制的对象是直流电机,在上个学期学习的《电机与电力拖动》时已知直流电机可通过改变给定电压的大小调节其转速,但实际测试时风扇的转速变化不够明显,故采用了两种方案

1、用汇编语言编写的程序通过改变电压控制直流电机的转速。

2、用C语言编写的程序采用PWM波控制直流电机的转速。

方案1较容易实施,但由于对PWM波比较陌生,方案2需要搜索了一些PWM控制方式的相关资料,所得资料如下:

PWM控制就是对脉冲的宽度进行调制的技术。即通过对一系列脉冲的宽度进行调制来等效地获得所需要波形(含形状和幅值)。在采样控制理论中有一条重要的结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同,冲量即窄脉冲的面积。效果基本相同是指环节的输出响应波形基本相同。上述原理称为面积等效原理。

简单点说,就是通过调节时间周期很小的方波的占空比就可以明显地调节直流电机的转速。

                    图1、TD-PIT直流电机及驱动电路单元

驱动电机的电压由DA0832提供,DA0832的输出OUT接驱动电路的A端,驱动电路的12V和A`端分别接直流电机的1端和2端。

图2、DA0832单元

    

解决了电机的控制问题后,课题要求有6个LED灯显示相应的风速和类型以及3个按键做相应的控制,于是本人想到了用一片8255做LED灯的驱动电路和小键盘的读取接口。

8255内部包含3个8位的输入输出端口A、B和C,端口A和端口B都可以用作一个8位的输入口或8位的输出口,端口C既可以作为一个8位的输入口或8位的输出口,又可以作为两个4位的输入输出口(C口上半部分和C口下半部分)使用,还可以配合A口和B口工作,分别用来产生A口和B口的输出控制信号和输入A口和B口的端口状态信号。

本次设计,我对8255的使用是这样的:8255工作于方式0,A口低四位接键盘及数码管显示单元的Y4-Y1;C口接LED及开关单元的LED灯D0-D7;B口和A口高四位悬空。

选择C口做LED灯的接口是因为C口能方便地通过编程置位和复位,从而方便的点亮和熄灭相应的LED信号。

图3、8255单元

键盘及数码管显示单元的X1接地,Y1对应“风速”,Y2对应“类型”,Y3对应“停止”,X2、X3、X4悬空。本次实验未用到数码管,故A、B、C、D、E、F、G、DP悬空。

图4、小键盘及数码管显示单元

图5、硬件电路总接线图

如上图示:该图涉及到系统总线、可编程外围接口芯片8255、DA0832、键盘及数码管显示单元、直流电机及其驱动电路。8255和DA0832的D0~D7 依次接系统总线的XD0~XD7,DA0832的A1和A0分别接系统总线的XA3和XA2;WR和RD 依次接系统总线上的XIOW和XIOR;8255的CS接系统总线的IOY0,DA0832的CS接系统总线的IOY1;DA0832的OUT接驱动电路的A端;8255的PC0-PC7接低八位LED。

四、典型程序模块及典型编程技巧分析

1、C语言与汇编语言的共同典型模块

(1)主函数(或主程序)MAIN

当程序运行时,PC机屏幕上显示提示菜单,完成硬件初始化——电机不转动且LED无显示,8255工作方式0、A口输入、C口输入,并等待小键盘的输入。

若①当小键盘有键按下且键值是“110(Y3\Y2\Y1)”时电机启动,PC机屏幕显示电机转动的风速强弱,LED显示风速和类型(低速、正常\PC0和PC4为1);

若②当小键盘有键按下且键值为“011”时,退出程序。

编程小技巧:将读入的A口数据与07H“与”运算可屏蔽A口其他位对输入信息的影响。

(2)不带键盘检测的延时模块DELLY

用与键盘检测时防抖。

(3)小键盘检测模块KEY

   当小键盘无输入时返回调用该模块的下一条指令,如果有小键盘输入则延时一定的时间(调用不带键盘检测的延时模块),若输入为“110”则改变风速,若输入为“101”则改变类型,若输入为“011”则停止风扇转动并熄灭LED指示灯。

(4)带键盘检测的延时模块DELLY2

    由于希望“睡眠”和“自然”类型下风扇能实时响应小键盘的控制,所以在这两种类型中的延迟用的是带键盘检测的延时模块。

2、C语言的特别模块——风扇控制集成模块WIND_MODE

本模块将风扇的转速和类型控制集于一体,先检测风速强弱的标志FLAG,再检测类型标志FLAG2,从而对直流电机和LED灯进行相应的控制。在电机的运行过程中实时调用小键盘检测模块以及时响应输入。

3、汇编语言的特别模块

汇编语言中的的风速和类型控制并不作为独立过程,而是用标号标示在主程序中,通过条件判断和跳转指令给DA0832相应的电压数字量和延时,用做标志的是LIGHT1和LIGHT2,即通过灯控信号识别直流电机的控制信号。

编程小技巧:由于灯控信号是通过8255的C口输出的,而C口可通过控制字进行置位(1)和复位(0),如果要熄灭一盏已点亮的LED灯,可将该LED对应的灯控信号(比如LIGHT1)与0EH“与”运算再输出到8255的控制字。

五、课程设计中遇到的问题及解决方法

1、直流电机的控制方式:用哪种方式能改变直流电机的转速,使其有明显的转速变化以区分“弱”、“中”、“强”三种风速是最开始遇到的问题。通过查找资料,并在实验室调节DA0832的输出(占空比不变时改变电压数字量、电压不变时改变占空比)观察风扇的转速变化,最终确定调节PWM波的占空比为有效的控制方式。

2、小键盘检测:由于采用的是软件延时,小键盘的检测究竟需要多久的延时才使程序在检测到一次按键时,刚好使风速或者类型改变一次(而不是两次或以上)是个很棘手的问题。为此曾多次调节键盘检测延时的参数,也多次由于延时不当使程序执行时造成死机。最后终于调出了合适的延时参数。

3、自然和睡眠类型下风扇需要转一会停一会,如何在风扇停转的这段延时中使风扇能实时响应小键盘的输入,这是又一个大问题。在多次调整程序的结构觉得毫无作用的时候,本人想到了增加一个带键盘检测的延时模块,从而轻松解决了该问题。

4、当按下小键盘的按键时X端和Y端的状态是低电平还是高电平直接关系到输入检测问题。通过查询TD-PIT实验平台用户手册和使用数字万用表了解了X端和Y端在按键按下时的电平状态,据此可获得所要检测的数字输入信号。

5、程序编译连接没通过,尤其是C语言,提示的错误不存在,很可能是因为函数的括号没成对出现或者某个语句缺少分号结尾而产生。或者是输入的符号用了全角或者中文输入而没注意,这些通过养成良好的编程习惯可以很大程度地避免。

6、程序在调试中没问题,可是一运行就死机,这种问题经常发生,有可能是硬件的问题,也可能是调试时不够仔细,没调试完所有功能就急着运行了。这需要仔细耐心地把程序的所有功能都调试一遍,防止意外的执行结果产生。

六、实验程序的流程图

流程图1-1:MAIN函数流程图

流程图1-2:风扇运行模式

特别说明:圆点线部分由于页面大小无法全部画出,该部分与风速标志值为“1”时只在风速上有差别(分别为‘3’对应‘强风’,‘2’对应‘中风’),未画出的两个部分和中间的部分一起构成三个分支。

流程图1-3:小键盘检测

流程图1-4:带键盘检测的延时模块

流程图1-5:不带键盘检测的延时模块

特别说明:汇编语言的程序流程和C语言的大同小异,只是标志符号有所不同。

七、程序清单及程序注释

1、C语言程序清单

//使用芯片:0832\8255

//家用风扇控制

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <ctype.h>

#include <process.h>

void key(char *f_point,char *f2_point);                       

void delay(long int time);                         //不带键盘检测的延时模块

void delay2(long int time,char *f_point,char *f2_point);   //带键盘检测的延时模块

void wind_mode(char,char);

//************************根据查看配置信息修改下列符号***************

#define  IOY0         0xC400

#define  IOY1         0xC440

//*******************************************************************

#define  MY8255_A       IOY1 + 0x00*4

#define  MY8255_B       IOY1 + 0x01*4

#define  MY8255_C       IOY1 + 0x02*4

#define  MY8255_MODE  IOY1 + 0x03*4

//*******************************************************************

#define  DA0832         IOY0 + 0x00*4

char ch1,flag=1,flag2=1;

void main()

{char f;

    

 outp(MY8255_MODE,0x90);

 outp(DA0832,0x00);

 printf("WELCOME TO USE IT!\nCHOOSE 1 TO CHANGE SPEED!I\nCHOOSE 2 TO CHANGE TYPE!\nCHOOSE 3 TO QUITE!\n");

 while(1)

 {

 loop1: f=inp(MY8255_A);

        f=f&0x07;

        if(f!=0x07)

        {switch(f)

         {case 0x06: {wind_mode(flag,flag2);break;}

          case 0x03: {outp(DA0832,0x00);flag=1;flag2=1;break;}

          case 0x05: {outp(DA0832,0x00);outp(MY8255_MODE,0x90);exit(0);break;}

         }

        }

 }

}

//*****************************风速模式******************************

void wind_mode(char f,char f2)

{long int a,b;

 char *f_point,*f2_point;

 f_point=&f;

 f2_point=&f2;

 switch(f)

 { //*******************flag=1则设置风速为弱,占空比1/3***************

  case 1: {                                      

            printf("wind_weak\t");             

            outp(MY8255_MODE,0x01);         //屏幕以及指示灯提示风速

           

            while(f==1)                     

            {switch(f2)                     

             {

              case 1:{outp(MY8255_MODE,0x0c);

                      outp(MY8255_MODE,0x09);

                      b=1;

                      for(a=0;a<b;a++)           //flag2=1,正常模式

                      {    ch1 = 0x00;

                                 outp(DA0832, ch1);

                                 delay(0x200);

             

                                 ch1 = 0xff;

                                 outp(DA0832, ch1);

                                 delay(0x100);  

                           key(f_point,f2_point);                     

                      }

                      break;                      

                     }             

              case 2:{outp(MY8255_MODE,0x08);

                      outp(MY8255_MODE,0x0b);

                      b=0x200000;

                     

                      for(a=0;a<(b/0x28);a++)           //flag2=2,自然模式

                      {    ch1 = 0x00;

                                 outp(DA0832, ch1);

                                 delay(0x200);

             

                              ch1 = 0xff;

                               outp(DA0832, ch1);

                                 delay(0x100);  

                           key(f_point,f2_point);

                                                

                           if(f2!=2||f!=1)

                           {break;}

                      }

                      if(f2!=2||f!=1)

                      {break;}

                     

                      outp(DA0832,0x00);

                      delay2(b,f_point,f2_point);

                     

                      break;                       

                     }             

                       case 3:{outp(MY8255_MODE,0x0a);

                               outp(MY8255_MODE,0x0d);

                      b=0x400000;

                     

                      for(a=0;a<(b/0x50);a++)           //flag2=3,睡眠模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x100);

             

                                     ch1 = 0xff;

                                     outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);

                   

                               if(f2!=3)    //小键盘有输入,跳出FOR循环

                               {f2=1;break;}

                               if(f!=1)

                               {break;}

                          }

                         

                          if(f2!=3||f!=1)

                          {break;}

                     

                          outp(DA0832,0x00);

                          delay2(b,f_point,f2_point);

                          if(f2!=3)

                          {f2=1;}

                     

                     

                      break;               

                                    } 

                      }               

            } 

            outp(MY8255_MODE,0x00);

            flag=f;

            flag2=f2;

            break;

          }                   

 //******************************************************************

 //*********************flag=2则风速为中,占空比1/2******************

  case 2: {   printf("wind_medium\t");            //屏幕以及指示灯提示风速

              outp(MY8255_MODE,0x03);

           

            while(f==2)

            {switch(f2)                     

             {

                  case 1:{outp(MY8255_MODE,0x0c);

                          outp(MY8255_MODE,0x09);

                          b=1;

                          for(a=0;a<b;a++)           //flag2=1,正常模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x100);

             

                                     ch1 = 0xff;

                                     outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);                     

                          }

                          break;                      

                         }             

                  case 2:{outp(MY8255_MODE,0x08);

                          outp(MY8255_MODE,0x0b);

                          b=0x200000;

                          for(a=0;a<(b/0x28);a++)      //flag2=2,自然模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x100);

             

                                  ch1 = 0xff;

                                   outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);

                                                 

                               if(f2!=2||f!=2)

                               {break;}

                             

                          }

                        

                          if(f2!=2||f!=2)

                          {break;}

                         

                          outp(DA0832,0x00);

                          delay2(b,f_point,f2_point);

                          break;                       

                         }             

                           case 3:{outp(MY8255_MODE,0x0a);

                                   outp(MY8255_MODE,0x0d);

                          b=0x400000;

                                      

                          for(a=0;a<(b/0x50);a++)    //flag2=3,睡眠模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x100);

             

                                     ch1 = 0xff;

                                     outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);

                   

                               if(f2!=3)    //小键盘有输入,跳出FOR循环

                               {f2=1;break;}

                               if(f!=2)

                               {break;}

                          }

                         

                          if(f2!=3||f!=2)

                          {break;}

                     

                          outp(DA0832,0x00);

                          delay2(b,f_point,f2_point);

                          if(f2!=3)

                          {f2=1;}

                     

                          break;               

                                           }

                      } 

                     }               

            outp(MY8255_MODE,0x02);

            flag=f;

            flag2=f2;

            break;  

          }

 //*******************************************************************

 

 //******************flag=3则风速为强,占空比2/3**********************

  case 3: {                                          

              printf("wind_strong\t");            //屏幕以及指示灯提示风速

              outp(MY8255_MODE,0x05);

            while(f==3)

            {switch(f2)                     

             {

                  case 1:{outp(MY8255_MODE,0x0c);

                          outp(MY8255_MODE,0x09);

                          b=1;

                          for(a=0;a<b;a++)           //flag2=1,正常模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x50);

             

                                     ch1 = 0xff;

                                     outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);                     

                          }

                          break;                       

                         }             

                  case 2:{outp(MY8255_MODE,0x08);

                          outp(MY8255_MODE,0x0b);

                          b=0x200000;

                          for(a=0;a<(b/0x28);a++)       //flag2=2,自然模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x50);

             

                                  ch1 = 0xff;

                                   outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);

                                                 

                               if(f2!=2||f!=3)

                               {break;}

                          }

                          if(f2!=2||f!=3)

                          {break;}

                          outp(DA0832,0x00);

                          delay2(b,f_point,f2_point);

                          break;                       

                         }             

                           case 3:{outp(MY8255_MODE,0x0a);

                                   outp(MY8255_MODE,0x0d);

                          b=0x400000;

                                      

                          for(a=0;a<(b/0x50);a++)       //flag2=3,睡眠模式

                          {    ch1 = 0x00;

                                     outp(DA0832, ch1);

                                     delay(0x50);

             

                                     ch1 = 0xff;

                                     outp(DA0832, ch1);

                                     delay(0x100); 

                               key(f_point,f2_point);

                   

                               if(f2!=3)

                               {f2=1;break;}

                               if(f!=3)

                               {break;}

                          }

                     

                          if(f2!=3||f!=3)

                          {break;}

                         

                          outp(DA0832,0x00);

                          delay2(b,f_point,f2_point);

                          if(f2!=3)

                          {f2=1;break;}

                          if(f!=3)

                          {break;}

            

                          break;               

                                           }

                      } 

                     }               

            outp(MY8255_MODE,0x04);

            flag=1;

            flag2=f2;

            break;  

          }

 //******************************************************************

 }

 return;

}

//****************************小键盘检测*****************************

void key(char *f_point,char *f2_point)                      

{char C;

   

  C=inp(MY8255_A);

  C=C&0x07;

  if(C!=0x07)

       {delay(0x10fff0);

        C=inp(MY8255_A);

        C=C&0x07;

        switch(C)

        {

         case 0x06:(*f_point)++;break;

         case 0x05:(*f2_point)++;break;

         case 0x03:outp(DA0832,0x00);outp(MY8255_MODE,0x90);(*f_point)++;break;     

       }  

       }

  return;

}

//******************************************************************

//************************不带小键盘检测的延时**********************

void delay(long int time)

{

       long int i;

       int j;

       for(i=0;i<=time;i++)

       {

              for(j=0;j<=0x100;j++)

              {  }

       }

       return;

}

//*******************************************************************

//************************带小键盘检测的延时**************************

void delay2(long int time,char *f_point,char *f2_point)

{

       long int i;

       int j;

       char f,f2;

      

       f=(*f_point);

       f2=(*f2_point);

      

       for(i=0;i<=time;i++)

       {

              for(j=0;j<=0x100;j++)

              {  }

           key(f_point,f2_point);

           if((*f_point)!=f||((*f2_point)!=f2))

           {return;}

       }

       return;

}

//******************************************************************

2、汇编语言程序清单

;***************根据CHECK配置信息修改下列符号值*******************

        IOY0  EQU       0E400H      ;片选IOY0对应的端口始地址

        IOY1  EQU       0E440H      ;片选IOY1对应的端口始地址

;*****************************************************************

    MY8255_A  EQU       IOY1+00H*4  ;8255的A口地址

    MY8255_B  EQU       IOY1+01H*4  ;8255的B口地址

    MY8255_C  EQU       IOY1+02H*4  ;8255的C口地址

 MY8255_MODE  EQU     IOY1+03H*4  ;8255的控制寄存器地址

      DA0832  EQU       IOY0+00H*4  ;DA0832的端口地址

     

     

      STACK1  SEGMENT   STACK       ;堆栈段定义

              DW        256 DUP(?)

      STACK1  ENDS

        DATA  SEGMENT

          LA  DB        ?           ;定义数据变量

          LB  DB        ?

          LC  DB        ?

      LIGHT1  DB        ?

      LIGHT2  DB        ?

         MES  DB        'WELCOME TO USE IT!',0DH,0AH,'INPUT 1 TO CHANGE SPEED!',0DH,0AH,'INPUT 2 TO CHANGE STYLE!',0DH,0AH, 'INPUT 3 TO QUITE!' ;定义字符串

              DB        0DH,0AH,'$'

        DATA  ENDS

        CODE  SEGMENT

              ASSUME    CS:CODE,DS:DATA

      START:  MOV       AX,DATA

              MOV       DS,AX

                    

              MOV       DX,OFFSET  MES

              MOV       AH,9                    ;显示字符串

              INT       21H

            

              MOV       AX,DATA

              MOV       DS,AX

              MOV       DX,MY8255_MODE       ;定义8255工作方式

              MOV       AL,90H      ;工作方式0,A、B、C口为输出

              OUT       DX,AL

                  

              MOV       DX,DA0832         ;写DA0832端口起始数据

              MOV       AL,00H

              OUT       DX,AL

         LL:  MOV       DX,MY8255_A   

;按1键则进入起始工作状态,否则等待重新按键

              IN        AL,DX

              AND       AL,07H

              CMP       AL,07H

              JNE       NEXT0

              JMP       LL

      NEXT0:  CALL      DELLY

              IN        AL,DX

              AND       AL,07H

              CMP       AL,07H

              JE        LL

              CMP       AL,06H

              JE        LOOP0

              CMP       AL,03H

              JNE       NEXT

              JMP       QUIT

       NEXT:  JMP       LL

      LOOP0:  MOV       DX,MY8255_MODE    ;写C口发出的起始数据

              MOV       AL,01H

              MOV       LIGHT1,AL

              OUT       DX,AL

             

              MOV       DX,MY8255_MODE

              MOV       AL,09H

              MOV       LIGHT2,AL

              OUT       DX,AL

                                     

         

              MOV       DX,DA0832             ;DA0832起始工作状态

              MOV       AL,73H

              OUT       DX,AL

             

              MOV       LC,AL

             

  

           

           

         L1:  MOV       AL,LIGHT1

               

              CMP       AL,01H

              JE        RUO         

              CMP       AL,03H

              JE        ZHONG

              CMP       AL,05H

              JE        QIANG

              CALL      KEY

                                       

          A:  MOV       AL,LIGHT2       ;1001 1011 1101

              CMP       AL,0DH          ;正常 自然 睡眠

              JE        SHUIMIAN

              CMP       AL,0BH

              JNE       NEXT2

              JMP       ZIRAN

      NEXT2:  JMP       ZHENGCHANG

             

        RUO:  MOV       AL,01H         

              MOV       LIGHT1,AL

              MOV       DX,MY8255_MODE

              OUT       DX,AL

              MOV       AL,73H          ;写DA0832端口数据,风速为弱风

              MOV       DX,DA0832

              OUT       DX,AL

              MOV       LC,AL

              MOV       AL,LIGHT2

              CMP       AL,0DH

              JE        SHUIMIAN

              CMP       AL,0BH

              JNE       X

              JMP       ZIRAN

          X:  JMP       ZHENGCHANG

   

      ZHONG:  MOV       AL,0A5H      ;写DA0832端口数据,风速为中

              MOV       DX,DA0832

              OUT       DX,AL

              MOV       LC,AL

              JMP       A

     

      QIANG:  MOV       AL,0FFH     ;写DA0832端口数据,风速为强

              MOV       DX,DA0832

              OUT       DX,AL

              MOV       LC,AL

              JMP       A

         L2:  MOV       AL,LIGHT2       ;指示灯指示风的类型

              CMP       AL,0DH

              JE        LB1

             

              AND       AL,0EH

              MOV       DX,MY8255_MODE

              OUT       DX,AL

                    

              MOV       AL,LIGHT2

              ADD       AL,2

              MOV       LIGHT2,AL

              OUT       DX,AL

             

              CMP       AL,0BH

              JNE       X2

              JMP       ZIRAN

         X2:  JMP       SHUIMIAN

            

        LB1:  AND       AL,0EH

              MOV       DX,MY8255_MODE

              OUT       DX,AL

            

              MOV       AL,09H

              MOV       LIGHT2,AL

              OUT       DX,AL

              JMP       ZHENGCHANG

   SHUIMIAN:  MOV       AL,LIGHT2       ;睡眠风子程序

              MOV       DX,MY8255_MODE

              OUT       DX,AL

            

              MOV       AL,LC           ;写DA0832端口数据

              MOV       DX,DA0832

              OUT       DX,AL

             

              CALL      DELLY2           ;软件延时,持续4秒

             

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R1

              JMP       L1                             

         R1:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT1

              JMP       A   

           

        RT1:  CALL      DELLY2

     

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R2

              JMP       L1                             

         R2:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT2

              JMP       A   

            

        RT2:  MOV       AL,00H      ;写DA0832端口数据

              MOV       DX,DA0832

              OUT       DX,AL

           

              CALL      DELLY2       ;软件延时,持续8秒

            

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R3

              JMP       L1                             

         R3:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT3

              JMP       A   

            

        RT3:  CALL      DELLY2

            

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R4

              JMP       L1                              

         R4:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT4

              JMP       A   

          

        RT4:  CALL      DELLY2

            

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R5

              JMP       L1                             

         R5:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT5

              JMP       A   

          

        RT5:  CALL      DELLY2

         

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        R6

              JMP       L1                             

         R6:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        RT6

JMP       A          

RT6:  JMP       SHUIMIAN

             

   

      ZIRAN:  MOV       AL,LIGHT2       ;自然风子程序

              MOV       DX,MY8255_MODE

              OUT       DX,AL

            

              MOV       AL,LC           ;写DA0832端口数据

              MOV       DX,DA0832

              OUT       DX,AL

              CALL      DELLY2          ;软件延时,持续4秒

             

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        T1

              JMP       L1                              

         T1:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        TT1

              JMP       A   

         

        TT1:  CALL      DELLY2

              

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        T2

              JMP       L1                             

         T2:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        TT2

              JMP       A   

       

       

        TT2:  MOV       AL,00H          ;写DA0832端口数据

              MOV       DX,DA0832

              OUT       DX,AL

             

              CALL      DELLY2          ;软件延时,持续4秒

             

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        T3

              JMP       L1

         T3:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        TT3

              JMP       A

             

        TT3:  CALL      DELLY2

             

              MOV       BL,LA

              CMP       BL,LIGHT1

              JE        T4

              JMP       L1

         T4:  MOV       BL,LB

              CMP       BL,LIGHT2

              JE        TT4

              JMP       A

        TT4:  JMP       ZIRAN

     

 ZHENGCHANG:  MOV       AL,LIGHT2       ;正常风 子程序

              MOV       DX,MY8255_MODE

              OUT       DX,AL

              MOV       AL,LC           ;写DA0832端口数据

              MOV       DX,DA0832

              OUT       DX,AL

             

              CALL      KEY

              JMP       L1

                

       QUIT:  MOV       AX,4C00H    ;返回到DOS

              INT       21H

       DELLY  PROC      NEAR        ;软件延时子程序

              MOV       CX,0E000H

         D1:  MOV       AX,0A000H

         D2:  DEC       AX

              JNZ       D2

              LOOP      D1

              RET

       DELLY  ENDP

       DELLY2 PROC      NEAR

              MOV       BL,LIGHT1

              MOV       LA,BL

              MOV       BL,LIGHT2

              MOV       LB,BL

              MOV       CX,0F000H

         K1:  MOV       AX,0FFFFH   

         K2:  DEC       AX

              JNZ       K2

              CALL      KEY

              MOV       BL,LA

              CMP       BL,LIGHT1

              JNE       BACK

              MOV       BL,LB

              CMP       BL,LIGHT2

              JNE       BACK

              LOOP      K1

       BACK:  RET

       DELLY2 ENDP

         KEY  PROC      NEAR

              MOV       DX,MY8255_A

              IN        AL,DX

              AND       AL,07H

              CMP       AL,07H

              JNE       G1

              RET

         G1:  CALL      DELLY

              IN        AL,DX

              AND       AL,07H

              CMP       AL,07H

              JNE       G2

              RET

         G2:  CMP       AL,06H            

;若在延迟中按下1键,则改变风速的灯光信号

              JNE       G3

              MOV       AL,LIGHT1

              AND       AL,0EH

              MOV       DX,MY8255_MODE

              OUT       DX,AL

              MOV       AL,LIGHT1

              ADD       AL,2

              CMP       AL,05H

              JBE       N1

              MOV       AL,01H       

         N1:  MOV       LIGHT1,AL

              OUT       DX,AL

              RET

         G3:  CMP       AL,05H           

  ;若在延迟中按下2键,则改变类型的灯光信号

              JNE       G4

              MOV       AL,LIGHT2

              AND       AL,0EH

              MOV       DX,MY8255_MODE

              OUT       DX,AL

              MOV       AL,LIGHT2

              ADD       AL,2

              CMP       AL,0DH

              JBE       N2    

              MOV       AL,09H

         N2:  MOV       LIGHT2,AL

              OUT       DX,AL

              RET

         G4:  CMP       AL,03H

 ;若在延迟中按下3键,则调用‘停止’子程序

              JNE       G5

              CALL      STOP

              RET

         G5:  RET

         KEY  ENDP         

    STOP      PROC      NEAR            ;电扇停止状态时的数据写入

              MOV       DX,MY8255_MODE    ;指示灯熄灭     

             

              MOV       AL,LIGHT1

              AND       AL,0EH

              OUT       DX,AL

                          

              MOV       AL,LIGHT2

              AND       AL,0EH

              OUT       DX,AL

             

              MOV       DX,DA0832          ;风扇停转

              MOV       AL,00H

              OUT       DX,AL

             

              MOV       AL,01H              ;灯控标志复位

              MOV       LIGHT1,AL

              MOV       AL,09H

              MOV       LIGHT2,AL

              JMP       LL

              RET

              

STOP      ENDP  

 CODE      ENDS

                END       START

八、收获与体会

本次课程设计,总的来说完成的还比较顺利,在原来实验课程的基础上更进一步的学习了在pc机系统中扩展简单程序的方法,进一步学习了用汇编和C语言编写程序的设计方法,通过对各功能模块进行详细设计,并进行充分的测试,最终实现了直流电机的调速和LED指示功能,功能虽然比较完善,但仍有可以改进的地方,比如可以进一步运用闭环PID控制实现风扇的转速给定和测量(尽管对家用风扇来说这没很大的必要),这要在以后的学习中,进一步的补充。

通过这次实验我学会了灵活应对实验中的各种错误和故障(比如死循环、接线出错、符号格式不正确等等),始终冷静地分析和排除出现错误的各种原因,这当然离不开老师的亲切教导,从而最终完成了实验。再有以前对C语言的一些标准库函数不太了解,通过实践,使我在这个方面的认识有所提高。通过实践的学习,我认识到学好计算机要重视实践操作,要多做课题,才能增长实战中的经验。

通过这次设计实验我养成了多动手、多思考、多询问的好习惯,并加深了对汇编语言和C语言的理解,提高了运用自己的头脑和双手、运用现有的资源解决问题的能力,增强了对知识的融会贯通能力。在实验中,通过与老师、同学的讨论,通过网上查找资料,更加深刻的理解了直流电机、8255和DA0832芯片功能的应用,更进一步的熟悉了教材有关内容。看着自己头脑里的知识换成实验台上完整的系统模块时,那种喜悦无法比拟。更重要的是通过本次实验课程设计,让我对本专业的更充满了学习热情!

九、参考文献

1.吴秀清,周荷琴.《微型计算机原理与接口技术》(第二版).中国科学技术大学出版社.2003

2.《TD-PIT实验教程》.西安唐都科教仪器公司.2005

3.《TD-PIT用户手册》 西安唐都科教仪器公司.2005

 4.彭鸿才.《电机原理及拖动》.机械工业出版社.2005

相关推荐