1、家用电扇控制与驱动电路设计报告家用电扇控制实验与驱动电路设计一、 课程设计的目的课程设计是本科教学全过程中的重要环节。微机应用系统设计与综合实验(实践)课程设计主要培养自动化专业学生,运用所学知识解决计算机应用领域内实际问题能力,进一步提高学生运用计算机编程语言综合编程能力、程序调试技能和微机系统接口综合应用及电路设计能力。1、学习在PC系统中扩展简单的IO接口的方法。2、熟练掌握和运用汇编语言和C语言编写程序控制8255各口的输入输出,并正确带动数码管及步进电机;能熟练运用汇编和C语言实现8255的输入输出以及小键盘的输入功能,并利用软件来实现设计中对延迟的要求。3、熟练掌握在唐都实验箱上对
2、各硬件芯片的接线,并在TD_PIT+下实现对汇编程序和C程序的调试。二、 设计的题目名称及要求设计题目:小家用电扇控制实验与驱动电路设计基本设计要求: 1. 编程语言为汇编语言、C语言; 2. 控制硬件电路基于80x86微机接口电路; 3. 驱动电路(主回路)仅需设计; 4. 控制器功能包括:按钮三个,分别为风速、类型和停止,LED指示灯六个,指示风速强、中、弱,类型为睡眠、自然和正常。指标如下: 1) 电扇处于停转状态时,所有指示灯不亮,只有按下“风速”键时,才会响应,进入起始工作状态;电扇在任何状态,只要按停止键,则进入停转状态。 2) 处于工作状态时,有:初始状态为:风速-“弱”,类型-
3、正常”按“风速”键,其状态由“弱”“中”“强” “弱” 往复循环改变,每按一下按键改变一次;按“类型”键,其状态由“正常”“睡眠”“自然”“正常” 往复循环改变;3) 风速的弱、中、强对应于电扇的转动由慢到快。4) 类型的不同选择,分别为:正常电扇连续运转;自然电扇模拟自然风,即转4s,停8s;睡眠电扇慢转,产生轻柔的微风,运转 8s,停转8s;5) 按照风速与类型的设置输出相应的控制信号。附加功能扩展:1. 根据控制性能要求,同时实现了对直流电机的启动、转速及模式的调节选择和停止功能选择,并可以明显观测到电机风扇的变化。2. 实现了在数码管上实时显示直流风扇当前的工作状态。编程语言为汇编语
4、言和C语言。三、实验设备PC机一台(装有TDPIT软件)、唐都AEDK8688ET实验箱。四、设计的思想和实施方案本次课程设计的目的是小家用电扇控制实验与驱动电路设计,为了使课程设计的结果能够具有直接的可观测性。我们选择了实验箱上的直流电机作为驱动电路的控制电机。首先我得通过查阅相关资料对直流电机有个初步的了解和认识,直流电动机的工作原理:这一对电磁力形成了作用于电枢一个力矩,这个力矩在旋转电机里称为电磁转矩,转矩的方向是逆时针方向,企图使电枢逆时针方向转动。如果此电磁转矩能够克服电枢上的阻转矩(例如由摩擦引起的阻转矩以及其它负载转矩),电枢就能按逆时针方向旋转起来。因此,电枢一经转动,由于换
5、向器配合电刷对电流的换向作用,直流电流交替地由导体 ab和cd 流入,使线圈边只要处于N 极下,其中通过电流的方向总是由电刷A 流入的方向,而在S 极下时,总是从电刷 B流出的方向。这就保证了每个极下线圈边中的电流始终是一个方向,从而形成一种方向不变的转矩,使电动机能连续地旋转。这就是直流电动机的工作原理。考虑到所控制的电扇共有九种状态,其中风速分别为低速、中速和高速;类型分别为正常、自然和睡眠。故设想通过DA0832将数字量转换为模拟量,然后通过DA0832输出占空比不同的矩形波来控制和调节风扇的转速大小。再考虑到,硬件延时会增加芯片和成本,使系统过于复杂,故采用软件延时的方法。通过DA08
6、32输出电压为0,再软件延时4s或8s来改变类型,实现三种类型的改变。为了增强风扇的实时响应能力,我采用实验箱上键盘单元上的三个键来实现实时控制。1#键实现启动和风速的调节功能,2#键实现类型的调节功能,3#键实现风扇的停止功能。键盘信号的输入通过8255的PC0、PC1和PC2三个端口来实现。为了显示风扇的实时状态,我用6个LED来显示,分别代表低速、中速、高速、正常、自然和睡眠。通过8255的PA0-PA7口的输出信号(其中有两个口恒输出0,即没有使用)来控制。由于8255的B口没有使用,我考虑到利用一个七段数码显示管来显示风扇的类型,当类型为正常、自然和睡眠时数码管对应输出为1、2和3。
7、通过B口输出控制信号。同时,在电脑的屏幕上,我们设计了一个状态显示的画面,通过程序来实现。五、 系统各单元的实现及介绍1. 可编程外围接口芯片8255 图1 8255内部结构图和管脚图 图2 8255控制字格式 8255内部包含3个8位的输入输出端口A、B和C,端口A和端口B都可以用作一个8位的输入口或8位的输出口,端口C既可以作为一个8位的输入口或8位的输出口,又可以作为两个4位的输入输出口(C口上半部分和C口下半部分)使用,还可以配合A口和B口工作,分别用来产生A口和B口的输出控制信号和输入A口和B口的端口状态信号。针对电扇控制的特点,设置8255的工作方式如下:8255的A口接LED显示
8、单元的D0-D7,工作方式为0,输出;B口接数码管的A、B、C、D、E、F、G和DP,以使数码管显示电扇的类型,工作方式0,输出;C口低四位接键盘及数码管显示单元的Y1-Y4,工作方式0,输入,用来接受键盘的输入信号。8255的C口的低四位在本系统中没有用到。综上分析:初始化控制字为10000001B。2. D/A转换单元DA0832图3 D/A转换单元此次用D/A转换单元,主要是为了实现通过OUT端输出模拟电压量,实现对电扇的控制。故CS接系统总线的IOY1,OUT端接电机驱动电路的A端。3. LED灯显示单元 图4 LED电路 本次设计中,只用到D6-D4和D2-D0共六个LED灯显示状态
9、分别表示三个风速和三个状态。在接线时,我们将8255的A口与D0-D7依次连接,当相应的位输出为1时,对应的LED灯亮,为0时,则灭。4. 键盘及数码管显示单元图5 键盘及数码管电路本次设计,我们用到了第一个数码管来显示电扇转动的类型,0#、4#和8#键来控制风扇的状态。根据设计要求,将X1接地,Y1-Y3接8255的C低3口,用来输入信号。A-DP依次接8255的B口,控制数码管的显示。5. 驱动电路及直流电机单元图6 驱动电路及直流电机本次设计中,将驱动芯片的A端与DA0832的OUT端连接,+12V与直流电机1端相连,A端与2相连,其余悬空。六、硬件电路原理图及分析 图7 电扇控制硬件
10、原理图上图为用Protel DXP软件绘制的硬件电路图:该图涉及到系统总线、可编程外围接口芯片8255、键盘及数码管显示单元和直流电机及其驱动电路。1. 硬件接线及分析 设置8255的工作方式如下:8255的A口接LED显示单元的D0-D7,工作方式为0,输出;B口接数码管的A、B、C、D、E、F、G和DP,以使数码管显示电扇的类型,工作方式0,输出;C口低四位接键盘及数码管显示单元的Y1-Y4,工作方式0,输入,用来接受键盘的输入信号。8255的C口的低四位在本系统中没有用到。D/A转换单元,主要是为了实现通过OUT端输出模拟电压量,实现对电扇的控制。故CS接系统总线的IOY1,OUT端接电
11、机驱动电路的A端。本次设计中,只用到D6-D4和D2-D0共六个LED灯显示状态,分别表示三个风速和三个状态。在接线时,我们将8255的A口与D0-D7依次连接,当相应的位输出为1时,对应的LED灯亮,为0时,则灭我们用到了第一个数码管来显示电扇转动的类型,0#、4#和8#键来控制风扇的状态。根据设计要求,将X1接地,Y1-Y3接8255的C低3口,用来输入信号。A-DP依次接8255的B口,控制数码管的显示。本次设计中,将驱动芯片的A端与DA0832的OUT端连接,+12V与直流电机1端相连,A端与2相连,其余悬空。其他读写及总线端口与实验箱总线系统的相应接口连接。2.软件设计思路本设计通过
12、软件编程使8255的C口读入小键盘输入信号,再通过CPU分析,发出命令由8255的A口和B口输出信号来分别控制LED灯及数码管来显示电扇的状态。再通过对DA0832输出矩形波的占空比的控制来调节风速,而停转时间则由软件延时来实现。控制系统分四个功能模块,分别是风速设置、类型设置、默认状态运行、退出系统。提供了三个按键来进行控制,并在屏幕上实时显示状态。(1)风速设置 风速即为电机转速设置,风速分为强、中、弱三种,对应不同的电机转速。根据给DA0832输出的占空比来调节,我们可以计算出步进电机各相脉宽信号的频率和电机转速,也可以反过来根据对电机转速要求,计算并调整计算初值。具体设置占空比见表1。
13、表1风速输出00H(延迟常数)输出0ffH(延迟常数)占空比慢2001001/3中1001001/2快501002/3(2) 风的类型设置 风的类型有:正常、自然、睡眠三种。风的类型的不同选择,用flag2来记录状态:a) 正常 电扇连续运转。Flag2=1b) 自然 电扇模拟自然风,即转4s,停8s。Flag2=2c) 睡眠 电扇慢转,产生轻柔的微风,运转 8s,停转8s。Flag2=3电机的运转是DA0832的OUT端输出矩形波来控制,当DA0832输出为0时,电机停转。本次设计通过软件延时来控制电机停转的时间,从而改变电扇运行的类型。七、典型程序模块及分析1.主函数main( )首先,检
14、测小键盘的1#键是否有输入,若无输入就循环检测小键盘。当有小键盘的1#键有输入时,就赋给flag=1和flag2=1,并进入风速和类型子程序void wind_mode( )。本次程序设计的控制风扇的功能,主要在风速和类型子程序void wind_mode( )中实现。2.键盘检测子程序void key( )此子函数主要任务:当程序在风速和类型子程序void wind_mode( )运行时,实时的对小键盘进行检测,从而修改两个标志位,再返回风速和类型子程序void wind_mode( )的相应循环体运行。3.不带键盘检测的延时子程序void delay( ) 此函数主要完成,当程序在风扇运行
15、时,使OUT端输出矩形波的0时的延时,即控制矩形波的占空比。4.带键盘检测的延时子程序void delay2( )此函数主要完成:当程序在风扇类型为自然或睡眠时,实现停转4s或8s的功能,为了很好的具有键盘实时响应的功能,我们在此延迟程序中,调用了键盘检测的子程序,具有良好的实时性。5.风速和类型子程序void wind_mode( )此程序是本次程序设计的重点和难点。我们用了两个标志flag和flag2来分别标志风扇运行的风速和类型。为了使程序具有良好的可读性,我们采用了两重switch开关指令嵌套,共有9个循环体。6.图形界面状态子程序void discw( )void disss( )针
16、对风扇运行的九个状态,我们编写了九个状态屏幕显示的子程序,并用清屏函数实时刷新。八、典型编程技巧分析本次设计由于采用了较少的芯片和软件延迟方式,对程序的设计具有较高的要求。在整个程序设计中有以下几大亮点和编程技巧:1. 两个标志flag和flag2的应用,很好的解决了风扇类型和风速的嵌套调用关系,使程序更加明了且思路清晰。2. 在编写延迟程序时,编写了不带键盘检测的延时子程序void delay( )和带键盘检测的延时子程序void delay2( )两个子程序。增强了风扇的实时响应能力和延迟时间的精确性。3. 在风速和类型控制的子程序中,采用了swith语句,简化了编程,使之更加具有条理性。
17、九、课程设计中遇到的问题及解决方法1.小键盘输入出现状态多次跳变 这种情况出现在电机的加速、减速和改变转向中,这主要是在原有的键盘检测子程序中有一段判断按键是否弹起的程序,将此段换成一个合适的软件延时便可以起到很好的效果(按键不松时可以连续的加速和减速)。2. 程序调试应遵循的步骤查看各端口地址是否正确;根据程序运行中的出现的现象分析出程序出错的位置;在TDDEBUG中进行单步或设置断点进行调试;使程序有少到多有简单到复杂逐一验证其的正确性,以排除错误。2.数码管显示问题调用了数码管显示程序而却看不到数码管有示数,这主要是调用数码管显示子函数的频率不够高,可以把数码管显示子函数换个位置,或者是
18、多调用几次就可以解决了。至于数码管好像是全亮,情况正好相反,是数码管显示子函数调用的频率过高,把数码管显示子函数换个位置,或者是在关键位置调用一下延时函数就可以解决了。4.运行程序是易死机出现死机的原因很难说得清楚,有的是同一个程序换台机子运行就会死机,有的是同一台机子同一个程序运行多次就会死机,不过总的来看死机的出现多少是和所编写的程序有关,记得我以前用小键盘时就是很容易就死机了,不过在这次的课程设计中 我把所有的和小键盘有关的程序都用了子函数代替,大大简化了主程序的结构,这样就基本再也没发生过死机现象了。十、实验程序的流程图1、主程序流程图main( ) 2、风速类型子函数流程图void
19、wind_mode( )3、键盘检测子函数void key( ) 十一、程序清单及程序注释1. C语言程序 /使用芯片:08328255/风扇控制#include #include #include #include #include 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);void disc
20、w(void);void discm(void);void discs(void);void disnw(void);void disnm(void);void disns(void);void dissw(void);void dissm(void);void disss(void);/*根据查看配置信息修改下列符号值*#define IOY0 0xE400#define IOY1 0xE440/*#define MY8255_A IOY1 + 0x00*4#define MY8255_B IOY1 + 0x01*4#define MY8255_C IOY1 + 0x02*4#define
21、MY8255_MODE IOY1 + 0x03*4/*#define DA0832 IOY0 + 0x00*4char ch1,flag=1,flag2=1;extern int directvideo=1;void main()char f; outp(MY8255_MODE,0x90); outp(DA0832,0x00); printf(DC-FANn); while(1) loop1: f=inp(MY8255_A); f=f&0x07; if(f!=0x07) switch(f) case 0x06: wind_mode(flag,flag2);break; case 0x03: o
22、utp(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_weakt); outp(MY8255_MODE,0x01); /屏幕以及
23、指示灯提示风速 while(f=1) switch(f2) case 1:discw(); outp(MY8255_MODE,0x0c); outp(MY8255_MODE,0x09); outp(MY8255_B,0x30); b=1; for(a=0;ab;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:disnw(); outp(MY8255_MOD
24、E,0x08); outp(MY8255_MODE,0x0b); outp(MY8255_B,0x5b); 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_po
25、int); break; case 3:dissw(); outp(MY8255_MODE,0x0a); outp(MY8255_MODE,0x0d); outp(MY8255_B,0x4f); 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(
26、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_mediumt); /屏幕以及指示灯提示风速 outp(MY8255_MODE,0x03); while(f=2) switch(f2) case 1:discm(); outp(MY8255_MO
27、DE,0x0c); outp(MY8255_MODE,0x09); outp(MY8255_B,0x30); b=1; for(a=0;ab;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:disnm(); outp(MY8255_MODE,0x08); outp(MY8255_MODE,0x0b); outp(MY8255_B,0x5b); b=0x20
28、0000; 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:dissm(); outp(MY8255_MODE,0x0a); outp(MY
29、8255_MODE,0x0d); outp(MY8255_B,0x4f); 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; /*