您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 单片机课程设计-智能仪器
学院:计算机科学与信息工程专业:软件工程学号:11103205姓名:高红斌日期:2013年12月1日2012-2013学年第一学期论文题目:单片机系统设计开发应用—智能仪器单片机系统设计开发应用—智能仪器一、设计要求及目的本实验通过一个单通道通用型智能仪器的软硬件系统设计,将这学期学过的单片机原理加以综合运用,以此掌握单片机应用系统的设计要领,本次试验设计的总体目标是一路电压信号输入和两路报警开关量输出控制功能,其中信号电压范围0—5VDC,AD采样分辨率8bit,数码管显示信息为:以为参数字符和三位十进制采样值,控制参数有两个,即下限报警值L和上线报警值H,当采样值大于H时,高位报警继电器接通(用LED状态灯D1亮表示);当采样值小于L时,下位报警继电器接通(用D2表示);当采样值介于L和H之间时,两路报警器功能均被解除(D1和D2均熄灭表示)二、实验环境微型计算机一台,proteus软件,keilC编译器。三、元器件列表,图表1四、实验原理本实验选用了一只六联共阴极数码管显示器,按照动态显示原理接线,其中段码通过锁存器74LS245驱动后接于P0口,位码则有反相器74LS04驱动后接于P1.0-P1.5。A/D转换器采用逐次逼近方式的芯片ADC0809,其并行数据输出端直接连接于P2口,4个控制端CLOCK,START,EOC,和OE分别接于P3.2-P3.5,采用查询法等待转换结束,转换时钟利用定时器中断产生。四个面板按键通过8位串行输入并行输出移位寄存器74LS164与单片机接口,其移位时终端与单片机的TXD引脚相连,串行数据端(1和2脚)与单片机的RXD引脚相连,串口输出功能采用汇编语言与C51语言混合编程实现。软件系统采用一个有多个功能模块构成的程序,模块之间相互依赖,他们之间的关系如图,程序有主要的两个功能模块组成——控制模块和菜单模块。这两个模块能够同时运行。这里,“同时”的意思是指用户进行菜单操作的时候,程序还能采集数据并进行控制。图表2软件系统结构组成“控制”和“菜单”这两个主要的模块都是建立在其他小模块的基础上的,比如控制模块建立在A/D转换和LED显示的基础上,菜单建立在按键检测和LED显示的基础上,而按键检测又建立在串口输出的基础上。下表列出了各个模块的主要函数。图表3各个模块的主要函数和功能五、程序源代码//main.cvoidad_init();voidcontrol_thread();voidmenu_thread();voidmain(){ad_init();while(1){menu_thread();control_thread();}}//menu.c#defineMENU_ON0#defineMENU_OFF1#defineMENU_NUM2#defineMENU_MAX999#defineMENU_MIN0unsignedcharparam_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;iMENU_NUM;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_MIN){_menu_value[_menu_idx]=MENU_MIN;}}}if(menu_status==MENU_ON){//菜单状态为开时,显示参数值print(_menu_name[_menu_idx],_menu_value[_menu_idx]);}}//ad.c#includereg51.hsbitP32=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;}//control.c#includereg51.hsbitP16=P1^6;sbitP17=P1^7;unsignedcharad();voidprint(charname,unsignedintvalue);externunsignedcharparam_value[2];externcharmenu_status;voidcontrol_thread(){//第1步:A/D转换unsignedcharvalue=ad();//第2步:根据采样值控制LED灯if(valueparam_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);}}//keyboard.c#includereg51.h#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;//无键按下时键值为-1if(_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;}//led.c#includereg51.hcharcodemap1[]={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;i10;i++){for(j=0;j10;j++){}}}voidprint(charname,unsignedintvalue){charbuf[6];chari=5;for(i=5;i1;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;i6;i++){P1&=0xC0;P1|=(1i);P0=_convert(buf[i]);delay();}}//serial.asmPUBLIC_SERIALDESEGMENTCODERSEGDE_SERIAL:MOVSCON,#0MOVSBUF,R7JNBTI,$CLRTIRETEND六、实验结果图表4程序通过编译,并且没有错误系统运行效果如图所示,参数设置状态效果如图所示。实际运行情况表明,测控与参数设置着两个环节的确是“同时”进行的。具体表现为,若参数L设置为100,某一时刻的采样值为60,那么在参数设置过程中,处于后台运行的控制程序还会使报警器D1在此时点亮。若将参数L修改为30,只要确认保存参数后,不等关闭菜单显示,D1就会熄灭了。采用并行结构编程是一种非常有用的设计思想,其要点在于可是多个程序“同时”拥有运行权限,对外表现出实时多任务的效果。这类程序的关键在于每个程序都不能这多的占用机时,因此必须设法将长时运行改为短时运行。本实验采用的运行标记设置的做法就是一个具体的体现。g1g2g3g4g5g6s0s7s6s5s4s3s2s1s0s2s2s3s4s5s6s7c0c5c4c3c2c1c0c1c2c3c4c5p20p21p22p23p24p25p26p27p10p30p31p11p32p3
本文标题:单片机课程设计-智能仪器
链接地址:https://www.777doc.com/doc-6199302 .html