单片机课程设计智能仪器.docx
- 文档编号:25259700
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:15
- 大小:250.56KB
单片机课程设计智能仪器.docx
《单片机课程设计智能仪器.docx》由会员分享,可在线阅读,更多相关《单片机课程设计智能仪器.docx(15页珍藏版)》请在冰豆网上搜索。
单片机课程设计智能仪器
2012-2013学年第一学期
论文题目:
单片机系统设计开发应用—智能仪器
学院:
计算机科学与信息工程
专业:
软件工程
学号:
姓名:
高红斌
日期:
2013年12月1日
单片机系统设计开发应用—智能仪器
一、设计要求及目的
本实验通过一个单通道通用型智能仪器的软硬件系统设计,将这学期学过的单片机原理加以综合运用,以此掌握单片机应用系统的设计要领,本次试验设计的总体目标是一路电压信号输入和两路报警开关量输出控制功能,其中信号电压范围0—5VDC,AD采样分辨率8bit,数码管显示信息为:
以为参数字符和三位十进制采样值,控制参数有两个,即下限报警值L和上线报警值H,当采样值大于H时,高位报警继电器接通(用LED状态灯D1亮表示);当采样值小于L时,下位报警继电器接通(用D2表示);当采样值介于L和H之间时,两路报警器功能均被解除(D1和D2均熄灭表示)
二、实验环境
微型计算机一台,proteus软件,keilC编译器。
三、元器件列表,
图表1
四、实验原理
本实验选用了一只六联共阴极数码管显示器,按照动态显示原理接线,其中段码通过锁存器74LS245驱动后接于P0口,位码则有反相器74LS04驱动后接于。
A/D转换器采用逐次逼近方式的芯片ADC0809,其并行数据输出端直接连接于P2口,4个控制端CLOCK,START,EOC,和OE分别接于,采用查询法等待转换结束,转换时钟利用定时器中断产生。
四个面板按键通过8位串行输入并行输出移位寄存器74LS164与单片机接口,其移位时终端与单片机的TXD引脚相连,串行数据端(1和2脚)与单片机的RXD引脚相连,串口输出功能采用汇编语言与C51语言混合编程实现。
软件系统采用一个有多个功能模块构成的程序,模块之间相互依赖,他们之间的关系如图,程序有主要的两个功能模块组成——控制模块和菜单模块。
这两个模块能够同时运行。
这里,“同时”的意思是指用户进行菜单操作的时候,程序还能采集数据并进行控制。
图表2
软件系统结构组成
“控制”和“菜单”这两个主要的模块都是建立在其他小模块的基础上的,比如控制模块建立在A/D转换和LED显示的基础上,菜单建立在按键检测和LED显示的基础上,而按键检测又建立在串口输出的基础上。
下表列出了各个模块的主要函数。
图表3
各个模块的主要函数和功能
五、程序源代码
//
voidad_init();
voidcontrol_thread();
voidmenu_thread();
voidmain()
{
ad_init();
while
(1)
{
menu_thread();
control_thread();
}
}
//
#defineMENU_ON0
#defineMENU_OFF1
#defineMENU_NUM2
#defineMENU_MAX999
#defineMENU_MIN0
unsignedcharparam_value[]={100,150};
unsignedcharmenu_status=MENU_OFF;
char_menu_name[]={'L','H'};//参数名的符号
unsignedchar_menu_value[]={0,0};//供显示用的参数数组
unsignedchar_menu_idx=0;//参数序号
charget_key();
voidprint(charname,unsignedintvalue);
voidmenu_thread(void)
{
chari=0;
charkey=get_key();
if(menu_status==MENU_OFF)
{
//当前菜单为关闭状态时
if(key==0)
{//若按键0已被按下
menu_status=MENU_ON;//置当前菜单为打开状态
_menu_idx=0;//设置参数序号0
//将所有参数当前值取出,送入供显示的参数数组中
for(i=0;i { _menu_value[i]=param_value[i]; } } }else{ //如果当前菜单为打开状态,则进行以下操作: if(key==0) { //若按键0按下,则不保存键值,仅切换到下一个参数 if(++_menu_idx==MENU_NUM) {//判断是否所有参数都循环到了 menu_status=MENU_OFF;//若已循环完成,设置菜单关闭状态 } }elseif(key==1) { //若按键1按下,则保存键值,并切换到下一个参数 param_value[_menu_idx]=_menu_value[_menu_idx]; if(++_menu_idx==MENU_NUM) { menu_status=MENU_OFF; } }elseif(key==2){ //若按键2按下,则参数值加10 _menu_value[_menu_idx]+=10; if(_menu_value[_menu_idx]>MENU_MAX){ _menu_value[_menu_idx]=MENU_MAX; } }elseif(key==3){ //若按键3按下,则参数值减10 _menu_value[_menu_idx]-=10; if(_menu_value[_menu_idx] _menu_value[_menu_idx]=MENU_MIN; } } } if(menu_status==MENU_ON){ //菜单状态为开时,显示参数值 print(_menu_name[_menu_idx],_menu_value[_menu_idx]); } } // #include<> sbitP32=P3^2; sbitP33=P3^3; sbitP34=P3^4; sbitP35=P3^5; sbitP37=P3^7; unsignedcharad(){ P33=0; P33=1; P33=0; while(! P34); P35=1; returnP2; } voidad_init(){ TMOD=0x02; TH0=0; TL0=0; ET0=1; TR0=1; EA=1; } void_ad_clock(void)interrupt1{ P32=~P32;} // #include<> sbitP16=P1^6; sbitP17=P1^7; unsignedcharad(); voidprint(charname,unsignedintvalue); externunsignedcharparam_value[2]; externcharmenu_status; voidcontrol_thread(){ //第1步: A/D转换 unsignedcharvalue=ad(); //第2步: 根据采样值控制LED灯 if(value>param_value[1]){ P16=0; P17=1; }elseif(value<=param_value[1]&&value>=param_value[0]){ P16=0; P17=0; }else{ P16=1; P17=0; } //第3步: 如果菜单是关闭的,显示采集到的数值 if(menu_status==1){ print('',value); } } // #include<> #defineCHECK_KEY_DOWN0//处在检测按键压下阶段标志 #defineCHECK_KEY_UP1//处在检测按键抬起阶段标志 #defineKEY_UP0//按键抬起标志 #defineKEY_DOWN1//按键压下标志 sbit_p33=P3^3; sbit_p34=P3^4; sbit_p35=P3^5; sbit_p36=P3^6; char_key_status=CHECK_KEY_DOWN;//按键检测状态(初值为检测压下阶段) char_key_idx=0;//按键序号 voidserial(charbyte); char_check_key(unsignedchar_key_idx){//检查按键状态 serial(~(0x01<<_key_idx));//将待查按键键码转换成扫描码后输出 if(_p36==0){//根据P36状态决定返回值 returnKEY_DOWN; }else{ returnKEY_UP; } } charget_key(void){ charresult=-1;//无键按下时键值为-1 if(_key_status==CHECK_KEY_DOWN){//如果当前处于检查压下阶段,进行以下操作 if(_check_key(_key_idx)==KEY_DOWN){//判断当前扫描键的状态,若为压下标志则 _key_status=CHECK_KEY_UP;//将检查阶段标志设置为抬起 }else{//否则,将检查阶段标志设置为压下 if(++_key_idx==4){//判断是否4个按键已经轮流扫描一遍 _key_idx=0;//是,则将待扫描按键号设为0 } } }elseif(_key_status==CHECK_KEY_UP){//如果当前处于检查抬起阶段,进行以下操作 if(_check_key(_key_idx)==KEY_UP){//判断当前扫描键的状态,若为抬起标志则 result=_key_idx;//键值输出 _key_status=CHECK_KEY_DOWN;//按键检查阶段标志改为压下 if(++_key_idx==4){//判断是否4个按键已经轮流扫描一遍 _key_idx=0;//是,则将待扫描按键号设为0 } } } returnresult; } // #include<> charcodemap1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; charcodemap2[]={0x00,0x76,0x38}; char_convert(charc){ if(c=='') returnmap2[0]; elseif(c=='H') returnmap2[1]; elseif(c=='L') returnmap2[2]; elseif(c>='0'&&c<='9') returnmap1[c-'0']; return0; } void_delay(){ inti=0,j=0; for(i=0;i<10;i++){ for(j=0;j<10;j++){ } } } voidprint(charname,unsignedintvalue){ charbuf[6]; chari=5; for(i=5;i>1;i--){ buf[i]='0'+value%10; value/=10; if(value==0){ break; } } i--; for(;i>=1;i--){ buf[i]=''; } buf[0]=name; for(i=0;i<6;i++){ P1&=0xC0; P1|=(1< P0=_convert(buf[i]); delay(); } } // PUBLIC_SERIAL DESEGMENTCODE RSEGDE _SERIAL: MOVSCON,#0 MOVSBUF,R7 JNBTI,$ CLRTI RET END 六、实验结果 图表4 程序通过编译,并且没有错误 系统运行效果如图所示,参数设置状态效果如图所示。 实际运行情况表明,测控与参数设置着两个环节的确是“同时”进行的。 具体表现为,若参数L设置为100,某一时刻的采样值为60,那么在参数设置过程中,处于后台运行的控制程序还会使报警器D1在此时点亮。 若将参数L修改为30,只要确认保存参数后,不等关闭菜单显示,D1就会熄灭了。 采用并行结构编程是一种非常有用的设计思想,其要点在于可是多个程序“同时”拥有运行权限,对外表现出实时多任务的效果。 这类程序的关键在于每个程序都不能这多的占用机时,因此必须设法将长时运行改为短时运行。 本实验采用的运行标记设置的做法就是一个具体的体现。 图表5 测控状态运行效果 图表6 参数设置状态运行效果 七、总结 通过本次试验,我发现了自己对学习单片机和做实验中存在两个主要缺点: 一是依赖性很大,刚开始编程序时喜欢套用书上的语句,希望从书上找到源代码,但是当我从别处找来源代码时,却很难读懂别人写的代码,也就是对语句的理解不够。 于是当我在调试程序控制protues仿真软件时出现了很多的问题,而我也不知道该怎么样修改,因为眼前的程序都是自己写的和别人写的拼凑起来的,没有很清楚的理解哪些代码控制哪些功能,没法知道哪里错了。 但是经过我不断的改错,看c语言书,最后终于调试出来了,通过实验我发现编程是一件很严肃的事情,容不得半点错误。 二是基础知识的薄弱,在用C语言编程时,才发现自己C语言真的太差劲了,虽然这门课程我在大一下学期早就学过,但是就目前所掌握的C语言知识,对于单片机编程远远不够。 C语言也是我们以后学各种语言的基础,必须要花大量的时间温习强化。 在通过本次课程中,我遇到很多问题,但是与此同时,我们也学到了很多,对我以后的学习会产生影响: 不管做什么事,计划是很重要的;做事要多动脑,选出最好的方法;要注意细节。 细节决定成败;最后,也是最重要的一点,通过这次课题,我们学到了很多有关单片机方面的知识,也对单片机有了更深入的了解。 使我们受益匪浅。 在电子技术应用领域中,单片机的应用愈来愈多地应用到各行各业。 要开发单片机的应用,不但要掌握单片机硬件和软件方面的知识,而且还要深入了解各应用系统的专业知识,融会贯通和有机结合,才能设计出优良的应用系统。 培养自己接受新知识的自学能力,掌握芯片发展动态。 培养自己的创新精神,在原有的基础上进行改进,使之功能不断完善。 当然,最重要到还是态度,无论做什么事情,足够认真,足够坚强,足够毅力,足够决心,足够勇气,就一定能办到。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 课程设计 智能 仪器