数码管显示AD转换的电压值数码管显示秒表
- 格式:doc
- 大小:1.20 MB
- 文档页数:13
计算机科学与工程系实验报告实验题目:制作一个LED数码管显示的秒表班级:姓名:学号:日期:一、实验目的掌握单片机使用定时计数器控制LED数码管的设计与软件编程二、实验要求1、用2位数码管显示计时时间,最小计时单位为“百毫秒”,计时范围0.1~9.9s;2、当第1次按下并松开计时功能键时,秒表开始计时并显示时间;3、第2次按下并松开计时功能键时,停止计时,计算两次按下计时功能键的时间,并在数码管上显示;4、第3次按下计时功能键,秒表清0,再按1次计时功能键,重新开始计时。
5、如果计时到9.9s时,将停止计时,按下计时功能键,秒表清零,再按下重新开始计时。
三、实验要求提交的实验报告中应包括:电路原理图、实验设计思路、C51源程序(含注释语句)、运行效果(含运行截图与说明)、实验小结三、硬件电路原理图的设计四、编程思路及C51源程序编程思路:使用外中断服务处理程序处理按键,内部设计一个计数器,记录按键按下的次数,根据按键次数完成相应的功能。
用数码管显示计时时间,根据按键的次数以及其功能来显示数字。
#include<reg51.h> //包含8051单片机寄存器定义的头文件unsigned char code discode1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef} unsigned char code discode2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsigned char timer=0; //记录中断次数unsigned char second; //存储秒数unsigned char key=0; //记录按键次数main() //主函数{TMOD=0x01; //定时器T0方式1定时ET0=1; // 允许定时器T0中断EA=1; // 总中断允许second=0; //设初始值P0=discode1[second/10]; //显示秒位P2=discode2[second%10]; //显示0.1S位while(1) //循环{if((P3&0x80)==0x00) //当按键被按下时{key++; //按键次数加一switch(key) //根据按键次数分三种情况{case 1: //第一次按下为启动秒表表示TH0=0xee; //TL0=0x00; //TR0=1; //break; //case 2: //按下两次暂停秒表TR0=0; //break; //case 3: //按下三次秒表清零key=0; //second=0; //P0=discode1[second/10]; //P2=discode2[second%10]; //break;}while((P3&0x80)==0x00); //如果按键时间过长在此循环}}}}void int_t0() interrupt 1 using 0 //定时器T0中断子程序{TR0=0; //停止计时,执行以下操作(计时出现误差)TH0=0xee; //向TH0写入初值的高8位TL0=0x00; //向TL0写入初值的低8位,定时5mstimer++; //记录中断次数if (timer==20) //中断20次,20*5ms=100ms=0.1s{timer=0; //中断次数清0second++; //加0.1sP0=discode1[second/10]; //根据计时时间,即时显示秒位P2=discode2[second%10]; //根据计时时间,即时显示0.1s位}if(second==99) //当计时到9.9s时{TR0=0; //停止计时second=0; //秒数清0key=2; //按键数置2,当再次按下按键时,key++,即key=3,秒表清0复原}else //计时不到9.9s时{TR0=1; //继续计时}}五、仿真运行效果展示1、第一次按键,秒表开始计时,并计时到9.92、2次按键,停止计时,将计时的时间值送到数码管显示3、第3次按下计时功能键,秒表清零六、实验小结在实验的过程中,出现过几次错误,自己对理论知识了解的还不够透彻,所幸,通过自己思考解决了。
AD转换的数码管显示*本例程采用AD0804 芯片,硬件电路:cs 片选端接P2.3,WR 写数据端写P3.6,RD 读数据端接P3.7,锁存端接P2.6 脚,数码管位选端分别接P3.2,P3.3,P3.4,段选端接P1 口*/#includereg52.h//头文件#define uint unsigned int//宏文件#define uchar unsigned char//宏文件uchar num;//变量void delay3(uint z); //延时定义void dissy();//延时函数定义sbit ge=P3 ;//个位定义sbit shi=P3;//十位定义sbit bai=P3;//百位定义sbit ad_cs=P2;//片选端sbit ad_wr=P3;//写数据端sbit ad_rd=P3;//读数据端sbit pian=P2;//锁存器片选void add();//ad 转换子函数void delay(uint i);//延时子函数申明uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86, 0x8e};//数组/************主函数**********/void main(){while(1){add();//调用AD 转换子函数dissy();//数码管显示子函数} }/************AD 转换子函数**********/void add()//AD 转换子函数{uchar i;ad_cs=1;//将片选关闭ad_cs=0;//将片选打开ad_wr=1;//写数上升沿ad_wr=0;//写数下降沿ad_wr=1;//写数上升沿P1=0xff;//送数到P0 口ad_rd=1;//读数上升沿delay(25);//延时一会儿ad_rd=0;//读数下降沿//////**************因为AD 转换时间周期长,我现在的数码管没有采用锁存器,AD 转换时间大于显示时间,所以显示时会闪烁,解决此问题方法是,连续调用了显示子程序七次,这样显示时就和AD 转换时一至,显示出来的数就不闪了********************//////for(i=0;i7;i++)//调用7 次,相当于delay(255)void dissy();//////**********************************//////num=P1;//将数给计数器num}/************显示子函数**********/void dissy()//显示子函数{P0=table[num/100];//百位显示数据bai=0;//百位打开delay(14);//延时一会bai=1;//。
秒表-八位数码管显示1;************************************************************************** 2; 标题: 秒表-八位数码管显示(汇编)3; 作者: wentao 4; 5; 日期: 2007.3.36; 软件: Keil A51 V8.007; 芯片: AT89X518; 说明: 实验板实测通过,数码管为8位共阳9; 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途!10;************************************************************************** 1112dot_l equ 30h ;30单元存储百分之一秒值13dot_h equ 31h ;31单元存储十分之一秒值14sec_l equ 32h ;32单元存储秒个位值15sec_h equ 33h ;33单元存储秒十位值16min_l equ 34h ;34单元存储分个位值17min_h equ 35h ;35单元存储分十位值18hou_l equ 36h ;36单元存储时个位值19hou_h equ 37h ;37单元存储时十位值2021dot equ 38h ;38单元为百分之一秒计数器(0.00s-0.99s)22sec equ 39h ;39单元为秒计数器(00s-59s)23min equ 40h ;40单元为分计数器(00m-59m)24hou equ 41h ;41单元为时计数器(00h-00h)2526dis_b equ 42h ;dis_b(42单元)作为位码选通数码管27dis_r equ 43h ;dis_r(43单元)为取段码时的偏移量2829key_t equ 44h ;44单元为键按下的次数标记3031K bit p1.4 ;K键与P1.4相连3233 org 0000h34 ajmp start35 org 000bh ;定时器0的中断入口地址36 ajmp time0 ;跳到定时器0的中断服务程序处37 org 001bh ;定时器1的中断入口地址38 ajmp time1 ;跳到定时器1的中断服务程序处39 org 0030h40start:41 mov p2,#0xff ;关所有数码管42 mov p1,#0xff ;p1为准双向口,作输入时先写14344 mov dis_b,#0x7f ;初始选通P2.7口数码管45 mov dis_r,#0 ;初始化偏移量为046 mov dot,#0 ;百分之一秒计数器清零47 mov sec,#0 ;秒计数清零48 mov min,#0 ;分计数清零49 mov hou,#0 ;时计数清零50 mov key_t,#0 ;键按下次数清零5152 mov tmod,#00010001b ;定时/计数器0、1工作于方式153 mov th0,#0xd8 ;预置定时常数55536(d8f0),产生10ms时基信号54 mov tl0,#0xf055 mov th1,#0xfc ;预置定时常数64536(fc18),产生1ms间隔用于动态显示56 mov tl1,#0x185758 setb ea ;开总中断59 setb et0 ;定时/计数器0允许中断60 setb et1 ;定时/计数器1允许中断61 clr tr0 ;关定时/计数器062 setb tr1 ;开定时/计数器16364lop:65 jb K,lop ;键(P1.4)未按下则返回66 lcall d_10ms ;延时10ms消抖67 jb K,lop ;是抖动则返回重新扫描68 jnb K,$ ;等待键松开69 lcall key_to ;调用键处理部分70 ajmp lop ;循环显示7172key_to: ;键处理子程序73 inc key_t ;键按下次数加174 mov a,key_t ;按下次数送入a75 cjne a,#1,key_2 ;不是1次继续检测是否是第2次76 setb tr0 ;第1次按下启动定时器077 ret78key_2: cjne a,#2,key_3 ;也不是2次继续检测是否是第3次79 clr tr0 ;第2次按下关闭定时器080 ret81key_3: cjne a,#3,back ;也不为3则结束82 mov dot,#0 ;第3次按下将四个计数器清零83 mov sec,#084 mov min,#085 mov hou,#086 mov key_t,#0 ;按键次数清零87back: ret88;--------------------------------------------------------------------------------89time0: ;定时器0中断服务程序90 push psw ;保护现场91 push acc9293 inc dot ;百分之一秒计数器加194 mov a,dot ;计数器值送入a95 cjne a,#100,over ;未计到100则返回继续计数96 mov dot,#0 ;计到100后清零97 inc sec ;秒计数器加1(进位10ms*100=1s)98 mov a,sec ;秒计数值送入a99 cjne a,#60,over ;未计到60则返回继续计数100 mov sec,#0 ;计到60后秒计数器清零101 inc min ;分计数器加1(进位60s=1m)102 mov a,min ;分计数值送入a103 cjne a,#60,over ;未计到60则返回继续计数104 mov min,#0 ;计到60后分计数器清零,重新计时105 inc hou ;时计数器加1(进位60m=1h)106 mov a,hou ;时计数器送入a107 cjne a,#100,over ;未计到100则返回继续计数108 mov hou,#0 ;计到100后清零109110over: mov th0,#0xd8 ;重置定时常数111 mov tl0,#0xf0112 pop acc ;恢复现场113 pop psw114 reti ;中断返回115;--------------------------------------------------------------------------------116time1: ;定时器1中断服务程序117 push psw ;保护现场118 push acc119 push b120 ;以下是百分之一秒计数器值个位十位分开121 mov a,dot ;百分之一秒计数器值送入a(被除数)122 mov b,#10 ;除数10送入b123 div ab ;a除以b124 mov dot_l,b ;余数b(百分之一秒值)送入百分之一秒存储单元125 mov dot_h,a ;商a(十分之一秒值)送入十分之一秒存储单元126 ;以下是秒计数器值个位十位分开127 mov a,sec ;秒计数器值送入a(被除数)128 mov b,#10 ;除数10送入b129 div ab130 mov sec_l,b ;余数b(秒个位值)送入秒个位存储单元131 mov sec_h,a ;商a(秒十位值)送入秒十位存储单元132 ;以下是分计数器值个位十位分开133 mov a,min ;分计数器值送入a(被除数)134 mov b,#10 ;除数10送入b135 div ab136 mov min_l,b ;余数b(分个位值)送入分个位存储单元137 mov min_h,a ;商a(分十位值)送入分十位存储单元138 ;以下是时计数器值个位十位分开139 mov a,hou ;时计数器值送入a(被除数)140 mov b,#10 ;除数10送入b141 div ab142 mov hou_l,b ;余数b(小时个位值)送入时个位存储单元143 mov hou_h,a ;商a(小时十位值)送入时十位存储单元144145 mov dptr,#table ;数码管段码表首址送入dptr146147 mov a,#dot_l ;取百分之一秒值的地址148 add a,dis_r ;基址+偏移量149 mov r0,a ;R0为欲显示值的地址150 mov a,@r0 ;取欲显示值送入a151 ; dis_r : 0 1 2 3 4 5 6 7152 ;对应单元: dot_l dot_h sec_l sec_h min_l min_h hou_l hou_h153 movc a,@a+dptr ;取对应值的段码154 mov p2,dis_b ;位码送入P2口155156 mov r0,dis_b ;取位码判断是否为需加小数点的位[liuwentao]157 cjne r0,#0xdf,b3 ;不是P2.5再判断是否为P2.3158 ajmp add_dot ;是P2.5则段码加上小数点显示159b3: cjne r0,#0xf7,b1 ;也不是P2.3再判断是否为P2.1160 ajmp add_dot ;是P2.3则段码加上小数点显示161b1: cjne r0,#0xfd,com ;也不是P2.1则正常送段码162163add_dot: anl a,#0x7f ;是P2.5,P2.3,P2.1则段码和7f做与操作使对应位显示小数点164com: mov p0,a ;段码送入P0口165166 inc dis_r ;偏移量加1,下次中断时显示下个数167 anl dis_r,#0x07 ;dis_r增到8时自动清0(使之在0到7间循环)168169 mov a,dis_b ;位码循环右移,下次中断时选通下个数码管170 rr a171 mov dis_b,a172173 mov th1,#0xfc ;重置定时常数174 mov tl1,#0x18175176 pop b177 pop acc ;恢复现场178 pop psw179 reti180181d_10ms: mov r5,#20 ;1+(1+2*255)*20+2*20=10.261ms@12M182temp1: mov r6,#255 ;1+2*255183 djnz r6,$184 djnz r5,temp1185 ret186187table: db 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf ;段码表188 ; 0 1 2 3 4 5 6 7 8 9 - 对应内容189190end191/************************************************************************** 192* 标题: 八位数码管显示(C51)193* 作者: wentao 194 195* 日期: 2007.3.3196* 软件: Keil C51 V8.02197* 芯片: AT89X51198* 说明: 实验板实测通过,数码管为8位共阳199* 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途!200**************************************************************************/ 201202#include <reg51.h>203#include <intrins.h>204#define uchar unsigned char205206void delay_ms(uchar ms); // 延时毫秒@12M,ms最大值255207void key_scan(); // 按键扫描208void key_to(); // 按键处理209210uchar code dis_code[11] = {0xc0,0xf9,0xa4,0xb0,0x99, //段码表211 // 0 1 2 3 4 对应内容212 0x92,0x82,0xf8,0x80,0x90,0xbf};213 // 5 6 7 8 9 -214215uchar data dis[8]; // dis[0]为百分之一秒值,dis[1]为十分之一秒值216 // dis[2]为秒个位值,dis[3]为秒十位值217 // dis[4]为分个位值,dis[5]为分十位值218 // dis[5]为时个位值,dis[6]为时十位值219220uchar data dot = 0; // 百分之一秒计数器(0.00s-0.99s)221uchar data sec = 0; // 秒计数器(00s-59s)222uchar data min = 0; // 分计数器(00m-59m)223uchar data hou = 0; // 时计数器(00h-99h)224225uchar data dis_b; // dis_b为位码选通数码管226uchar data dis_r; // dis_r为取段码时的偏移量227228uchar data key_t = 0; // 按键次数,初始为0229230sbit K = P1^4; // K键与P1.4相连231232void main()233{234 P2 = 0xff; // 关所有数码管235 P1 = 0xff; // p1为准双向口,作输入时先写1236 dis[2] = 10; // '-'在段码表中偏移量为10237 dis[5] = 10; // '-'在段码表中偏移量为10238 dis_b = 0x7f; // 初始选通P2.7口数码管239 dis_r = 0; // 初始化偏移量为0240241 TMOD = 0x11; // 定时/计数器0,1工作于方式1242 TH0 = 0xd8; // 预置定时常数55536(d8f0),产生10ms时基信号243 TL0 = 0xf0;244 TH1 = 0xfc; // 预置定时常数64536(fc18),产生1ms间隔用于动态显示245 TH1 = 0x18;246 EA = 1; // 开总中断247 ET0 = 1; // 定时/计数器0允许中断248 ET1 = 1; // 定时/计数器1允许中断249 TR0 = 0; // 关闭定时/计数器0250 TR1 = 1; // 启动定时/计数器1251 while(1)252 {253 if(K != 1) // 有键按下254 {255 delay_ms(10); // 延时10ms去抖256 if(K != 1) // 确定是有键按下257 {258 while(K != 1); // 等待键松开259 key_to(); // 按键处理260 }261 }262 }263}264void key_to() // 按键处理子程序265{266 key_t++; // 按键次数加1267 if(key_t == 1) // 第一次按下268 TR0 = 1; // 启动定时器0269 else270 {271 if(key_t == 2) // 第二次按下272 TR0 = 0; // 关闭定时器0273 else274 {275 if(key_t == 3) // 第三次按下276 {277 dot = 0; // 四个计数器清零278 sec = 0;279 min = 0;280 hou = 0;281 key_t = 0; // 按键次数清零282 }283 }284 }285286}287void tiem0(void) interrupt 1 // T/C0中断服务程序(产生10ms时基信号) 288{289 dot++; // 百分之一秒计数器加1290 if(dot == 100) // 计数值到100291 {292 dot = 0; // 清零293 sec++; // 秒计数器加1(进位10ms*100=1s)294 if(sec == 60) // 秒计数值到60295 {296 sec = 0; // 秒计数器清零297 min++; // 分计数器加1(进位60s=1m)298 if(min == 60) // 分计数到60299 {300 min = 0; // 分计数器清零301 hou++; // 时计数器加1(进位60m=1h)302 if(hou == 100) // 时计数器到100303 hou = 0; // 时计数器清零304 }305 }306 }307 TH0 = 0xd8; // 重置定时常数308 TL0 = 0xf0;309}310void time1(void) interrupt 3 // T/C1中断服务程序(延时1ms数码管动态显示) 311{312 uchar data t = 0; // 段码临时变量313314 dis[0] = dot % 10; // 百分之一秒计数器个位分离出来赋绐dis[0] 315 dis[1] = dot / 10; // 百分之一秒计数器十位分离出来赋绐dis[1] 316 dis[2] = sec % 10; // 秒计数器个位赋绐dis[2]317 dis[3] = sec / 10; // 秒计数器十位赋绐dis[3]318 dis[4] = min % 10; // 分计数器个位赋绐dis[4]319 dis[5] = min / 10; // 分计数器十位赋绐dis[5]320 dis[6] = hou % 10; // 时计数器个位赋绐dis[6]321 dis[7] = hou / 10; // 时计数器十位赋绐dis[7]322323 t = dis_code[dis[dis_r]]; // 取出段码放入临时变量t324325 // 判断位码如果为显示P2.5,P2.3,P2.1则对应段码应加上小数点显示326 // 和0x7f(01111111)做与操作使原段码加上小数点变为新段码327328 if(dis_b == 0xdf | dis_b == 0xf7 | dis_b == 0xfd)329 t &= 0x7f;330331 P2 = dis_b; // 位码送P2口332 P0 = t; // 段码送P0口333334 dis_r++; // 偏移量加1,下次中断时显示下个数335 dis_r &= 0x07; // dis_r增到8时自动清0(使之在0到7间循环) 336337 dis_b = _cror_(dis_b,1); // 位码循环右移,下次中断时选通下个数码管338339 TH1 = 0xfc; // 重置定时常数340 TL1 = 0x18;341342}343void delay_ms(uchar ms) // 延时毫秒@12M,ms最大值255344{345 uchar i;346 while(ms--)347 for(i = 0; i < 124; i++);348}广州珍珠岩,广州珍珠岩厂 Ce57uICIJeu8。
电压采集,AD转换程序,数码管显示#include#includesbit ADC_CS=P3^5; //片选引脚,低电平有效sbit ADC_CLK=P3^4; //ADC0832芯片的时钟输入引脚sbit ADC_DO=P3^3; //数据信号输出引脚,用于将转换的数据输给单片机sbit ADC_DI=P3^3; //数据信号输入引脚,用于通道的选择控制#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换sbit LATCH1=P2^2;//定义锁存使能端口段锁存sbit LATCH2=P2^3;// 位锁存void Delay(unsigned char x);unsigned char ReadADC(viod);unsigned char TempData[8]; //存储显示值的全局变量unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x 7f,0x6f};// 显示段码值0~9unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码void Display(unsigned char FirstBit,unsigned char Num);void main(){unsigned char a;a=ReadADC();while(1){TempData[0]=dofly_DuanMa[a/100];//分解显示信息,如要显示68,则68/10=6 68%10=8TempData[1]=dofly_DuanMa[(a%100)/10];TempData[2]=dofly_DuanMa[(a%100)%10];Display(2,3);}}// 延时函数void Delay(unsigned char x){unsigned char i;for(i=0;i<x;i--);}// 把模拟电压转换成八位二进制数,并返回unsigned char ReadADC(unsigned char b){unsigned char i,ch;ch=0;ADC_CS=0; //片选引脚,低电平有效,ADC_DO=0; //DO为高阻状态for(i=0;i<10;i++); //稍做延时ADC_CLK=0;Delay(2); //以上那个为准备工作ADC_DI=1;ADC_CLK=1;Delay(2); //第一个脉冲,起始位ADC_CLK=0;Delay(2);ADC_DI=1;ADC_CLK=1;Delay(2); //第2个脉冲,DI=1表示双通道单极性输入ADC_CLK=0;Delay(2);ADC_DI=1;ADC_CLK=1;Delay(2); //第3个脉冲,DI=1表示表示选择CH1,马上准备读取转换数据ADC_CLK=1;Delay(2);ADC_CLK=0;Delay(2);for(i=0;i<8;i++){ADC_CLK=1;Delay(2);ADC_CLK=0;Delay(2);ch=(ch<<1)|ADC_DO;}ADC_CS=1; //取消片选,一个转换周期结束return(ch);}void Display(unsigned char FirstBit,unsigned char Num) {unsigned char i;for(i=0;i<num;i++){DataPort=0; //清空数据,防止有交替重影LATCH1=1; //段锁存LATCH1=0;DataPort=dofly_WeiMa[i+FirstBit]; //取位码LATCH2=1; //位锁存LATCH2=0;DataPort=T empData[i]; //取显示数据,段码LATCH1=1; //段锁存LATCH1=0;Delay(200); // 扫描间隙延时,时间太长会闪烁,太短会造成重影}}</num;i++)</x;i--);。
MPS430F149单片机之_模拟电压AD转换数码管显示数值/************************************************************** ***将P6口输入的模拟电压AD转换后,从P4,P5口连接的数码管输出*************************************************************** **/#include //声明库/************************************************************** ******数据类型定义*************************************************************** ******/#define uchar unsigned char#define uint unsigned int/************************************************************** ******数码管段码定义0123456789*************************************************************** ******/ucharTable[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码uchar wei[4]={0XEF,0XDF,0XBF,0X7F};//控制位uint z,x,c,v, date=0; //定义数据类型/************************************************************** ********延时函数程序,参数i 延时时间*************************************************************** *******/void DelayMS(uint i){uint j;for(;i!=0;i--){for(j=200;j!=0;j--);}}/************************************************************** ********按键函数*************************************************************** *******/void KEY()//按键函数名{if(!(P1IN&BIT0))//判断按键按下{DelayMS(100);//消抖延时while(!(P1IN&BIT0));//判断按键松开date++;//按键数值加1}}/************************************************************** ********数码管动态扫描*************************************************************** ******/void Pre_Display(){/***********************数据转换*****************************/ z=date/1000; //求千位x=date%1000/100;//求百位c=date%100/10; //求十位v=date%10; //求个位P5OUT=wei[0]; //位控制P4OUT=Table[z]; //显示千位DelayMS(5); //延时P5OUT=wei[1]; //位控制P4OUT=Table[x]; //显示百位DelayMS(5); //延时P5OUT=wei[2]; //位控制P4OUT=Table[c]; //显示十位DelayMS(5); //延时P5OUT=wei[3]; //位控制P4OUT=Table[v]; //显示个位DelayMS(5); //延时}/************************************************************** ******I/O口初始化*************************************************************** ******/void Init_IO(void)//初始化I/O{P1DIR&=~BIT0;//设置P4口为输出P4DIR=0XFF;//设置P5口为输出P5DIR=0XFF;}/************************************************************** ******主函数*************************************************************** ******/void main(void)//主函数{Init_IO();//初始化I/OWDTCTL=WDTPW+WDTHOLD;//关闭看门狗while(1)//无限循环{KEY();//数码管显示数值Pre_Display();//数码管扫描显示函数}}/************************************************************** ******结束*************************************************************** ******/。
6.2-AD转换操作+数码管显示//由通道A TD0进行单通道A/D转换,转换值在B口显示,并用数码管实现二进制值//与B口对应//AN7接电位器0~5V输入#include <hidef.h> /* common defines and macros */#include "derivative.h"/* derivative-specific definitions */const unsigned char DisplayDecode[]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f,~0x40,~0xff,0x88,0x83,0xc6,0XA1,0x86,0x8e,0xd0,0x89};//'- ABCDEFGH'const unsigned char WeiMa[]={0xfe,0xfd,0xfb,0xf7};void display(unsigned char wei,unsigned char data);void delay_ms(int m);void dis(int time ,int a, int b, int c,int d) ;byte ad_value; //AD转换结果/*-----------------ms 级延时---------------------*/void delay_ms(int m){int i,j;for(j=0;j<m;j++)for(i=0;i<800;i++);}/***---------------初始化程序---------------***/void InitAD(void){ATD0CTL2 = 0XC0; //1100 0000 启动A/D,快速清除标志位//无等待模式,外部触发禁止(bit2=0),//中断禁止(bit1=0)ATD0CTL3 = 0X0C; //0 0001 1 00 转换序列为1 、FIFO模式启动,冻结模式下继续转换ATD0CTL4 = 0XE1; // 1 11 00001 8位精度,24个A TD采样时间// 总线(1+1)*2 = 4 分频,AD时钟= 1MHz ATD0CTL5 = 0X27; // 0 0 1 0 0 111 右对齐,无符号,连续转换,单通道, 起始通道A TD7ATD0DIEN = 0X00; // 数字输入disabled}/***---------------主程序---------------***/void main(void) {InitAD();DDRB=0XFF; // 设PORTB为输出口PORTB=0xff;DDRP=0xFF;DDRT=0xFF;EnableInterrupts; // 开放总中断for(;;) {while(!ATD0ST AT2L_CCF7); //等待转换结束,退出循环ad_value=(byte)ATD0DR7H;//左对齐,右对齐时转换结果都先存储在A TD0DRxH,后存储在A TD0DRxL.PORTB=ad_value; //PORTB输出AD转换结果,并用8个LED发光二极管显示dis(1,(ad_value%100)%10,(ad_value%100)/10,ad_value/100,0);}}void dis(int time ,int a, int b, int c,int d){int i;for(i=1;i<time*25;i++) {display(1,a);display(2,b);display(3,c);display(4,d);}}void display(unsigned char wei,unsigned char data){PTT=WeiMa[wei-1];PTP=DisplayDecode[data];delay_ms(10);}。
#define F_CPU 4000000UL //4 MHZ#include<avr/io.h>#include<util/delay.h>#define INT8U unsigned char#define INT16U unsigned int//各数字的数码管段码,最后一位为空白const INT8U SEG_CODE[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0xFF}; //两路模拟转换结果显示缓冲,显示格式为:X.XX X.XX ,第4位和第8位不显示INT8U Display_Buffer[]={0,0,0,10,0,0,0,10};//___________________________________________//对通道CH进行模拟数字转换void ADC_Convert(INT8U CH){int Result;ADMUX=CH; //ADC通道选择//读取转换结果,并转换为电压值Result=(int)((ADCL+(ADCH<<8))*500.0/1023.0);//或使用语句:Result=(int)(ADC*500.0/1023.0);//ADC0的结果放入数组0、1、2单元,ADC1的结果放入数组4、5、6单元Display_Buffer[CH*4]=Result/100;Display_Buffer[CH*4+1]=Result/10%10;Display_Buffer[CH*4+2]=Result%10;}//主函数int main(){INT8U i;DDRA=0xFC;//配置AD转换端口ADC0、ADC1为输入DDRC=0xFF;PORTC=0x00;//配置数码管显示端口DDRD=0xFF;PORTD=0x00;ADCSRA=0xE6;//ADC转换置位,启动转换,64分频_delay_ms(3000);//延时等待系统稳定while(1){ADC_Convert(0);ADC_Convert(1);//对2个通道进行A/D转换for(i=0;i<8;i++){PORTC=0xFF;//先关闭段码PORTD=_BV(i);//发送数码管位码PORTC=SEG_CODE[Display_Buffer[i]];//发送数字段码if(i==0||i==4)PORTC&=0x7F;//对整数位加小数点_delay_ms(4);}} }。
电子科技大学微电子与固体电子学院实验报告实验名称现代电子技术综合实验姓名:詹朋璇学号:2011031030024评分:教师签字电子科技大学教务处制电子科技大学实验报告学生姓名:詹朋璇学号:2011031030024 指导教师:熊万安实验地点:211大楼308 实验时间:2014. 6.30 晚一、实验室名称:单片机技术综合实验室二、实验项目名称:数码管显示A/D转换的电压值&数码管显示秒表三、实验学时:12四、实验目的与任务:1、熟悉系统设计与实现原理2、掌握KEIL C51的基本使用方法3、熟悉实验板的应用4、连接电路,编程调试,实现各部分的功能5、完成系统软件的编写与调试五、实验器材1、PC机一台2、实验板一块六、实验原理、步骤及内容试验要求:数码管的第1位显示任务号1,第3位到第5位显示、A/D转换的电压值,可调节电压,第7、8位显示两位学号;数码管第2位和第6位显示“-”号;按按键key1进行切换,此时数码管第1位显示任务号2,第7、8位显示循环倒计时的秒表,范围为08秒到01秒后,再过01秒,秒表又显示为08秒;(单片机系统中利用定时器/计数器计数秒表的值:利用定时器T0延时1秒进行计数。
),其它位显示不变,按按键key2时,秒表停止计数,再按按键key2时,秒表继续计数,按key1键,又回到任务1的显示状态。
当电压值大于2伏时,按按键不起作用。
1、硬件设计(可打印)2、各部分硬件原理(可打印)数码管动态扫描TLS549ADC工作时序图3、软件设计思考题:按键改用外部中断模式,电路如何修改(画示意图)?程序如何修改,写出中断服务程序。
答:将KEY1与KEY2键通过跳线分别接到INT0与INT1接口上。
开启中断:SysInit(){ …EA=0; //禁止总中断EX1=1; //使能/INT1 中断EX0=1; //使能/INT0 中断EA=1; }//使能总中断中断服务程序:void INT0SVC () interrupt 0{if(cnt<=31) cnt++;}void INT1SVC () interrupt 2{if(cnt>=17) cnt--;}七、总结及心得体会1.利用单片机开发板上丰富的资源可以实现一个有一定功能的系统。
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 cd e f - blank,全亮unsigned char DispBuf[8]; //定义显示缓冲区(由定时中断程序自动扫描)unsigned char key_value,flag;//定义键盘返回值,任务标志unsigned char y1000,y100,y10,y;//定义秒表的个位,十分位,百分位,千分位unsigned short mbiao;//定义秒表计数单元void delay(int ms); //延时大约1msunsigned 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 = 0xFC;TL0 = 0x66;TR0 = 1;ET0 = 1;EA =1;AdcInit();for(i=0; i<8; i++)DispBuf[i] = 17; //全部8位显示灭y1000=9;y100=9;y10=9;y=9;mbiao=9999;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[0] = 4;DispBuf[1] = 2;DispBuf[2] = 16;DispBuf[3] = x;DispBuf[4] = x10;DispBuf[5] = x100;DispBuf[6] = 16;DispBuf[7] = 1;delay(100);if(key_value == 8&&volt<=200){flag = 1;mbiao=9000;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] = y1000;DispBuf[1] = 0;DispBuf[2] = 16;DispBuf[3] = x;DispBuf[4] = x10;DispBuf[5] = x100;DispBuf[6]=16;DispBuf[7]=2;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);}}}}/*函数:T1INTSVC()功能:定时器T1的中断服务函数*/void T1INTSVC() interrupt 3{code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};static unsigned char n = 0;TR1 = 0;TH1 = 0xFC;TL1 = 0x66;TR1 = 1;LED_dig = 0xFF; //暂停显示if(flag==0){if(n==5)LED_seg = ~(disp_seg[DispBuf[n]]|0x80);elseLED_seg = ~disp_seg[DispBuf[n]];//更新扫描数据}if(flag==1){ if(n==5)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]]; //更新扫描数据}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 = 0xFC;TL0 = 0x66;TR0 = 1;if(mbiao<=9000&&TR0==1)mbiao=mbiao-1;if(mbiao==0)mbiao=9000;y1000=mbiao/1000;y100=(mbiao-y1000*1000)/100;y10=(mbiao-y1000*1000-y100*100)/10;y=(mbiao-y1000*1000-y100*100)%10;}。