基于单片机的智能仪器综合设计实验
- 格式:doc
- 大小:757.50 KB
- 文档页数:16
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语言混合编程实现。
软件系统采用一个有多个功能模块构成的程序,模块之间相互依赖,他们之间的关系如图,程序有主要的两个功能模块组成——控制模块和菜单模块。
这两个模块能够同时运行。
这里,“同时”的意思是指用户进行菜单操作的时候,程序还能采集数据并进行控制。
基于单片机智能RLC测试仪的设计毕业设计摘要本文主要论述了基于凌阳SPCE061A单片机的智能RLC测试仪的设计,利用单片机对R、L、C等参数进行测量,可以充分利用单片机的运算和控制功能,方便地实现测量,使测量精度得到提高。
同时用软件程序代替一些硬件测量电路,可在硬件结构不变的情况下,修改软件以增加新的功能。
能够很好的完成对RLC参数的测量,以满足现代测控系统的需要。
关键词:单片机;SPCE061A;RLC测试仪ABSTRACTIt is mainly discussed in this paper that the design of intellectual RLC parameter measurer based on Lingyang SPCE061A MCU. MCU use of R, L, C, and other parameters measured, can take full advantage of MCU processing and control functions, to facilitate the realization of measurements for improved measurement accuracy. Simultaneously uses the software procedure to replace some hardware metering circuits, may in the hardware architecture invariable situation, revi se software to increase the new very good completing to the RLC parameter survey, satisfy the modern observation and control system the need.Keywords: MCU;SPCE061A;RLC testing device目录摘要 (I)ABSTRACT (II)目录 (III)前言 (V)1 系统测试原理与总体方案设计 (1)RLC测试原理 (1)相位+有效值测量 (1)相位+有效值测量方案的软仿真 (2)RLC参数测量方法 (3)总体设计方案 (4)系统原理框图 (4)整个系统工作流程 (4)系统设计中的难点和关键技术 (5)2 RLC测试仪硬件部分实现 (6)-5V电源的设计 (6)标准正弦信号发生模块 (6)标准正弦信号的原理 (6)AD9850芯片简介 (8)AD9850硬件电路图及单片机程序 (9)3 I-V变换模块 (11)I-V变换方案设计 (11)I-V变换的硬件电路 (11)4 同时采样模块 (12)同时采样模块方案设计 (12)A/D芯片的选择 (12)ADS7861芯片介绍 (13)ADS7861转换时序的逻辑控制 (13)5 单片机系统设计 (16)SPCE061A单片机概述 (16)单片机的电源设计 (16)SPCE061A最小系统 (17)6 RLC测试仪应用软件设计 (18)数据采集模块程序流程图 (18)中断程序流程图 (19)主程序流程图 (19)结论 (21)参考文献 (22)致谢 (23)附录 (24)前言随着微电子技术、计算机技术、软件技术的高度发展及其在电子测量技术与仪器上的应用,新的测试理论、新的测试方法、新的测试领域以及新的仪器结构不断出现,在许多方面已经冲破了传统仪器的概念,电子测量仪器的功能和作用发生了质的变化。
桂林理工大学信息学院实习报告实习名称:电子系统设计创新与实践设计题目:基于单片机的智能台灯设计专业班级:姓名:学号:组员:指导老师:实习时间:目录1概述 (3)1.1 题目名 (3)1.2 功能和技术指标要求 (3)1.3 国内外相关情况概述 (3)1.4 调光技术的选择 (4)2. 技术方案 (5)2.1 光照强度检测传感器的基本原理介绍 (5)2.2 总体技术方案 (5)3 硬件设计 (6)3.1 总体电路原理图 (6)3.2 各模块分别介绍 (7)3.2.1 MSP430G2553单片机模块 (7)3.2.2 BISS0001 人体红外感应模块热释电传感器 (8)3.2.3光敏电阻控制模块 (11)3.2.4 光敏电阻的应用 (12)3.3 灯光控制模块 (12)3.4 PWM调光说明 (13)3.5 硬件调试 (13)3.5.1 调试方法 (13)3.5.2 调试步骤 (14)4. 软件设计 (15)4.1 软件功能说明 (15)4.2 软件总流程 (15)4.3 软件测试 (15)5. 性能测试 (16)5.1 测试方法 (16)5.2 给出相应记录 (16)5.3 对实验数据进行分析以及提出相应的改进办法 (17)6.总结 (17)附录(程序清单):................................................. 错误!未定义书签。
参考文献: (18)1概述1.1 题目名基于单片机的智能台灯设计1.2 功能和技术指标要求本项目针对台灯的节电和使用的方便性进行创新设计与研究,以单片机为核心,综合运用热释电红外、光检测等技术,设计制作出智能型多功能LED台灯。
该台灯具有自动开、关,自动调光等功能,实现了LED的亮度随周围光照强度的变化而变化。
本设计一智能台灯控制器,实现照明控制系统的人性化,即当亮度足够时灯光关闭,在亮度不足时,有人走近自动点亮,并根据周围环境的亮度自动调节灯泡的功率的节能环保的智能型LED台灯的设计理念。
北京邮电大学基于DS18B20和PT100的温度计的研究与设计实验报告姓名:班级:学号:学院:信息与通信工程学院指导老师:葛顺明摘要本设计为一个基于PIC32MX795F512L单片机的温度计,利用键盘按键来选择温度传感器的线路。
能够实时将数据传至液晶屏和电脑显示。
根据单片机的工作原理,通过硬件电路制作和软件编译,设计出一个能够双路实时显示的温度计。
该系统主要由液晶显示模块、键盘模块、温度传感器模块以及串口模块组成。
设计利用MPLAB软件对温度计源程序进行编译和调试。
可以进行数字和模拟两种方式得到相应的温度值并进行两种方式的优缺点比较。
关键词:PIC32MX795F512L单片机,模块,模拟,数字。
SUMMARYThe design for a thermometer based on PIC32MX795F512L microcontroller, using the keys on the keyboard to select the temperature sensor circuit. Real time data to the LCD screen and a computer display. According to the working principle of the single-chip hardware circuit production and software compiler design a two-way real-time display of the thermometer. The system mainly consists of the LCD module, keyboard module, temperature sensor module, and serial modules. Design thermometer source code to compile and debug using MPLAB software. Can be both digital and analog manner to give the corresponding temperature value, and the advantages and disadvantages of the two methods of comparison.KEY WORDS:PIC32MX795F512L microcontroller module, analog and digital.目录一,引言 4二,背景介绍 52.1 PIC32系列单片机简介52.2 DS18B20温度传感器52.3 PT100温度传感器82.4 LCD1602 82.5 4*4键盘92.6 串口与MAX232 102.7 MPLAB简介11三,设计总体方案和研究意义113.1系统模块图113.2 研究意义11四,每部分具体实施:121.DS18B20温度传感器部分122. ADC模数转换部分183. LCD1602部分184.键盘部分195. 串口部分20五,实验遇到的问题及心得体会20 六,实验源代码21七,参考文献33一,引言现在可以说单片机是百花齐放,百家争鸣的时期,世界上各大芯片制造公司都推出了自己的单片机,从8位、16位到32位,数不胜数,应有尽有,有与主流C51系列兼容的,也有不兼容的,但它们各具特色,互成互补,为单片机的应用提供广阔的天地。
基于单片机的智能仪器综合设计实验一、实验目的在实验一~实验三的基础上,完成综合设计实验,学会信号采集、数据处理、键盘控制、LCD或LED显示等功能的智能仪器设计。
二、复习与参考实验一~实验三三、设计指标利用K分度号热电偶进行温度检测,测温范围为500-1200ºC,室温为20ºC,用LCD或LED显示室温和测量温度。
具有4路温度信号循环检测功能,通道切换时间可调;具有任意指定通道显示功能。
四、实验要求1.选择传感器,设计硬件电路,包括检测电路、信号调理电路、AD转换电路、单片机最小系统、LED显示(单号)、LCD显示(双号)、独立式按键,画出电路原理图。
2.画出软件流程图。
3.用Keil C51编写程序。
3.实验结果在LCD或LED上显示出来。
4.实验前完成第1、2项备查。
五、实验仪器设备和材料清单PC机;单片机实验板、连接导线、ST7920图形液晶模块Keil c51软件六、实验成绩评定方法实验成绩包括预习、实验完成质量、实验报告质量3部分组成,各部分所占比例分别为30%、40%、30%。
八、实验报告要求实验报告格式:●实验名称●实验目的●实验内容●硬件设计●软件设计●调试过程●参考文献●附1:电路原理图●附2:程序清单附录:实验程序源代码如下:(陈寅)#include "reg51.h"#define THC0 0xee //5ms时间常数设置#define TLC0 0x00sbit ADWR=P3^6; /***WR*****/sbit ADRD=P3^7; /***RD*****/sbit ADCS=P2^7; /***CS*****/sbit EOC=P3^3; /***EOC****/sbit ADA=P1^3; //通道选择引脚sbit ADB=P1^4;sbit ADC=P1^5;sbit CS =P1^0; /****************/sbit SID=P1^1; /**液晶引脚定义**/sbit SCLK=P1^2; /****************/sbit MODE=P2^0; /*************************/sbit UP=P2^1; /*四个按键接口,0表示按下*/sbit DOWN=P2^2; /*************************/sbit LED1=P2^3; /**4个LED灯引脚定义**/sbit LED2=P2^4; /********************/sbit LED3=P2^5; /********************/sbit LED4=P2^6; /********************//***************500~1200°C范围的K分度表,间隔10*******************/ unsigned int code K_TABLE[71]={20644,21066,21493,21919,22346,22772,23198,23624,24050,24476,24902,25327,25751,26176,26599,27022,27445,27867,28288,28709,29128,29547,29965,30383,30799,31214,31629,32042,32455,32866,33277,33686,34095,34502,34909,35314,35718,36121,36524,36925,37325,37725,38122,38519,38915,39310,39703,40096,40488,40897,41296,41657,42045,42432,42817,43202,43585,43968,44349,44729,45108,45486,45863,46238,46612,46985,47356,47726,48095,48462,48828}; unsigned char GetAdData[10]={0}; //存放获得AD值的数组变量unsigned char ViewTemperature[4]={"0000"}; //显示温度缓冲数组变量unsigned MODESelect=1;int ChangeTime=2; //通道切换时间,单位Sint TongDao=1;void delay(unsigned int j){unsigned char i;do{for(i=0;i<100;i++);}while(j--);}void send_command(unsigned char command_data) //发送命令{unsigned char i;unsigned char i_data;i_data=0xf8; //操作命令,可以查看资料delay(10);CS=1;SCLK=0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data=i_data&0x0f;i_data<<=4;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}void send_data(unsigned char command_data) //发送数据{unsigned char i;unsigned char i_data;i_data=0xfa; //操作命令,可以查看资料delay(10);CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data=i_data&0x0f; //取低四位i_data<<=4; //左移四位,从而变成高四位for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}void InitLCD() //液晶初始化{send_command(0x30); //功能设置:一次送8位数据,基本指令集send_command(0x06); //点设定:显示字符/光标从左到右移位,DDRAM地址加1send_command(0x0c); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x04); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x01); //清DDRAMsend_command(0x02); //DDRAM地址归位send_command(0x80); //把显示地址设为0X80,即为第一行的首位}/* x,y为起始座标x(0<=x<=3),y(0<=y<=7),x为行座标,y为列座标;how为要显示汉字的个数;style为显示字符的类型,0表汉字,1表字母;str是要显示汉字的地址*/void Display(unsigned char x,unsigned char y,unsigned char how,bit style,unsigned char *stri) //液晶显示{unsigned char hi=0;if(x==0) send_command(0x80+y);else if(x==1) send_command(0x90+y);else if(x==2) send_command(0x88+y);else if(x==3) send_command(0x98+y);if(style==0){for(hi=0;hi<how;hi++){send_data(*(stri+hi*2));send_data(*(stri+hi*2+1));}}elsefor(hi=0;hi<how;hi++) send_data(*(stri+hi));}float LvBo(void)//复合滤波{unsigned char max,min,i;unsigned int sum=0;float U1;max=GetAdData[0];min=GetAdData[0];for(i=0;i<10;i++){sum=sum+GetAdData[i];if(max<GetAdData[i]) max=GetAdData[i];if(min>GetAdData[i]) min=GetAdData[i];}sum=sum-max-min;U1=(float)sum/8;U1=10.0*((U1*5.0)/255); //换成mvreturn U1;}void search (void)//查表子函数{unsigned int da=0,max,min,mid,j;unsigned int var;da=LvBo()*1000; //u1扩大1000倍da=da+798; //20度max=71;min=0;var=0;while(1){mid=(max+min)/2; //中心元素位置if(K_TABLE[mid]==da) {var=mid*10;break;} //中心元素等于查表元素,计算相应温度else if(K_TABLE[mid]>da) max=mid-1;else min=mid+1;if(max-min==1) /*线性插值计算温度值*/{j=(K_TABLE[max]-K_TABLE[min])/10; /*表中相邻两值对应温度相差10°C*/j=(da-K_TABLE[min])/j;var=10*min+j;break;}if(max==min){if(da>=K_TABLE[min]){j=(K_TABLE[min+1]-K_TABLE[min])/10;j=(da-K_TABLE[min])/j;}else if(da<K_TABLE[min]){j=(K_TABLE[min]-K_TABLE[min-1])/10;j=(da-K_TABLE[min-1])/j;min=min-1;}var=10*min+j;break;}}var=var+500;ViewTemperature[0]=var/1000+0x30;ViewTemperature[1]=var/100%10+0x30;ViewTemperature[2]=var/10%10+0x30;ViewTemperature[3]=var%10+0x30;}void LcdDisplay(void){unsigned char ViewMODESelect,ViewTongDao[5]={"0 "},ViewChangeTime[5]={"00(S)"};ViewMODESelect=MODESelect+0x30;ViewTongDao[0]=TongDao+0x30;if(MODESelect==1||MODESelect==2){if(MODESelect==1) Display(0,3,5,0,":自动切换");else if(MODESelect==2) Display(0,3,5,0,":手动切换");Display(0,0,2,0,"模式"); //液晶显示Display(0,2,1,1,&V iewMODESelect);Display(1,0,5,0,"温度通道:");Display(1,5,5,1,V iewTongDao);Display(2,0,4,0,"温度值:");Display(2,4,4,1,V iewTemperature);Display(2,6,2,1,"℃");}else if(MODESelect==3){ViewChangeTime[0]=ChangeTime/10+0x30;ViewChangeTime[1]=ChangeTime%10+0x30;Display(0,0,2,0,"模式");Display(0,2,1,1,&V iewMODESelect);Display(0,3,5,0,":设置时间");Display(1,0,5,0,"切换时间:");Display(1,5,5,1,V iewChangeTime);Display(2,0,14,1," "); //本行清屏}}void TDSelect(void) //AD通道设置{if(TongDao>=5) TongDao=1;if(TongDao<=0) TongDao=4;if(TongDao==1) {ADC=0;ADB=0;ADA=0;}else if(TongDao==2) {ADC=0;ADB=0;ADA=1;}else if(TongDao==3) {ADC=0;ADB=1;ADA=0;}else if(TongDao==4) {ADC=0;ADB=1;ADA=1;}}main(){unsigned char AdCount=0; //用来存放AD采集次数InitLCD();TMOD=0x11; //定时器0初始化TH0=THC0;TL0=TLC0;TR0=1;ET0=1;EA=1;P2|=0x07; //按键初始为高while(1){ADWR=1; /************/ADCS=0; /************/ADWR=0; /**AD初始化**/ADWR=1; /************/while(!EOC); //等待转换结束ADRD=0;GetAdData[AdCount]=P0; //读取转换结果AdCount++;if(AdCount>=10) //连续采集10次值{AdCount=0;search(); //查表LED1=!LED1;LcdDisplay(); //显示}}}void Timer0() interrupt 1{static unsigned char count=0,UPFlag=1,DOWNFlag=1; //按键标志位static unsigned int TimeCount=0;TH0=THC0;TL0=TLC0;if(MODE==0||UP==0||DOWN==0){count++;if(count>=30) //消抖处理{count=0;if(MODE==0) //按键按下{MODESelect++;if(MODESelect>=4) MODESelect=1;}else if(UP==0){UPFlag=0;if(MODESelect==2){TongDao++;TDSelect();}}else if(DOWN==0){DOWNFlag=0;if(MODESelect==2){TongDao--;TDSelect();}}}}else count=0;if(MODESelect==1){TimeCount++;if(TimeCount>=(ChangeTime*1000/5)){TimeCount=0;TongDao++;TDSelect();}}else if(MODESelect==3){if(UPFlag==0) {UPFlag=1;ChangeTime++;}else if(DOWNFlag==0){DOWNFlag=1;ChangeTime--;if(ChangeTime<=0) ChangeTime=1;}}}。
基于单片机的智能仪器综合设计实验一、实验目的在实验一~实验三的基础上,完成综合设计实验,学会信号采集、数据处理、键盘控制、LCD或LED显示等功能的智能仪器设计。
二、复习与参考实验一~实验三三、设计指标利用K分度号热电偶进行温度检测,测温范围为500-1200ºC,室温为20ºC,用LCD或LED显示室温和测量温度。
具有4路温度信号循环检测功能,通道切换时间可调;具有任意指定通道显示功能。
四、实验要求1.选择传感器,设计硬件电路,包括检测电路、信号调理电路、AD转换电路、单片机最小系统、LED显示(单号)、LCD显示(双号)、独立式按键,画出电路原理图。
2.画出软件流程图。
3.用Keil C51编写程序。
3.实验结果在LCD或LED上显示出来。
4.实验前完成第1、2项备查。
五、实验仪器设备和材料清单PC机;单片机实验板、连接导线、ST7920图形液晶模块Keil c51软件六、实验成绩评定方法实验成绩包括预习、实验完成质量、实验报告质量3部分组成,各部分所占比例分别为30%、40%、30%。
八、实验报告要求实验报告格式:●实验名称●实验目的●实验内容●硬件设计●软件设计●调试过程●参考文献●附1:电路原理图●附2:程序清单附录:实验程序源代码如下:(陈寅)#include "reg51.h"#define THC0 0xee //5ms时间常数设置#define TLC0 0x00sbit ADWR=P3^6; /***WR*****/sbit ADRD=P3^7; /***RD*****/sbit ADCS=P2^7; /***CS*****/sbit EOC=P3^3; /***EOC****/sbit ADA=P1^3; //通道选择引脚sbit ADB=P1^4;sbit ADC=P1^5;sbit CS =P1^0; /****************/sbit SID=P1^1; /**液晶引脚定义**/sbit SCLK=P1^2; /****************/sbit MODE=P2^0; /*************************/sbit UP=P2^1; /*四个按键接口,0表示按下*/sbit DOWN=P2^2; /*************************/sbit LED1=P2^3; /**4个LED灯引脚定义**/sbit LED2=P2^4; /********************/sbit LED3=P2^5; /********************/sbit LED4=P2^6; /********************//***************500~1200°C范围的K分度表,间隔10*******************/ unsigned int code K_TABLE[71]={20644,21066,21493,21919,22346,22772,23198,23624,24050,24476,24902,25327,25751,26176,26599,27022,27445,27867,28288,28709,29128,29547,29965,30383,30799,31214,31629,32042,32455,32866,33277,33686,34095,34502,34909,35314,35718,36121,36524,36925,37325,37725,38122,38519,38915,39310,39703,40096,40488,40897,41296,41657,42045,42432,42817,43202,43585,43968,44349,44729,45108,45486,45863,46238,46612,46985,47356,47726,48095,48462,48828}; unsigned char GetAdData[10]={0}; //存放获得AD值的数组变量unsigned char ViewTemperature[4]={"0000"}; //显示温度缓冲数组变量unsigned MODESelect=1;int ChangeTime=2; //通道切换时间,单位Sint TongDao=1;void delay(unsigned int j){unsigned char i;do{for(i=0;i<100;i++);}while(j--);}void send_command(unsigned char command_data) //发送命令{unsigned char i;unsigned char i_data;i_data=0xf8; //操作命令,可以查看资料delay(10);CS=1;SCLK=0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data=i_data&0x0f;i_data<<=4;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}void send_data(unsigned char command_data) //发送数据{unsigned char i;unsigned char i_data;i_data=0xfa; //操作命令,可以查看资料delay(10);CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data=i_data&0x0f; //取低四位i_data<<=4; //左移四位,从而变成高四位for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}void InitLCD() //液晶初始化{send_command(0x30); //功能设置:一次送8位数据,基本指令集send_command(0x06); //点设定:显示字符/光标从左到右移位,DDRAM地址加1send_command(0x0c); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x04); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x01); //清DDRAMsend_command(0x02); //DDRAM地址归位send_command(0x80); //把显示地址设为0X80,即为第一行的首位}/* x,y为起始座标x(0<=x<=3),y(0<=y<=7),x为行座标,y为列座标;how为要显示汉字的个数;style为显示字符的类型,0表汉字,1表字母;str是要显示汉字的地址*/void Display(unsigned char x,unsigned char y,unsigned char how,bit style,unsigned char *stri) //液晶显示{unsigned char hi=0;if(x==0) send_command(0x80+y);else if(x==1) send_command(0x90+y);else if(x==2) send_command(0x88+y);else if(x==3) send_command(0x98+y);if(style==0){for(hi=0;hi<how;hi++){send_data(*(stri+hi*2));send_data(*(stri+hi*2+1));}}elsefor(hi=0;hi<how;hi++) send_data(*(stri+hi));}float LvBo(void)//复合滤波{unsigned char max,min,i;unsigned int sum=0;float U1;max=GetAdData[0];min=GetAdData[0];for(i=0;i<10;i++){sum=sum+GetAdData[i];if(max<GetAdData[i]) max=GetAdData[i];if(min>GetAdData[i]) min=GetAdData[i];}sum=sum-max-min;U1=(float)sum/8;U1=10.0*((U1*5.0)/255); //换成mvreturn U1;}void search (void)//查表子函数{unsigned int da=0,max,min,mid,j;unsigned int var;da=LvBo()*1000; //u1扩大1000倍da=da+798; //20度max=71;min=0;var=0;while(1){mid=(max+min)/2; //中心元素位置if(K_TABLE[mid]==da) {var=mid*10;break;} //中心元素等于查表元素,计算相应温度else if(K_TABLE[mid]>da) max=mid-1;else min=mid+1;if(max-min==1) /*线性插值计算温度值*/{j=(K_TABLE[max]-K_TABLE[min])/10; /*表中相邻两值对应温度相差10°C*/j=(da-K_TABLE[min])/j;var=10*min+j;break;}if(max==min){if(da>=K_TABLE[min]){j=(K_TABLE[min+1]-K_TABLE[min])/10;j=(da-K_TABLE[min])/j;}else if(da<K_TABLE[min]){j=(K_TABLE[min]-K_TABLE[min-1])/10;j=(da-K_TABLE[min-1])/j;min=min-1;}var=10*min+j;break;}}var=var+500;ViewTemperature[0]=var/1000+0x30;ViewTemperature[1]=var/100%10+0x30;ViewTemperature[2]=var/10%10+0x30;ViewTemperature[3]=var%10+0x30;}void LcdDisplay(void){unsigned char ViewMODESelect,ViewTongDao[5]={"0 "},ViewChangeTime[5]={"00(S)"};ViewMODESelect=MODESelect+0x30;ViewTongDao[0]=TongDao+0x30;if(MODESelect==1||MODESelect==2){if(MODESelect==1) Display(0,3,5,0,":自动切换");else if(MODESelect==2) Display(0,3,5,0,":手动切换");Display(0,0,2,0,"模式"); //液晶显示Display(0,2,1,1,&V iewMODESelect);Display(1,0,5,0,"温度通道:");Display(1,5,5,1,V iewTongDao);Display(2,0,4,0,"温度值:");Display(2,4,4,1,V iewTemperature);Display(2,6,2,1,"℃");}else if(MODESelect==3){ViewChangeTime[0]=ChangeTime/10+0x30;ViewChangeTime[1]=ChangeTime%10+0x30;Display(0,0,2,0,"模式");Display(0,2,1,1,&V iewMODESelect);Display(0,3,5,0,":设置时间");Display(1,0,5,0,"切换时间:");Display(1,5,5,1,V iewChangeTime);Display(2,0,14,1," "); //本行清屏}}void TDSelect(void) //AD通道设置{if(TongDao>=5) TongDao=1;if(TongDao<=0) TongDao=4;if(TongDao==1) {ADC=0;ADB=0;ADA=0;}else if(TongDao==2) {ADC=0;ADB=0;ADA=1;}else if(TongDao==3) {ADC=0;ADB=1;ADA=0;}else if(TongDao==4) {ADC=0;ADB=1;ADA=1;}}main(){unsigned char AdCount=0; //用来存放AD采集次数InitLCD();TMOD=0x11; //定时器0初始化TH0=THC0;TL0=TLC0;TR0=1;ET0=1;EA=1;P2|=0x07; //按键初始为高while(1){ADWR=1; /************/ADCS=0; /************/ADWR=0; /**AD初始化**/ADWR=1; /************/while(!EOC); //等待转换结束ADRD=0;GetAdData[AdCount]=P0; //读取转换结果AdCount++;if(AdCount>=10) //连续采集10次值{AdCount=0;search(); //查表LED1=!LED1;LcdDisplay(); //显示}}}void Timer0() interrupt 1{static unsigned char count=0,UPFlag=1,DOWNFlag=1; //按键标志位static unsigned int TimeCount=0;TH0=THC0;TL0=TLC0;if(MODE==0||UP==0||DOWN==0){count++;if(count>=30) //消抖处理{count=0;if(MODE==0) //按键按下{MODESelect++;if(MODESelect>=4) MODESelect=1;}else if(UP==0){UPFlag=0;if(MODESelect==2){TongDao++;TDSelect();}}else if(DOWN==0){DOWNFlag=0;if(MODESelect==2){TongDao--;TDSelect();}}}}else count=0;if(MODESelect==1){TimeCount++;if(TimeCount>=(ChangeTime*1000/5)){TimeCount=0;TongDao++;TDSelect();}}else if(MODESelect==3){if(UPFlag==0) {UPFlag=1;ChangeTime++;}else if(DOWNFlag==0){DOWNFlag=1;ChangeTime--;if(ChangeTime<=0) ChangeTime=1;}}}。
基于单片机的智能仪器综合设计实验1.实验目的在实验一~实验三的基础上,完成综合设计实验,学会信号采集、数据处理、键盘控制、LCD显示等功能的智能仪器设计。
2.实验内容利用K分度号热电偶进行温度检测,测温范围为0-1200ºC,室温为25ºC,按键选择室温和被测温度的显示,用LCD显示。
具有8路温度信号循环检测功能,通道切换时间可调;具有任意指定通道显示功能。
(选作)具有北京时间显示、修改功能。
(选作)3.主要仪器设备PC机;单片机实验板、连接导线、ST7920图形液晶模块Keil c51软件4.设计思想该实验主要完成北京时间显示与修改,数据采集通道显示与修改,室温显示与设定,采集结果显示。
4.1 硬件设计4.1.1 最小系统设计该实验中的最小系统模块中包括CPU、复位电路和晶振,其最小系统原理图如图4.1.1所示432EA /VP 31X 119X 218R ESE T 9R D 17W R 16INT 012INT 113T014T115P101P112P123P134P145P156P167P178P0039P0138P0237P0336P0435P0534P0633P0732P2021P2122P2223P2324P2425P2526P2627P2728PS EN29A LE/P 30TX D 11R XD 10U 58051A HR 2R ES2C 3C APV CCR 1R ES2S0SW S PSTC 2C APC 1C APY 1C RY ST ALP00P01P02P03P04P05P06P07P20P21P22P23P24P25P26P27P10P11P12P13P14P15P16P17P30P31P32P33P34P35P36P37A LE PS ENV CC X 1X 2R ESE T图4.1.1 CPU 时钟与复位电路图4.1.2 4*4非编码键盘电路本次设计中采用的4*4的非编码键盘。
矩阵式非编码键盘的电路原理图如图4.1.2所示。
当没有键按下时,行线和列线之间是不相连。
若第N 行第M 列的键被按下,那么第N 行与第M 列的线就被接通。
如果在行线上加上信号,根据列线的状态,便可得知是否有键按下。
如果在行线上逐行加上一个扫描信号(本实验中用的低电平),就可以判断按键的位置。
常用的按键识别有两种方法:一种是传统的行扫描法;另一种是速度较快的线反转法,这种方法必须采用可编程并行接口。
本实验中采用的是行扫描法进行识键。
paizu123456789pai1VCCC 1P00P01P02P03P04P05P06P07S1S2S3S13S4S5S6S14S7S8S9S15S10S11S12S16P00P01P02P03P04P05P06P07图4.1.2 矩阵键盘原理图4.1.3 LCD 显示电路本设计采用ST7920控制器的LCD 液晶显示器,其具有低电压,字迹清晰、能够显示汉字和字符等特点,且编程方便,易于查看、修改。
本实验中主要用到了VSS 、VDD 、RS 、RW 、CS 引脚。
ST7920液晶显示器与MCU 接口电路原理图如图4.1.3所示。
V S S1V D D 2V 03R S 4R W 5C S 6D B 07D B 18D B 29D B 310D B 411D B 512D B 613D B 714P S B 15N C 16R S T17N C 18B L A19B L K 20U 2LC DV CCR 210K15uV CCP27P26P25图4.1.3 LCD 显示电路原理图4.1.4 AD 采集电路本设计采用ADC0809为电压采集转换芯片。
ADC0809是一种8位逐次比较型A/D 转换器,转换时间为100us ,输入电压范围为0~5V ,片内有8通道模拟开关,可接入8个模拟量输入。
芯片内有输出数据锁存器,输出的数字量可直接与连接n.d d b图4.2.1 主程序流程图4.2.2 数据采集部分当主函数调用该函数时,感函数首先选择通道号,然后启动ADC0809,对指定通道数据采集10次,并将转换后的结果存储在全局变量table数组中供后续程序处理。
其流程图如图4.2.2所示。
图4.2.2 数据采集函数流程图该函数要实现去掉采集结果的最大值和最小值,并将采集结果转换为标准电压。
所以该函数首先采用冒泡排序法对全局变量table数组进行排序,然后去掉两个最值,求取剩余项的平均值,最后将结果转换为标准电压值。
其流程图如图4.2.3所示。
准备table数组排序table数组中间8个数求和转换为标准电压值返回图4.2.3 滤波函数流程图4.2.4 查表部分该函数主要采用了对半查表法进行程序编写。
K分度表中0~1200°C范围的121个电压值(每隔10°C对应一个电压值)都放大1000倍变成整数,构成一张表存放在程序存储器中备查。
该函数主要对全局变量进行操作,将所得结果赋值给全局变量fhwd供后续操作。
其流程图如图4.2.4所示。
图4.2.4 查表函数流程图该函数主要被定时器调用。
此函数主要用行扫描法先将行拉低,再读取值,若读回的值与输出值不一致则表示有键按下,再根据读回的值判断具体按键,返回该按键的值。
流程图如图4.2.5所示。
图4.2.5 按键扫描函数流程图4.2.6 中断部分该函数主要用于整个程序中的定时,并在其中调用按键函数,以达到实时采集按键信息的目的。
可以通过按键实时修改北京时间、室内温度和通道选择。
因为该函数中代码较长,所以选择50ms定时中断一次。
当中断次数达到20次时,秒计数自增一,修改时间更新标志。
当秒变量等于60时,秒变量清零,分变量自增一,以此递推关系类推。
当时变量等于24时,分、秒、时变量均清零,重新计数。
其流程图如图4.2.6所示。
图4.2.6 中断函数流程图4.2.7 显示部分该函数主要在主函数中被调用。
当刷新标志位变化时,就调用该函数刷新显示。
该函数主要执行步骤为送显示命令,然后送待显示字符,最后刷新显示。
其流程图如图4.2.7所示。
图4.2.7显示程序流程图4.2.8 延时部分该函数主要用于数据采集过程中的延时。
该函数是用C语言编写,为非精确定时。
主要通过两个嵌套for循环达到延时的目的。
其流程图如图4.2.8所示。
图4.2.8 延时函数流程图5.调试该函数的调试过程遇到不少麻烦。
可能因为代码太长,自己思路不是很清晰所致。
最终该程序代码能够实现数据采集,北京时间显示,室温显示,通道号显示,采集结果显示。
但按键修改部分功能没有调试成功,如果要修改室温或者数据采集通道号只有通过修改程序来达到目的。
单个调试按键函数没问题,如果让LCD显示按键返回值,可以在LCD上看到准确的结果,但如果是在定时器中用按键返回值去修改一些功能便出现了“没按键按下”的奇怪现象。
最初怀疑是定时时间太短,而定时器中代码太长,加长定时时间后没见效果。
现在我想是按键消抖部分出了问题。
消抖所花时间太长。
当消抖时间过的时候按键已经弹起,没有按键按下信息了。
6.参考文献[1].《智能仪器》程德福林君北京机械工业出版社2009.8[2].《51单片机基础综合实验板实验指导书》李家庆2009.2附录一:硬件原理图654321D C BAEA /VP31X 119X 218R ESE T9R D 17W R 16INT 012INT 113T014T115P101P112P123P134P145P156P167P178P0039P0138P0237P0336P0435P0534P0633P0732P2021P2122P2223P2324P2425P2526P2627P2728PS EN29A LE/P 30TX D 11R XD 10U 58051A HR 2R ES2C 3C APV CC R 1R ES2S0SW S PSTC 2C APC 1C AP Y 1C RY ST AL IN-026msb2-1212-220IN-1272-3192-418IN-2282-582-615IN-312-714lsb2-817IN-42EO C7IN-53A DD -A 25IN-64A DD -B 24A DD -C23IN-75A LE22ref(-)16EN A BL E 9ST AR T 6ref(+)12C LO CK10U 4A DC 080912345678J23C ON 8X 1A N ORX 1B N OR ST AR TO EC LKC LK3D2SD 4C D1Q 5Q6U 7A74LS74C LK3D 2SD 4C D1Q 5Q6U 8A 74LS74C LK2C LK1ALEC LKC LK2V CCC LK1P00P01P02P03P04P05P06P07P00P01P02P03P04P05P06P07P20P21P22P23P24P25P26P27P10P11P12P13P14P15P16P17P30P31P32P33P34P35P36P37A LE PS ENV CC X 1X 2R ESE T P27P26P25O E ST AR T V CC P36P37V SS 1V DD 2V 03R S 4R W 5C S 6D B07D B18D B29D B310D B411D B512D B613D B714PS B 15N C 16R ST 17N C 18B LA 19B LK 20U 2LC DV CCR 210K15uV CCP27P26P25p a i z u123456789pai1V CCC 1P00P01P02P03P04P05P06P07S1S2S3S13S4S5S6S14S7S8S9S15S10S11S12S16P00P01P02P03P04P05P06P07附录二:源程序代码#include "reg51.h"#include "math.h"#define THCO 0x3c#define TLCO 0xb0#define Keyscan P1#define rowkey() (~P1)&0x0f //读入P1低4位(列按键值)宏unsigned int code K_TAB[121]={ 0,397,798,1203,1611,2022,2436,2850,32 66,3681,4095,4508,4919,5327,5733,6137,653 9,6939,7338,7737,8137,8537,8938,9341,9745, 10151,10560,10969,11381,11793,12207,1262 3,13039,13456,13874,14292,14712,15132,155 52,15974,16395,16818,17241,17664,18088,18 513,18938,19363,19788,20214,20640,21066,2 1493,21919,22346,22772,23198,23624,24050, 24476,24902,25327,25751,26176,26599,2702 2,27445,27867,28288,28709,29128,29547,299 65,30383,30799,31214,31629,32042,32455,32 866,33277,33686,34095,34502,34909,35314,3 5718,36121,36524,36925,37325,37724,38122, 38519,38915,39310,39703,40096,40488,4089 7,41296,41657,42045,42432,42817,43202,435 85,43968,44349,44729,45108,45486,45863,46 238,46612,46985,47356,47726,48095,48462,4 8828}; /*0~1200°C范围的K分度表,每隔10°C对应一个电压值*/unsigned int table[10]={255,200,255,250,255,255,255 ,255};unsigned int da=0,max=120,min=0,mid,temp,var,fhwd ;unsigned int sum=0,bcdy,tdflag=1,swflag=1;float u1;unsigned char time[8]={"00:00:00"},flag=0,Returnnum ber = 0,adflag=1;unsigned charH=0,M=0,S=0,sw=25,td=0,shiw,gew,tdz, swz[2],fhwdz[4];unsigned char KeyScanner(void);//按键扫描程序void delay(unsigned int x);//nms延时程序void ad0809(int a);//芯片启动程序void send_command(unsigned char command_data); //发送命令void send_data(unsigned char command_data); //发送数据void InitLCD(void); //液晶初始化void DispHanzi(unsigned char x,unsigned char y,unsigned char how,unsigned char *stri); //汉字显示void DispZimu(unsigned char x,unsigned char y,unsigned char how,unsigned char *stri);//字母数字都可以显示void ser2 (void);//查表子函数//void lbo(void);//滤波子函数sbit a_c = P2^0;sbit a_b = P2^1;sbit a_a = P2^2;sbit eoc = P2^3;sbit p24 = P2^3;sbit r s = P3^7;sbit w r = P3^6;sbit CS = P2^5; //液晶接口sbit S ID = P2^6;sbit S CLK = P2^7;sbit key = P2^4;void lbo(void){int i,j;for(i=0;i<9;i++)for(j=i+1;j<10;j++){if (table[i]>table[j]){temp=table[i];table[i]=table[j];table[j]=temp;}}for(i=1;i<9;i++){sum+=table[i];}u1=(float)sum/408;}void main(){unsigned char time[8]={"00:00:00"};p24=1;TMOD=0x11; //定时器0初始化TH0=THCO;TL0=TLCO;TR0=1;ET0=1;EA=1;InitLCD();DispHanzi(0,0,4,"当前时间");//第1行0列显示汉字DispZimu(0,4,8,time);DispHanzi(1,0,4,"通道选择");DispHanzi(2,0,4,"室内温度");DispHanzi(3,0,4,"采集结果");while(1){if(adflag==1){ad0809(td);adflag=0;lbo();ser2 ();fhwdz[0]=fhwd/1000+0x30;fhwdz[1]=fhwd%1000/100+0x30;fhwdz[2]=fhwd%100/10+0x30;fhwdz[3]=fhwd%10+0x30;DispZimu(3,5,4,&fhwdz);}if(flag==1){flag=0;time[0]=H/10+0x30;//数字转为ASCCII值进行显示time[1]=H%10+0x30;time[3]=M/10+0x30;time[4]=M%10+0x30;time[6]=S/10+0x30;time[7]=S%10+0x30;DispZimu(0,4,8,time);}if(tdflag==1){adflag=1;tdz=td+0x30;DispZimu(1,5,1,&tdz);tdflag=0;if(swflag==1){adflag=1;shiw=sw/10;gew =sw%10;bcdy=K_TAB[shiw]+(K_TAB[shiw+1]-K_TAB[shiw])/10*(int)gew;swz[0]=shiw+0x30;swz[1]=gew+0x30;swflag=0;DispZimu(2,5,2,&swz);}}}}void InitLCD(void) //液晶初始化{send_command(0x30); //功能设置:一次送8位数据,基本指令集send_command(0x06); //点设定:显示字符/光标从左到右移位,DDRAM地址加1 send_command(0x0c); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x04); //显示设定:开显示,显示光标,当前显示位反白闪动send_command(0x01); //清DDRAMsend_command(0x02); //DDRAM地址归位send_command(0x80); //把显示地址设为0X80,即为第一行的首位}//nms 延时程序void delay(unsigned int x){unsigned char i;while(x-->0)for(i=0;i<125;i++);}//ADC启动程序void ad0809(int a){int i;switch(a) //选择采集通道{case 0: a_a=0;a_b=0;a_c=0;break;case 1: a_a=1;a_b=0;a_c=0;break;case 2: a_a=0;a_b=1;a_c=0;break;case 3: a_a=1;a_b=1;a_c=0;break;case 4: a_a=0;a_b=0;a_c=1;break;case 5: a_a=1;a_b=0;a_c=1;break;case 6: a_a=0;a_b=1;a_c=1;break;case 7: a_a=1;a_b=1;a_c=1;break;}for(i=0;i<10;i++){rs=1; //起动AD0809wr=1;delay(1);wr=0;delay(1);wr=1;while(!eoc); //等待转换结束rs=0; //取出读得的数据table[i]=P0; //送相关通道数组delay(1);}}void send_command(unsigned char command_data) //发送命令{unsigned char i;unsigned char i_data,temp_data1,temp_data2;i_data=0xf8; //操作命令,可以查看资料delay(10);CS=1;SCLK=0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;temp_data1=i_data&0xf0;temp_data2=i_data&0x0f;temp_data1>>=4;temp_data2<<=4;i_data=temp_data1|temp_data2;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}void send_data(unsigned char command_data) //发送数据{unsigned char i;unsigned chari_data,temp_data1,temp_data2;i_data=0xfa; //操作命令,可以查看资料delay(10);CS=1;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}i_data=command_data;temp_data1=i_data&0xf0;temp_data2=i_data&0x0f;temp_data1>>=4;temp_data2<<=4;i_data=temp_data1|temp_data2;i_data&=0xf0;for(i=0;i<8;i++){SID=(bit)(i_data&0x80);SCLK=0;SCLK=1;i_data=i_data<<1;}CS=0;}/* x,y为起始座标x(0<=x<=3),y(0<=y<=7),x为行座标,y为列座标;how为要显示汉字的个数;str是要显示汉字的地址*/void DispHanzi(unsigned char x,unsigned char y,unsigned char how,unsigned char *stri)//汉字显示{unsigned char hi=0;if(x==0) send_command(0x80+y);//else if(x==1) send_command(0x90+y);else if(x==2) send_command(0x88+y);else if(x==3) send_command(0x98+y);for(hi=0;hi<how;hi++){send_data(*(stri+hi*2));send_data(*(stri+hi*2+1));}}void DispZimu(unsigned char x,unsigned char y,unsigned char how,unsigned char *stri)//字母数字都可以显示{unsigned char hi=0;//字母显示if(x==0) send_command(0x80+y);else if(x==1) send_command(0x90+y);else if(x==2) send_command(0x88+y);else if(x==3) send_command(0x98+y);for(hi=0;hi<how;hi++){send_data(*(stri+hi));}}void ser2 (void) //查表子程序{unsigned int j;da=(unsigned int)(u1*10000)+bcdy;//u1扩大10000倍while(1){mid=(max+min)/2;//中心元素位if(K_TAB[mid]==da){var=mid*10;break;} //中心元素等于查表的元素,计算if((max-min)==1) //线形插值计算{j=(K_TAB[max]-K_TAB[min])/10; //表中相邻两值对应温度相j=(da- K_TAB[min])/j;var=10*min+j;fhwd=(unsigned int)var;break;}if(K_TAB[mid]>da)max=mid;elsemin=mid;}}void timer0() interrupt 1{static unsigned char count=0,K_count=0,number = 0 ,shiwei = 0,Mode=0;//MODE, 1:修改小时;2:修改分钟;3:选择通道号;4:设定室温TH0=THCO;TL0=TLCO;count++;if(count==20) //秒计时,定时器定时50ms,计20次为一秒{count=0;S++; flag=1;if(S==60){S=0;M++;adflag=1;if(M==60) //时间计时{M=0; H++;if(H==24)H=0;}}}/* Returnnumber = KeyScanner(); //读取矩阵键盘返回值if(Returnnumber >= 1 && Returnnumber <= 16) //有键按下{K_count++;if(K_count >= 30) //消抖处理{K_count = 0;if(Returnnumber == 16) //第十六号键,修改Mode,Mode++;if(Mode==5) Mode=1;else if(Returnnumber == 15)//第15号键,+ 键{if(Mode == 1) //实时时间小时加{ H++; if(H >= 24)H = 0; }else if(Mode == 2)//实时时间分钟加{ M++; if(M >= 60)M = 0; }else if(Mode == 3)//通道号加{ td++; if(td > 7)td = 0; tdflag=1;}else{ sw++; if(sw > 60)sw = 0;swflag=1; }//室温加}else if(Returnnumber == 14) //第14号键,- 键{if(Mode == 1) //小时减{if(H == 0)H = 23;else H--;}else if(Mode == 2) //分钟减{if(M == 0)M = 59;else M--;}else if(Mode == 3)//通道号减{ td--; if(td < 0)td = 7; tdflag=1;}else{ sw--; if(sw < 0)sw = 60; swflag=1;}//室温减}else if(Returnnumber == 13) //第十三键清零{ H = 0; M = 0; S = 0;td=0;sw=25;tdflag=1;swflag=1; }else if(Returnnumber >=1 && Returnnumber <=10) //1~10号键对应数字1~10{if(Returnnumber == 10) Returnnumber = 0; //10号键对应数字0if(Mode == 1 ){number ++;if(number == 1) {H = Returnnumber * 10;shiwei = H;if(H > 20)H = 20;}else { H = shiwei + Returnnumber; number = 0; if (H >23)H = 23;}}if(Mode == 2 ){number ++;if(number == 1) {M = Returnnumber * 10;shiwei = M;if(M > 50)M = 50;}else { M = shiwei + Returnnumber; number = 0; if (M >59)M = 59;}}if(Mode == 3 ){td = Returnnumber;if(td >= 8)td = 8;tdflag=1;}if(Mode == 4 ){number ++;if(number == 1) {sw = Returnnumber * 10;shiwei = sw;if(sw > 60)M = 60;}else { sw = shiwei + Returnnumber; number = 0; if (sw >60)sw = 60;}}}}}else K_count=0;}unsigned char KeyScanner(void){unsigned char scan = 0xef,keyin = 0,KeyNumber = 0,row,col;for(col = 0;col < 4;col++){Keyscan = scan;keyin = rowkey();if(keyin != 0){if(keyin == 1)row = 1;else if(keyin == 2)row = 2;else if(keyin == 4)row = 3;else if(keyin == 8)row = 4;KeyNumber = row + col * 4;break;}scan = (scan <<1 ) | 0x01;}return KeyNumber; */}。