当前位置:文档之家› 单片机课程设计-智能仪器

单片机课程设计-智能仪器

2012-2013学年第一学期论文题目:单片机系统设计开发应用一智能仪器学院:计算机科学与信息工程专业:软件工程学号:姓名:高红斌日期:2013年12月 1日单片机系统设计开发应用—智能仪器一、设计要求及目的本实验通过一个单通道通用型智能仪器的软硬件系统设计,将这学期学过的单片机原理加以综合运用,以此掌握单片机应用系统的设计要领,本次试验设计的总体目标是一路电压信号输入和两路报警开关量输出控制功能,其中信号电压范围0—5VDC AD采样分辨率8bit ,数码管显示信息为:以为参数字符和三位十进制采样值,控制参数有两个,即下限报警值 L 和上线报警值H当采样值大于H时,高位报警继电器接通(用LED 状态灯D1亮表示);当采样值小于L时,下位报警继电器接通(用D2表示);当采样值介于L和H之间时,两路报警器功能均被解除(D1和D2均熄灭表示)实验环境元器件列表,*+JeP■ep里片机系统设计开发应用—智能仪器屮元器件満单*[74LSO41PRES PPOT-H屏MAXL241PLED-YELLO^*J CRYSTALPCAF-ELEEBUTTON-'AT89C51^ADC0809^AEC080&-'74LS245P74LS161IEC^74LS04^74HC59&^7SEG-WG-CC-BUJE^图表1四、实验原理本实验选用了一只六联共阴极数码管显示器,按照动态显示原理接线,其中段码通过锁存器74LS245驱动后接于P0 口,位码则有反相器74LS04驱动后接于。

A/D转换器采用逐次逼近方式的芯片ADC0809其并行数据输出端直接连接于 P2 口,4个控制端CLOCK,START,EO和,OE分别接于,采用查询法等待转换结束,转换时钟利用定时器中断产生。

四个面板按键通过8位微型计算机一台, proteus 软件,keilC编译器串行输入并行输出移位寄存器 74LS164与单片机接口,其移位时终端与单片机的TXD引脚相连,串行数据端(1和2脚)与单片机的RXD引脚相连,串口输出功能采用汇编语言与 C51语言混合编程实现。

软件系统采用一个有多个功能模块构成的程序,模块之间相互依赖,他们之间的关系如图,程序有主要的两个功能模块组成――控制模块和菜单模块。

这两个模块能够同时运行。

这里,“同时”的意思是指用户进行菜单操作的时候,程序还能采集数据并进行控制。

图表2软件系统结构组成“控制”和“菜单”这两个主要的模块都是建立在其他小模块的基础上的,比如控制模块建立在 A/D转换和LED显示的基础上,采单建立在按键检测和 LED显示的基础上,而按键检测又建立在串口输出的基础上。

下表列出了各个模块的主要函数。

图表3各个模块的主要函数和功能五、程序源代码// void ad」n it();void con trol_thread();void menu _thread();void mai n()ad_init();while (1){menu_thread();control_thread();}}//#define MENU_ON 0#define MENU_OFF 1#define MENU_NUM 2#define MENU_MAX 999#define MENU_MIN 0unsigned char param_value[] = {100, 150};char _menu_name[] = {'L','H'}; // 参数名的符号unsigned char menu_status = MENU_OFF;unsigned char _menu_value[] = {0,0}; // 供显示用的参数数组unsigned char _menu_idx = 0; // 参数序号char get_key();void print(char name, unsigned int value);void menu_thread(void){char i = 0;char key = get_key();if (menu_status == MENU_OFF){// 当前菜单为关闭状态时 if (key == 0)// 若按键 0 已被按下menu_status = MENU_ON; // 置当前菜单为打开状态_menu_idx = 0; // 设置参数序号 0// 将所有参数当前值取出,送入供显示的参数数组中for (i = 0 ; i < MENU_NUM ; i++){_menu_value[i] = param_value[i];}}} else{// 如果当前菜单为打开状态,则进行以下操作:if (key == 0){// 若按键 0 按下,则不保存键值,仅切换到下一个参数if (++_menu_idx == MENU_NUM){ // 判断是否所有参数都循环到了menu_status = MENU_OFF; // 若已循环完成,设置菜单关闭状态}} else if (key == 1){// 若按键 1 按下,则保存键值,并切换到下一个参数param_value[_menu_idx] = _menu_value[_menu_idx];if (++_menu_idx == MENU_NUM) {menu_status = MENU_OFF;}} else if (key == 2) {// 若按键 2 按下,则参数值加 10_menu_value[_menu_idx] += 10;if (_menu_value[_menu_idx] > MENU_MAX) {menu_value[_menu_idx] = MENU_MAX;} else if (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]);}}// #include <> sbit P32 = P3八2;sbit P33 = P3A3;sbit P34 = P3A4;sbit P35 = P3A5;sbit P37 = P3A7; unsigned char ad() { P33 = 0;P33 = 1;P33 = 0;while(!P34);P35 = 1;return P2;}void ad_init() {TMOD = 0x02;TH0 = 0;TL0 = 0;ET0 = 1;TR0 = 1;EA = 1;}void _ad_clock(void) interrupt 1 {P32 = ~P32;}//#include<>sbit P16=P1A6;sbit P17二PM7;unsigned char ad();void print(char name, unsigned int value); extern unsigned char param_value[2]; extern char menu_status;void control_thread() {//第1步:A/D转换unsigned char value = ad();//第2步:根据采样值控制LED灯if (value > param_value[1]) {P16 = 0;P17 = 1;} else if (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 <>#define CHECK_KEY_DOWN 0 段标志#define CHECK_KEY_UP 1段标志#define KEY_UP 0#define KEY_DOWN 1sbit _p33 = P3八3;sbit _p34 = P3A4;sbit _p35 = P3A5;sbit _p36 = P3八6;// 处在检测按键压下阶// 处在检测按键抬起阶// 按键抬起标志// 按键压下标志char _key_status = CHECK_KEY_DOWN; // 按键检测状态(初值为检测压下阶段)char _key_idx = 0; // 按键序号void serial(char byte);char _check_key(unsigned char _key_idx) { // 检查按键状态serial(~(0x01<<_key_idx)); // 将待查按键键码转换成扫描码后输出if (_p36 == 0) { //根据P36状态决定返回值return KEY_DOWN;} else {return KEY_UP;}} char get_key(void) {char result = -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 }}} else if (_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 }}}return result;}// #include<>char codemap1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};char code map2[]={0x00,0x76,0x38};char _convert(char c){ if(c==' ')return map2[0];else if(c=='H')return map2[1];else if(c=='L')return map2[2];else if(c>='0'&&c<='9')return map1[c-'0'];return 0;}void _delay(){int i=0,j=0;for(i=0;i<10;i++){ for(j=0;j<10;j++){}}void print(char name, unsigned int value) { char buf[6];char i = 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 << i);P0 = _convert(buf[i]);delay();}}//PUBLIC _SERIALDE SEGMENT CODERSEG DESERIAL:1MOVscoz #0MOVSBURR7JNBT「SCLRT-RETENDF「 = 丿 逵乍・S H 6W ・aALlADd hJ cb密I I T L fl H s t d筑和耳审丘耳2世$kM 3F Jnig&VHairvc--ATEi- a Fr 'E i rl^?Brevet呢^也F l lb i I O E1-*'s n 审l£n丹% ydp■ -LJ1IX A c Q [ff s d 及一啊情*辭苗挪K字空誉 '宦血曲a ¥瞥莎已3 i e E ^3l 堆k T ・llef「»a^4&weiMUIT U?T ・^・ J|[Im 诃宦©d E-p1-凶专芸T u p bs莎33 E個-阿L h-DITW-J1-E C口斗u h--E 諾g 5r h■a -l^k^bcdnd.c,1r書F hT ・ErnainxQJPUI WirdlJrt ttll l l i l业-ta&el:・-|431说专1・ D m ee 口b 1 l口也 ⑷IARTUP-A51 ・: 乳c M P M J a l i E n Q n pi l i H g n o s n p -l」i s qn l3:Tlp.l1l b g lQ 营p H l K-ug nolmpiliTig m ILJJ 卓■ I b二s1 1口一 ■p h ag b'B J l m -l K q Brdnto-=2.E ・!3Md 口一.CLhun口d nz i a:业 UnlreAtiRIg he-N File 「com=9H a 0d ・・- r Q M H sg Mg 】用 蛊 m lg ba @・一莎史 n 05J .-s - * 」『F T-” 】fL L E -n ■:-n - i B contlTD l-h --- k ^y tr d q r d- c-・-IMlmn ・:「山 ETiw1・ 05g h l<a IL刃鱼耳5一IE 1\E;2m =l e E}r y丁耳:町T dLT$呂艮i I L i -rt-10voidaQritrl I l l i一tua u t o ・ 「voidB d L i a.T crlll 014图表 4程序通过编译,并且没有错误系统运行效果如图所示,参数设置状态效果如图所示。

相关主题