电子科技大学学院实验报告实验名称现代电子技术综合实验姓名:学号:评分:教师签字电子科技大学教务处制电子科技大学实验报告学生姓名:学号:指导教师:熊万安实验地点:211大楼308 实验时间:一、实验室名称:单片机技术综合实验室二、实验项目名称:数码管显示A/D转换电压值及秒表三、实验学时:12四、实验目的与任务:1、熟悉系统设计与实现原理2、掌握KEIL C51的基本使用方法3、熟悉实验板的应用4、连接电路,编程调试,实现各部分的功能5、完成系统软件的编写与调试五、实验器材1、PC机一台2、实验板一块六、实验原理、步骤及内容试验要求:①、数码管可在第2位到第4位显示A/D转换的电压值,可调电压,数码管第5位显示“-”号,第6、7位显示2位学号;②、再按按键key1进行切换,此时数码管第6、7位显示从学号到(学号值+5秒)的循环计时秒表,时间间隔为1秒。
按按键key2时,秒表停止计数,再按按键key2时,秒表继续计数。
按按键key1可切换回任务1的显示。
③、当电压值大于2伏时,按按键不起作用。
1、硬件设计2、各部分硬件原理(相关各部分例如:数码管动态扫描原理;TLC549ADC特征及应用等)(1)数码管动态扫描原理多位联体的动态数码管段选信号abcdefg和dp(相当于数据线是公用的,而位选信号com是分开的。
扫描方法并不难,先把第1个数码管的显示数据送到abcdefg和dp,同时选通com1,而其它数码管的com信号禁止;延时一段时间(通常不超过10ms),再把第二个数码管的显示数据送到abcdefg和dp,同时选通com2,而其他数码管的com信号禁止;延时一段时间,再显示下一个。
注意,扫描整个数码管的频率应当保证在50Hz 以上,否则会看到明显的闪烁。
(2)TLC549ADC特征及应用等当/CS变为低电平后,TLC549芯片被选中,同时前次转换结果的最高有效位MSB (A7)自DAT端输出,接着要求自CLK端输入8个外部时钟信号,前7个CLK信号的作用,是配合TLC549 输出前次转换结果的A6-A0 位,并为本次转换做准备:在第4个CLK 信号由高至低的跳变之后,片内采样/保持电路对输入模拟量采样开始,第8个CLK 信号的下降沿使片内采样/保持电路进入保持状态并启动A/D开始转换。
转换时间为36 个系统时钟周期,最大为17us。
直到A/D转换完成前的这段时间内,TLC549 的控制逻辑要求:或者/CS保持高电平,或者CLK 时钟端保持36个系统时钟周期的低电平。
由此可见,在自TLC549的CLK 端输入8个外部时钟信号期间需要完成以下工作:读入前次A/D转换结果;对本次转换的输入模拟信号采样并保持;启动本次A/D转换开始。
(3)共阴极数码管共阴极数码管的一段连在一起接地,所以给一个高电平,相应的段位发光。
(4)按键逻辑按键逻辑是连接在P2.0到P2.7的。
当按键不按下的时候,输入为高电平,当按下按键,P2.x口与地相连,输入为低电平,所以按键是低电平有效。
3、软件设计(说明:我和另一个同学一起做的,所以在程序设计上增加了一个状态)思考题:按键改用外部中断模式,电路如何修改(画示意图)?程序如何修改,写出中断服务程序。
若按键改成外部中断模式,即把按键key2连接在INT0上。
电路示意图为:而中断服务程序为:void T0INTSVC() interrupt 0{ET0=1;EX0=1;EA =1;if(mbiao<2600&&TR0==1)mbiao=mbiao+1;if(mbiao==2600)mbiao=2000;y10=mbiao/1000;y=(mbiao-y10*1000)/100;}七、总结及心得体会通过本实验课程的学习,我初步掌握了KEIL C51的基本使用方法,并能够自主连接电路,编程调试,实现各部分的功能,进而整合自己所学知识进行简单的编程,完成一系列组合实验。
与此同时,我对中断和定时有了较深入的了解,对单片机的认识也有了进一步的提高。
八、对本实验过程及方法、手段的改进建议在本实验的实现过程中有几个问题需要注意:1、数码管是采取的动态扫描,所以位选频率一定要高于50Hz才能使人眼不能看到闪烁。
2、实验软件的环境配置没有针对本地开发板进行默认配置,所以有同学会出现下载到开发板而不能运行,如果有初始配置的话,程序的调试会更加方便。
九、附录1、程序/*利用TLC549 A/D转换器实现电压测量与显示*/#include <reg51.h> //包含8051的SFR寄存器定义头文件#include <absacc.h> //扩展并行接口所需的绝对地址访问库函数#define LED_dig XBYTE[0x9000] //8位数码管显示器的位选输出控制#define LED_seg XBYTE[0x8000] //8位数码管显示器的段码(字形码)输出控制#define KEY_IN XBYTE[0x8000]//定义TLC549操作接口sbit ADC_CS = P1^7;sbit ADC_DA TA = P1^6;sbit ADC_CLK = P1^5;code unsigned char disp_seg[]= //显示段码{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5f,0x79,0x 71,0x40,0x00,0xff};// 0 1 2 3 4 5 6 7 8 9 a b c de f - blank,全亮unsigned char DispBuf[8]; //定义显示缓冲区(由定时中断程序自动扫描)unsigned char key_value; //定义按键int flag; //定义状态标志unsigned char y10,y; //定义秒表的个位,十分位unsigned short mbiao; //定义秒表计数单元void delay(int ms); //延时大约1ms unsigned char ReadAdc(void); //读取A/D转换结果void AdcInit(void); //初始化ADC接口void key_scan(void);void main(){unsigned char i=0;unsigned char volt, x100, x10, x;TMOD &= 0x0f;TMOD |= 0x10;TH1 = 0xFC;TL1 = 0x66;TR1 = 1;ET1 = 1;TMOD &= 0xf0;TMOD |= 0x01;TH0 = 0xdc;TL0 = 0x00;TR0 = 1;ET0 = 1;EA =1;AdcInit();for(i=0; i<8; i++)DispBuf[i] = 17; //全部8位显示灭y10=2;y=0;mbiao=2000;flag=0;while(1){while(flag ==0) //初始状态—学号状态{volt = ReadAdc(); //得到A/D转换结果的数字量(0x00~0xff)volt = volt * 250/256; //转换成电压值,其中Vr=2.5Vx100 = volt/100;x10 = (volt - x100*100)/10;x = (volt - x100*100)%10;DispBuf[7] = 17;DispBuf[6] = x100;DispBuf[5] = x10;DispBuf[4] = x;DispBuf[3] = 16;DispBuf[2] = 0;DispBuf[1] = 8;DispBuf[0] = 17;delay(100);if(key_value == 8&&volt<=200){flag = 3;while(key_value == 8);}}while(flag==1) //计数状态{TR0=1;volt = ReadAdc();volt = volt * 250/256; //转换成电压值,其中Vr=2.5Vx100 = volt/100;x10 = (volt - x100*100)/10;x = (volt - x100*100)%10;DispBuf[0] = 17;DispBuf[1] = y;DispBuf[2] = y10;DispBuf[3] = 16;DispBuf[4] = x;DispBuf[5] = x10;DispBuf[6] = x100;DispBuf[7] = 17;if(key_value == 8&&volt<=200){flag = 0;while(key_value == 8);} else if(key_value == 7&&volt<=200){flag = 2;while(key_value == 7);}}while(flag==2) //计数暂停状态TR0=!TR0;if(key_value == 7){flag = 1;while(key_value == 7);}}while(flag==3) //学号状态{volt = ReadAdc(); //得到A/D转换结果的数字量(0x00~0xff)volt = volt * 250/256; //转换成电压值,其中Vr=2.5Vx100 = volt/100;x10 = (volt - x100*100)/10;x = (volt - x100*100)%10;DispBuf[7] = 17;DispBuf[6] = x100;DispBuf[5] = x10;DispBuf[4] = x;DispBuf[3] = 16;DispBuf[2] = 2;DispBuf[1] = 0;DispBuf[0] = 17;delay(100);if(key_value == 8&&volt<=200){flag = 1;mbiao=2000;while(key_value == 8);}}}}/*函数:T1INTSVC()功能:定时器T1的中断服务函数*/void T1INTSVC() interrupt 3{code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};static unsigned char n = 0;TH1 = 0xfc;TL1 = 0x66;TR1 = 1;LED_dig = 0xFF; //暂停显示if(flag==0){if(n==6)LED_seg = ~(disp_seg[DispBuf[n]]|0x80);elseLED_seg = ~disp_seg[DispBuf[n]];//更新扫描数据}if(flag==1){ if(n==6)LED_seg = ~(disp_seg[DispBuf[n]]|0x80);elseif(n==4)LED_seg = ~( disp_seg[DispBuf[n]] ); //更新扫描数据,elseLED_seg = ~disp_seg[DispBuf[n]]; //更新扫描数据}if(flag==2){LED_seg = ~disp_seg[DispBuf[n]]; //更新扫描数据}if(flag==3){if(n==6)LED_seg = ~(disp_seg[DispBuf[n]]|0x80);elseLED_seg = ~disp_seg[DispBuf[n]];//更新扫描数据}LED_dig = ~com[n]; //重新显示key_scan();n++;n &= 0x07;}void delay(int ms){unsigned int i,j;for(i=0; i<ms; i++) //延时大约1ms (fosc=11.0592MHz) {for(j=0; j<100; j++);}}/*函数:ReadAdc()功能:读取A/D转换结果返回:8位ADC代码*/unsigned char ReadAdc(void){unsigned char d; //读取得ADC结果unsigned char n; //ADC bit位计数ADC_CS = 0;n = 5;while ( --n != 0 ); //模拟tsu时间n = 8;do{d <<= 1;if ( ADC_DA TA )d = d | 0x01; //或d++;ADC_CLK = 1;ADC_CLK = 0;}while ( --n != 0 );ADC_CS = 1;return d;}/*函数:AdcInit()功能:初始化ADC接口*/void AdcInit(void){ADC_CS = 1;ADC_CLK = 0;ADC_DATA = 1;ReadAdc(); //空读一次,用于启动一次A/D转换过程}void key_scan(void){unsigned char key_in;key_in = KEY_IN;switch(key_in){case 0xff:key_value = 0;break;case ~0x01:key_value = 1;break;case ~0x02:key_value = 2;break;case ~0x04:key_value = 3;break;case ~0x08:key_value = 4;break;case ~0x10:key_value = 5;break;case ~0x20:key_value = 6;break;case ~0x40:key_value = 7;break;case ~0x80:key_value = 8;break;default:break;}}/*函数:T1INTSVC()功能:定时器T0的中断服务函数*/void T0INTSVC() interrupt 1{TR0 = 0;TH0 = 0xdc;TL0 = 0x00;TR0 = 1;if(mbiao<2600&&TR0==1)mbiao=mbiao+1;if(mbiao==2600)mbiao=2000;y10=mbiao/1000;y=(mbiao-y10*1000)/100;}。