微型计算机控制技术课程设计报告二阶电压跟踪 单片机Word下载.docx
《微型计算机控制技术课程设计报告二阶电压跟踪 单片机Word下载.docx》由会员分享,可在线阅读,更多相关《微型计算机控制技术课程设计报告二阶电压跟踪 单片机Word下载.docx(23页珍藏版)》请在冰豆网上搜索。
![微型计算机控制技术课程设计报告二阶电压跟踪 单片机Word下载.docx](https://file1.bdocx.com/fileroot1/2023-1/26/effa6070-0660-42e4-8f45-a69445e2d1eb/effa6070-0660-42e4-8f45-a69445e2d1eb1.gif)
我们采用实验箱上的4×
4键盘作为系统输入,实验箱读取按键后,得到一个给定值,系统通过A/D读取二阶环节的电压并与给定值比较,采取控制并将输出值通过D/A送给二阶环节。
整个过程中需要用的读键程序、D/A、A/D转换程序、LED显示程序、滤波程序、控制计算程序……
2.2.3设计人机交互接口(键盘)
由于任务要求信号参数可通过人机交互接口设置,我们讨论后设计在LED上显示输入的信息。
通过4×
4键盘输入控制信号。
按键设置为‘0’到‘9’十个按键加上负号、小数点和确认这三个按键。
2.2.4精度要求
对于精度≤±
5%,调节时间≤25秒的设计要求,我们决定在软件调试时通过修改各参数来完成。
2.3硬件设计
本次课程设计中最为重要的硬件设计任务是信号数据采集系统的搭建。
数据采集系统是由单片机和硬件接口电路组成,硬件接口电路主要由采样保持器、A/D转换电路、输入接口电路、D/A转换电路、控制逻辑电路输出接口电路等组成。
其工作过程是:
由机接收电路模拟信号,将模拟信号送到采样保持电路进行采样;
当单片机启动A/D转换电路转换时,采样保持电路处于保持状态,并把信号送给A/D转换电路实现模拟量到数字量的转换;
A/D转换结束后,将送出一结束信号,该信号可产生已中断请求或供单片机查询,同时采样/保持电路进入采样状态,单片机由输入接口电路读取模拟信号并进行一次转换数据。
当单片机向D/A转换电路输出数据时,D/A转换电路输出一个与输出数据对应的模拟电压。
硬件电路就是选取合适的电子器件和芯片,设计成满足系统速度、精度和可靠性等技术要求的电路接口,使单片计算机能按要求完成上述工作过程。
其次,按键键盘功能设计也是重要的,不同的键盘设计带给编程的难度是不同的,具体功能的体现也是有差别的。
本次课程设计需要用到的硬件系统还有闭环控制系统。
其实闭环控制系统硬件组成与数据采集系统基本相同,主要由模拟输入通道、模拟输出通道和被控对象等组成。
图2.3.1就是此次设计过程中一个很重要的硬件模块,即二阶环节系统:
图2.3.1二阶环节
2.4软件设计
相同于硬件设计,软件设计也大体分为两个部分,及采集系统和闭环控制系统。
因为此次课程设计的主要任务是完成闭环控制系统的软件设计,而且采集系统的软件设计可以包括在闭环控制系统的步骤里。
除了必须达到采集系统的要求外,闭环控制系统的软件设计还必须有控制算法程序和更强的数据处理能力。
其实一个控制系统的控制过程可归纳为以下3个步骤:
1.实时数据采集:
即对被控参数的瞬时值进行测量。
2.实时决策:
对表征被控对象状态的测量值进行分析,并按已定的控制规律进行控制。
3.实时控制:
根据决策,实施对控制机构发出控制信号。
控制程序的运行必须满足以上控制过程,同时控制算法是使被控参数尽快达到给定值,并能将被控参数随时间的变化情况在屏幕上显示出来。
参考程序流程图如图3所示。
该程序由初始化和数据采集,数据滤波,标度变换,LED显示,D/A输出,控制程序和等子程序构成。
各子程序功能为:
(1)数据采集:
连续采集12个数据,每采集一个数据,去掉最前面一个数据。
(2)数字滤波:
具体方法是对12个数据取平均值
(3)标度变换:
函数voidsymbol()将数字滤波后的采样值按比列换成与实际输入对应的模拟电压毫伏值,然后存放在数据缓冲区。
(4)LED显示:
函数voiddisplay()显示给定值和跟踪电压值。
(5)控制决策:
函数voidpid()对给定值与真实值的误差进行比例、积分和微分运算,得到本次控制值,存放在输出缓冲区。
(6)D/A输出:
D/A输出程序是将当前输出缓冲区数据输出到D/A转换器端口。
(7)检查按键:
函数voidkeyscan()检查是否有键按下,以确定给定值为多少。
如有键按下,读取键值,是确定键键就表示输入完毕。
2.5调试完善程序
相关硬件及软件设计完成后,最后的主要工作就是调试运行程序,并达到设计任务要求的精度。
整个过程就是不断地修改相关参数并调试运行,已达到理想效果。
调试完善程序之后,我们便开始着手撰写课程设计报告。
3、心得体会
计算机控制原理的课程设计刚刚结束,微型计算机控制的课程设计接踵而至。
这次我们面对的实际控制对象更接近于我们的生活了,我突然感觉到了我积累了的知识终于有了用武之地了。
我很兴奋,但兴奋的同时我也感觉得到此次课程设计的重要性,眼前的难题是我们分到了单片机类型的控制。
虽然平时比较擅长软件设计的我此时也感到一丝丝压力,因为我们小组决定要用已经一年多没有用过的C语言编写程序,虽然当时我学习C语言的时候很认真。
而且我自认为当时学得很不错的,但毕竟有一年多没有用了,不经有点生疏了。
周一,我们满怀激情的来到了单片机实验室。
我们没有着急马上动手做实验,而是检查起了我们的实验设备是否能正常工作。
我们把给的实例程序写到了单片机里,导线也连接了,当我们运行时,发现实验设备无法正常工作,起初我们还怀疑过是不是实例程序出了问题。
同时我们也在认真的检查我们的线路连接,当然,我们并没有发现问题。
就这样,迷迷糊糊的周一就这样过去了,一点收获也没有。
周二,我们又调试了其他实例程序,发现用lcd显示的时候,是能够正常显示的。
但我们问了一下和我们做同一个项目的组员,他们也没有多大的进展。
这下我心里稍微舒缓了一下,然后听他们说着实验设备有些老化,不能得到正确的结果就可能是这个原因了,我现在也只能这样想了,我决定先用proteus仿真一下。
下午一回到宿舍就开始搭建实验电路了,但当我用搭建好的实验电路仿真时,发现也不能正常的运行。
这下我一下子就懵了,我不知道到底是我搭建的电路有问题,还是程序出现了问题。
我努力的在网上查找资料,关于仿真软件的运用,还有就是查找软件的错误,但到了晚上十点多了,还是没有找到结果。
周三,没有任何进展,还是在查找proteus仿真的错误,还是没有任何的进展。
很快,到了晚上,有些小组已经换到了计算机硬件机房,用另外一套设备了。
到了我们小组抉择的时候了,我们到底是继续选择留在单片机机房,还是换机房用新的设备。
最后通过小组决定,我们还是决定留下了,我们不能退缩,面对这点困难。
但说实话,目前为止我们还是没有任何进展,此时,不经心里有点着急了,一周的课程设计我们已经花了大半的时间了。
剩下的两天时间,我们能做出结果吗?
我真的无从知晓。
周四,我们又来到了单片机机房,今天老师考虑到了导线老化的原因,终于为我们换了一批导线。
用新的导线接上,实例程序能正常工作了。
我一下子来了精神,当天上午我完成了我的指定任务,调试也完全没有问题。
我也分配给了小组成员不同的子程序,这样希望能尽快完成我们的任务,毕竟我们的时间已经不多了。
下午我们进行了A/D转换模块的调试,这模块的调试遇到了一些麻烦。
到了晚上,A/D模块仍然没有任何进展。
周五,很早就来到了实验室,这是我们最后一天了,我们要抓紧时间了,其他小组已经陆续答辩了,这无形给了我们很大的压力,但是压力就是动力。
到了中午的时候,终于调试出了A/D模块功能。
现在主要是PID算法和D/A模块了,下午我们早早就完成了D/A模块的调试,我们不敢休停半刻,我们着手PID的调试。
现在回想起来,这个模块是最伤脑筋的模块了,我们一直调试到晚上十点了,此时就剩下四组了。
最让我感到温暖的是,老师也在同我们并肩作战,虽然到最后还是没有调试出来,但老师看到我们那依依不舍的样子,决定星期六再给我们半天的时间。
这消息对我们无疑是雪中送炭。
周六,花了两个小时,终于把结果弄出来了,我们一周的课程设计也算告一段落了。
现在总结一下,我觉得主要是我们定义的数据类型出了问题。
一开始我们考虑到要用到小数点,所以定义浮点类型数据,编译时发现地址溢出。
我们只能将有些数据改为其他类型,但运算时出现了问题。
还有就是c语言用负数计算时,有可能会出错,最好用正数进行运算。
当然计算时也要考虑数据溢出的问题。
总之,通过这次课程设计,我懂得了如何用软件实现pid控制,同时对pid的原理也有了更清晰的认识。
本次微型计算机控制我们的课程设计题目是二阶环节电压跟踪控制系统的设计(采用单片机教学实验系统的)。
由于本次的时间比较紧只有一周的时间,再加上要使用单片机无疑增加了难度。
为了能很好的完成任务小组成员都花了不少时间复习单片机和计算机控制的知识,并自行研究课题设计如何做。
在对题目有一定的了解基础后我们小组开始展开讨论,确定和设计系统框图并分配好任务,通力完成。
题目要求我们设计一个控制器输出作用于电路输入IN使得电路输出能够跟踪-5~5V范围内的任意阶跃信号,这就需要我们的程序设计中要包含有A/D转换、标度变换、D/A转换、PID控制算法以及显示与键盘等模块。
在明确好各个模块后我分配到的是标度转换模块然后协助其他组员完成其他模块。
微型计算机控制系统在读入被测模拟信号后需要转换成数字量,变成操作人员所熟悉的数值并显示出来,这就是标度变换模块所要气的作用。
本次课题我们要A/D转换读入电压值并转成0~255中的数字量。
-5~5V的电压转成0~255相应的数字量我们采用的是线性标度转换,把它带入相应的标度变换公式,再用程序语言表示出来即可,再接下来就是把相应的数字量一位一位分离出来再在LED显示管上显示出来。
在复习过单片机和计算机控制后很快就完成了这模块的编程。
在经过漫长的编程后,终于把每个模块都初步完成,再接下来我们就一起进行联调。
一开始,小错误不断,在我们仔细排错下对多处地方进行了调整修改后键盘、显示、A/D转换、D/A转换都能够顺利的工作,但在整块一起调试以后我们的结果却出不来,我们的PID控制一直没起到控制的效果,输出电压总是维持在5V处,没有跟随输入变化。
我们经过多次排查甚至多次改控制算法都没能解决问题的算在。
最后我们实在没办法,只能请老师来协助我们。
在老师的协助下我们调出各个模块单步调试,观察变量变化看是否按照程序在准确执行,最终老师帮我们找到了原因:
我们都数据类型定得太乱了,一会整型一会浮点数的,计算出来的数值一直有错。
在老师的建议下我们改动程序,统一把数值定为整型,解决了我们的困扰。
最后我们一起对控制算法进行调整,先是值进行比例控制确定了一个比较合适的参数,再加入微分环节加快了调节时间,接着引入积分环节消除静差。
在经过一周的努力我们成功的完成了课题,并且有不错的控制效果,输出在经过很多的调节时间后进入稳定,并且已输入的误差只有0.03V左右。
在这次课程设计中我们小组遇到了很多困难,在我们相互帮助团结协作下才得以完成。
这短短的几天时间了让我感受到了团结合作的重要性,以及遇到困难要敢于冲击敢于挑战,只有这样你才能走得跟远,取得成功。
相信在今后的学习生活中这次课程设计的经历将对我有很大的帮助。
在这次短暂的一个星期的学习和设计中,我和我的队友们一起合作完成了二阶环节电压跟踪控制系统的设计任务。
二阶环节电压跟踪控制系统可以用C语言编写,因此程序简洁,易于阅读。
在这次课程设计中,我负责的主要是A/D转换功能的实现和编写报告。
设计完了程序则该轮到调试了,各个模块进行独立的调试。
调试是一件很需要耐心的工作,同时也需要相当的仔细。
也许只是稍微写漏了一句语句也会耽搁相当大的时间。
尤其是当设计者被调试扰乱了思维的时候更应该静下心来仔细阅读程序,检验自己的逻辑是否有误。
这些都是需要慢慢学习的。
这次程序的设计构思没有多大问题,但是当调试的时候,总是出现运算的错误,经老师的指导,才发现原来不同类型的数据运算结果会出现相当多的问题,这在编程时应多加注意。
当问题被一个个解决之后,我们终于看到了希望。
整个系统能够跟踪二阶环节的电压。
虽然精度还有不足,但我们已经向成功迈进。
接下来则是对程序进行控制算法的优化,减小静差。
总之,在这次的课程设计中,我学习到了很多的东西,感觉自己终于能够将所学的知识跟实际应用联系到了一起。
深刻认识到了自己的动手能力以及知识的熟悉程度等方面的欠缺。
这还需要进行大量的练习才行。
我们组本次计算机控制技术课程设计的题目是二阶电压跟踪控制系统的设计,我们班采用的是抽签的方式分配题目,当我们接到这个题目的时候顿时傻眼了。
不想选这个题目,原因有两个:
第一,对于这种抽象的控制对象,设计起来比较枯燥;
第二,采用单片机系统,也就是要用到忘了很久C语言,这无异于增加了编程的难度。
说实话,经过一个假期之后,计算机控制技术和单片机的知识,到现在我已经忘得差不多了。
本来学习的时候就学得不是很好,为了不拖大家的后腿,我用周末的时间把计算机控制技术和单片机的书粗略的过了一遍,把支离破碎的知识重新拾起在脑海里。
星期一,早上八点半,我们准时来到了实验室。
我们几个理清了所有的功能和流程,一个上午我们把整个的流程图画出来了,再用了下午跟晚上的时间修改整理出来了主程序,和各个模块的流程图。
第三天,我们把主程序和各个模块的流程图用专业工具画了出来。
然后进行了任务分工,由于我编程水平一般,所以没有分配到特别复杂的模块,我分配到的是PID和DA模块。
乍一看,我的任务太简单了,我最初也这么以为,可是当我真正着手干的时候我才发现,各种各样的问题都来了。
首先DA,我是通过老师给的参考程序来学习的,程序很短,只有几行,可是我怎么也搞不懂那个地址是怎么来的,自己想了很久还是没有想出来,最终还是通过同学才弄懂了。
其次,是PID,PID乍一看一点都不难,只是按书上把公式表达出来就行了,这也是最后最困扰我们的地方,就在这个问题上面我们就弄了两天,最终拖到星期六才答辩。
其实PID我们在程序的思想上面完全没有问题,包括其他地方也是,大家往往在大的思想上面都不会出错,小的地方很多时候才是最致命的地方。
本次设计,我(包括我的队友)犯错在了变量的类型上了。
还好有王老师的帮助,才让我们从错误的泥沼中抽身出来,在这里要特别感谢王老师。
在我们组的小错误上面花了太多时间,同时我们我们也会总结经验,争取以后都不再犯同类型的错误。
在设计和调试的过程中我们遇到了各种各样的问题,还好我们相互帮助,相互提醒,相互鼓励,最终完成了这次的设计。
这次的设计不仅让我复习了计算机硬件基础的基本知识,还让我学会了理论与实际的结合,最重要的是我体会到了一个团队的力量。
四、参考文献
【1】《计算机硬件技术基础》—杨天怡等主编—重庆大学出版社
【2】《计算机硬件技术基础实验教程》—黄勤等主编—重庆大学出版社
【3】《单片微型计算机与接口技术》—李群芳等主编—电子工业出版社
【4】《计算机控制技术》—王建华等主编—高等教育出版社
五、附录
5.1系统框图
5.2电原理图
图5.2.1系统电源理图
5.3程序流程图
5.4程序清单
/******************************************************/
/*文件名:
KeyScan.c*/
/*功能描述:
控制8255完成键盘扫描及数码显示实验*/
#include<
SST89x5x4.h>
Absacc.h>
intrins.h>
stdio.h>
#defineC8255_AXBYTE[0x7FFC]//8255端口地址定义
#defineC8255_BXBYTE[0x7FFD]
#defineC8255_CXBYTE[0x7FFE]
#defineC8255_CONXBYTE[0x7FFF]
#definead574_0XBYTE[0x7f00]
#definead574_1XBYTE[0x7f08]
//数码管显示编码
unsignedchara[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,
0x40,0x5c,0x1c,0x78};
//40为负号
//显示缓冲
unsignedcharb[]={11,11,11,11,11,11};
unsignedcharc[]={0x5c,0x1c,0x78};
//显示out超出范围
unsignedchard[]={0,0,0,0,0,0};
//传递真实值floatset_value
//unsignedinte[11]={0};
unsignedcharf[3]={0};
//存取个十百数据
unsignedcharkey_down;
unsignedcharkey_value;
unsignedcharkey_count;
unsignedcharkey_v_mflag=0;
unsignedcharkey_v_pflag=0;
//小数点和负号标志
sbitda_cs=P2^0;
sbitda_wr=P2^1;
longintadvalue;
longintset_value=-2000;
longintsym_fruit;
longintad_fruit;
longintek,ek1,eki,ekd;
longintout;
longintadv_fruit;
//求取12次转换结果
intkp=1,kd=5,ki=1;
voiddisplay();
voiddelay(unsignedinttime);
voidclear();
voidwritebuffer();
voidgetkey();
//得到按键值
voidcmp_value();
voidkeyscan();
//按键扫描函数
voidconfirm_value();
voidadcge();
voidadcge12();
voidsymbol();
//标度变变换
voidadave();
////////////////////////////////////中断服务程序
voidint_timer0()interrupt1
{
TH0=0xb1;
//初始化定时器0
TL0=0xe0;
display();
clear();
}
/////////////////////////////////ad574
voidsymbol()//标度变变换
{
sym_fruit=advalue*625;
sym_fruit=sym_fruit/256;
sym_fruit=sym_fruit-5000;
ad_fruit=sym_fruit;
if(sym_fruit>
=0)
{b[2]=11;
sym_fruit/=100;
b[0]=(char)sym_fruit%10;
sym_fruit/=10;
b[1]=(char)sym_fruit%10;
b[1]+=20;
//将第三位加上小数点
}
else
{sym_fruit*=-1;
//要将负数变为正数,否则显示会出错
sym_fruit/=10;
//将第三位加上小数点
b[2]=30;
voidadcge()
unsignedcharHbyte,Lbyte;
delay(100);
Hbyte=ad574_0;
//读取AD转换结果的高8位
Lbyte=ad574_1;
//读取AD转换结果的低8位
advalue=(((unsignedint)Hbyte)<
<
4)|((Lbyte&
0xf0)>
>
4);
//转换结果
voidpid()
{ekd=ek;
ek=set_value-ad_fruit;
//ek
eki+=ek;
ek1=ek*kp*0.8+ki*eki*0.001+kd*(ek-ekd);
if(ek1>
5000)
ek1=5000;
if(ek1<
-5000)
ek1=-5000;
out=(ek1+5000);
out=out*255;
out/=10000;
da_cs=0;
da_wr=0;
P1=(char)(out);
voiddisplay()
unsignedchari,j=0xDF;
for(i=0;
i<
6;
i++)
{
C8255_A=0xFF;
C8255_B=a[b[i]];
//查表输出显示
C8255_A=j;
delay(0x100);
j=(j>
1)|(j<
7);
voiddelay(unsignedinttime)
unsignedinti;
time;
i++);
voidkeyscan()//按键扫描函数
unsignedcharcc;
C8255_A=0x00;
//X1~X4
cc=C8255_C;
//得到Y1~Y4的值
key_down=(~cc)&
0x0f;
voidclear()//清屏
C8255_B=0x00;
voidwritebuffer()
key