有八4位共阳数码管管和一个矩形按键,用keil中的AT89c51编写秒表的程序。

用AT89C51设计一个4位的LED数码显示作为“秒表”:显示时间为00—99.99秒,其中通过第二位数码管闪烁作秒计_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
用AT89C51设计一个4位的LED数码显示作为“秒表”:显示时间为00—99.99秒,其中通过第二位数码管闪烁作秒计
要求按键抬起时再动作,按键按下时会发出啪的一声,开始键和暂停键复用一个按键;暂停”键和一个“复位”键,其中另设计一个“开始&#47
我有更好的答案
这个多看看资料其实挺简单的,说白了就是一个数字钟的形式,开始/暂停就用按键开启/关闭定时器就可以了!
为您推荐:
其他类似问题
您可能关注的内容
at89c51的相关知识
换一换
回答问题,赢新手礼包51单片机c语言的秒表设计_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
51单片机c语言的秒表设计
&&单片机课程设计
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩13页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢设计一个9-0的倒计时秒表,利用AT89C51单片机的并口驱动一个共阳型数码管进行显示_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
设计一个9-0的倒计时秒表,利用AT89C51单片机的并口驱动一个共阳型数码管进行显示
计算出共阳型数码管的所有字形的断码,利用KEIL软件进行编写汇编,谢谢
我有更好的答案
我的百度空间,有两位的。
为您推荐:
其他类似问题
at89c51的相关知识
换一换
回答问题,赢新手礼包单片机秒表程序 80C51_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
单片机秒表程序 80C51
求一个单片机程序 用80C51单片机制作秒表的程序 三个按键 两个数码管 有复位电路 外接晶振 求一个程序 简单介绍一下程序万分感谢 会加分
我有更好的答案
include & EA=1;}void KEY()
//请注意写程序时的格式规范;
//计数重新从零开始十位选通定义void Delay(unsigned int tc)
///个位选通定义sbit shiwei=P2^7;/定义计数值,每过1/10秒,sec加一unsigned char keycnt=0;
&#47,0x66,
0x6d,0x7d;j--);
if(P3^0==0)
switch(keycnt)
//定时10秒,0x6f};
P0=table[sec%10];
//第一次按下
TH0=0x06;/LED显示函数{
P0=table[sec&#47,0x5b,0x4f;/定时器工作在方式2ET0=1;
shiwei=1;reg52;延时程序{ while( tc != 0 )
{定时结束0;/每过250ust tcnt加一if(tcnt==400)
//计满400次(1//开始定时
&#47,此处是为了节省纸张void t0(void) interrupt 1 using 0
for(i=0; i&100; i++);
}}void LED()
/按下次数判断
///第三次按下
keycnt=0;/按键扫描程序{unsigned char i.H& unsigned char code table[]={0x3f,0x06;/对TH0 TL0赋值
TL0=0x06; if(P3^0==0)
for(i=20; sec=0; while(1)
gewei=1;定时中断服务函数{ tcnt++;
/键值判断sbit gewei=P2^6,在从零开始计时
} }void main(void) { TMOD=0x02;
/重新开始判断键值
//10秒)时
tcnt=0;/重新再计
if(sec==100) //
/延时去干扰
for(j=248;j&
/第二次按下
while(P3^0==0);
//i&0;i--)
/&#47,0x07,0x7f
采纳率:28%
好好上课去,这倒霉孩子
//键盘 蜂鸣器 时钟-闹钟 程序 希望对你有帮助//功能键 //模式1或模式4时 //12 进入模式2; 11 进入模式3 ;1 退出模式4(当前为模式4),转为模式1//模式2时//12 退出模式2,回到上一模式; 11 光标移位; 1-9 数字键//模式3时//12 光标移位; 11 退出模式3,回到上一模式; 1-9 数字键#include &reg51.h&#include&intrins.h&#define NOP();{_nop_(); _nop_(); _nop_(); _nop_();}
/* 定义空操作指令 */#define uchar unsigned char#define uint unsigned intuchar ii = 1;uchar mod = 1; //用于标志当前模式 1表示正常工作(没有闹钟),1表示设置时间,2表示设置闹钟,4表示正常工作的同时闹钟还要显示uchar mod_last = 0; //记录上一模式 //辅助延时 1s 的计数变量,用于定时器0uint n_T1; //用于定时器1uchar hour,min, //时间uchar hour_r,min_r,sec_r; //闹钟时间uchar h_temp,m_temp,s_uchar time[]={0, 0, 0, 0, 0, 0};uchar time_r[]={0, 0, 0, 0, 0, 0};sbit bell= P1^7;
/*蜂鸣器*/bit
FLAG0=0; // 扫描键盘的标志位uchar ptr = 13; // 哪个键按下了?uchar ptr_last = 0; //上一次扫描键盘值,通过和这次比较,用于检测上升沿uchar count = 0; //设置时间时记住设置到哪位(时2位,分2位,秒2位,共6位,依次为1到6)?bit mm = 0; //闪烁扫描的标志位,0 不显示,1 显示sbit LCD_RS=P2^5; //RS为液晶的寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。sbit LCD_EN=P2^7; //E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。sbit LCD_RW=P2^6; //RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。uchar time_h,time_l; //校正定时器的临时变量void delay(uint x) //简单延时{
while(x--&0) //判断完x是否大于0,无论结果,x就--
for(j=0;j&125;j++)
{;} }}void scan_key(void)
/*扫描键盘副程式*/{ uchar a1=0xF7,i,m;
/*A1=0XF7列扫描初值,I行*/
/*设按键回应旗号为0,键盘扫描计数指标为0*/ for(i=1;i&5;i++)
/*键盘3个扫描列*/ {
/*列扫描输出,读入P1存入M,以便侦测行与侦测按键是否放开*/
switch(m&0x87)
/*取行的高4位元,侦测那一行被按*/
case 0x83:
if(i==1)ptr=1;
if(i==2)ptr=4;
if(i==3)ptr=7;
if(i==4)ptr=10;
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
} /*跳出此循环*/
case 0x85:
if(i==1)ptr=2;
if(i==2)ptr=5;
if(i==3)ptr=8;
if(i==4)ptr=11;
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
} /*跳出此循环*/
case 0x86:
if(i==1)ptr=3;
if(i==2)ptr=6;
if(i==3)ptr=9;
if(i==4)ptr=12;
FLAG0=1; /*是则设FLAG0=1表有按键输入*/
} /*跳出此循环*/
default: /*跳出此循环*/
if(FLAG0==1)
/*不为1,则扫描列右移,扫描下一列*/
a1=(a1&&1)|0x87;
} //检测到按键就让蜂鸣器响一下 if(FLAG0) {
delay(160);
bell = 1; }} void LCD_STROBE(void)
/*LCD闸门滤波,或者说液晶使能?*/{ LCD_EN=1; NOP(); LCD_EN=0;}unsigned char lcd_read_cmd_nowait(void){ LCD_RW=1;
当RS为低电平RW为高电平时可以读忙信号
//关液晶? NOP(); readc=P0; LCD_EN=0;
/* 返回写入液晶的默认模式*/ LCD_RW=0;
//低电平时进行写操作 return(readc);}void lcd_check_busy(void) /*当液晶不再busy,或者等待时间足够长时,返回*/{ for(retry=1000;retry&0;retry--)
//如果一直都忙,重试1000次??? {
c=lcd_read_cmd_nowait();
/* Check busy bit.
If zero, no longer busy*/
if(0==(c&0x80)) //与操作 //如果c的最高位为0,退出重试,说明不忙 }}void lcd_cmd(unsigned char c)
/*发一个命令到液晶*/{ P0=c; LCD_STROBE(); // LCD闸门滤波 有什么用?液晶使能?}void lcd_data(unsigned char c)
/*发数据到液晶*/{ lcd_check_busy(); //出这个函数时 LCD_RW=0; LCD_RS=1; //作用?为高电平时选择数据寄存器 当RS为高电平RW为低电平时可以写入数据 NOP(); P0=c; //向P0输入数据 LCD_STROBE(); LCD_RS=0; //作用?为低电平时选择指令寄存器 当RS和RW共同为低电平时,可以写入指令或者写入显示的地址 为下一次的lcd_cmd(?) 做准备}void lcd_puts(const char *s)
/*写一串字符到液晶*/{ while(*s) //如果指针所指有内容
lcd_data(*s++); //先输出 *s ,然后 s 进行 ++ 操作;s是指针,*s是指针的内容}void clear_display(void)
/*液晶清屏*/{ lcd_cmd(0xc0); //第二行 lcd_puts(&
&); lcd_cmd(0x80); //第一行 lcd_puts(&
&);}void lcd_init(void)
/*液晶初始化*/{ LCD_RS=0; //选指令寄存器 LCD_EN=0; // LCD_RW=0; //RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时,可以写入指令或者写入显示的地址。工作时都为低? delay(); //为什么要延时?延时5000us = 5 ms 大概 P0=0x3f; // Set Function: 8位接口,两行显示,5*10点阵 0x3f LCD_STROBE(); lcd_cmd(0x38);//8 bits interface,2 lines display.5×点阵7//但是这块东西最多支持5*8所以5*10没意义 lcd_cmd(0x0f);//Display On(整体显示), Cursor(指针、光标) On, Blink(指针:闪烁、眨闪) on lcd_cmd(0x01); //Display Clear 也可以写成 0x1(所有内容消除,把光标定位到第一行第一位) lcd_cmd(0x06); //Entry Mode (set cursor move direction: cursor moves increase,(Specifies shift of display)display is not shifted
//指令3:(D2 = 1); (D1):光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移; (D0): S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效 clear_display();}void change(void){ time[0]=hour/10; //时间更新 time[1]=hour%10; time[2]=min/10; time[3]=min%10; time[4]=sec/10; time[5]=sec%10; time_r[0]=hour_r/10; //闹时更新,只有在模式3中才会??,在其他时候也不影响 time_r[1]=hour_r%10; time_r[2]=min_r/10; time_r[3]=min_r%10; time_r[4]=sec_r/10; time_r[5]=sec_r%10; }void display(uchar tmp){
switch(tmp)
case 0 : lcd_puts(&0&);
case 1 : lcd_puts(&1&);
case 2 : lcd_puts(&2&);
case 3 : lcd_puts(&3&);
case 4 : lcd_puts(&4&);
case 5 : lcd_puts(&5&);
case 6 : lcd_puts(&6&);
case 7 : lcd_puts(&7&);
case 8 : lcd_puts(&8&);
case 9 : lcd_puts(&9&);
default : ;
} }void scan() //正常工作时扫描液晶 {
lcd_cmd(0xc0);
if(mod == 3||mod == 4)
lcd_puts(&T:
&); //共16位
else if(mod == 1||mod == 2)
lcd_puts(&
&); //共16位
lcd_cmd(0xc4); //时
display(time[0]);
lcd_cmd(0xc5);
display(time[1]);
lcd_cmd(0xc6);
lcd_puts(&:&);
lcd_cmd(0xc7); //分
display(time[2]);
lcd_cmd(0xc8);
display(time[3]);
lcd_cmd(0xc9);
lcd_puts(&:&);
lcd_cmd(0xca); //秒
display(time[4]);
lcd_cmd(0xcb);
display(time[5]);
lcd_cmd(0xcc);
lcd_puts(&
&);if(mod == 3||mod == 4) //模式3与模式4时,扫描第一行显示
lcd_cmd(0x80); //前面四位
if(mod == 3)
lcd_puts(&SR: &); //共16位,SR 设置闹钟
lcd_puts(&R:
&); //共16位
lcd_cmd(0x84); //闹时
display(time_r[0]);
lcd_cmd(0x85);
display(time_r[1]);
lcd_cmd(0x86);
lcd_puts(&:&);
lcd_cmd(0x87); //闹分
display(time_r[2]);
lcd_cmd(0x88);
display(time_r[3]);
lcd_cmd(0x89);
lcd_puts(&:&);
lcd_cmd(0x8a); //闹秒
display(time_r[4]);
lcd_cmd(0x8b);
display(time_r[5]);
lcd_cmd(0x8c); //最后四位
lcd_puts(&
else if(mod == 1)
lcd_cmd(0x80); //液晶地址 第一行 0x80 到 0x8f ,第二行 0xc0 到 0xcf
lcd_puts(&
else if(mod == 2)
lcd_cmd(0x80); //液晶地址 第一行 0x80 到 0x8f ,第二行 0xc0 到 0xcf
lcd_puts(&
} }void scan_wink() //用于进入模式(设置时间、设置闹钟)时的扫描液晶,具有闪烁功能{ if(mod == 2) //设置时间模式,闪烁第二行
position = 0xc4; else if(mod == 3) //设置闹钟模式,闪烁第一行
position = 0x84; for(ii = 1; ii&=6; ii++) {
if(count == ii)
if(ii &= 2)
lcd_cmd(position+ii-1);
else if(ii&= 5)
lcd_cmd(position+ii-1+2);
lcd_cmd(position+ii-1+1);
} } if(mm) //该亮 {
if(mod == 2)
display(time[count-1]);
else if(mod == 3)
display(time_r[count-1]); }
if(!mm&&(count&=1&&count&=6)) //不该亮(即是显示空格)
lcd_puts(& &); mm = ! //翻转亮与不亮的模式
}void in_judge(){ if((mod == 1||mod == 4)&&(ptr == 12&&ptr_last != 12)) //判断是否要进入设置时钟模式 {
mod_last =
TR0 = 0; //停止计时 } else if((mod == 1||mod == 4)&&(ptr == 11&&ptr_last != 11)) //判断是否要进入设置闹钟模式 {
mod_last =
hour_r = 0; //初始化闹钟时间为00:00:00
min_r = 0;
sec_r = 0; }}void out_judge(){ if(mod == 2&&(ptr == 12&&ptr_last !=12)) //判断是否要退出设置时钟模式 {
mod = mod_
/*定时50ms,11.0592MHz*/
TR0=1; //开始计时
n=20; } else if(mod == 3&&(ptr == 11&&ptr_last != 11)) //判断是否要退出设置闹钟模式 {
mod_last = } else if(mod == 4&&(ptr == 10&&ptr_last != 10)) {
mod = 1; }}void shift_judge() //在模式2和模式3中的移位判断{ if(ptr == mod+9&&ptr_last != mod+9) //模式2 mod+2 = 11,模式3 mod+2 = 12 {
if(count&6)
count = count%6; }}void ptr_last_update(){ if(!FLAG0||ptr&13) //更新上一次的按键值 {
if(!FLAG0)
ptr_last = }}void main(){
TMOD=0x11; //定时器0和定时器1都为方式1 16位定时器
/*定时50ms,11.0592MHz*/
IE=0x8a; //定时器0和定时器1都中断使能
IP=0x02; //定时器0具有最高优先级hour=0; //时钟初始化
hour_r = 0; //闹钟初始化
min_r = 0;
sec_r = 0;
lcd_init(); //液晶初始化
lcd_cmd(0x0c); //去掉光标
mod = 1; //初始化模式为1 正常模式
mod_last = 1;while(1)
count = 1;
scan_key();//扫描键盘
out_judge();//判断是否要从模式4退出到模式1
in_judge();//判断是否进入模式2或模式3
ptr_last_update();//更新ptr_last
while(mod == 2||mod == 3)
scan_wink(); //闪烁扫描
delay(150);
if(mod == 2) //暂时变量保存
h_temp = hour_r;
m_temp = min_r;
s_temp = sec_r;
if(count == 1) //处理输入
if(ptr &= 1&&ptr &=3)
h_temp = 10*(ptr-1)+h_temp%10;
else if(count == 2)
if(ptr &= 1&&ptr &=4)
h_temp = (h_temp/10)*10+ptr-1;
else if((count == 3||count ==5)&&(ptr&=1&&ptr&=6))
if(count == 3)
m_temp = 10*(ptr-1)+m_temp%10;
s_temp = 10*(ptr-1)+s_temp%10;
else if((count == 4||count == 6)&&(ptr&=1&&ptr&=10))
if(count == 4)
m_temp = (m_temp/10)*10+ptr-1;
s_temp = (s_temp/10)*10+ptr-1;
if(mod == 2) //暂时变量返回
hour_r = h_
min_r = m_
sec_r = s_
//change();
scan_key(); //下次一扫描键盘
out_judge();
shift_judge();
ptr_last_update();
change(); //回到模式1或模式4
delay(30); }}void time_50ms() interrupt 1 //定时器0的中断处理程序 50MS{ /*TR1 = 0;
//多了这段 46个指令周期,没有的话 24 22/2 = 11 time_h = TH1+0x4c; time_l = TL0+0x07; time_h = TH1; time_l = TL0; TR1 = 0; time_h = TH1+0x4c; time_l = TL0+0x07; time_h = TH1; time_l = TL0;*/
TR0 = 0; time_h = TH0; //用于补偿进入中断过程的耗时 time_l = TL0;
TH0=0x4c+time_h;
//算不算两条指令??YES 3cb0 本来TL0 = 0xb0 要加11条指令才能补偿下面从TR0=0后到TR0=1完 TL0=0x0b+time_l;
//但是实验板上的是11.0592 变成了 4C00H TR0=1; //启动计时器
TF0=0; //计时器溢出归位 n--; if(n==0) {
if(sec == 59)
if(min == 59 )
if(hour == 23)
if((hour == hour_r&&min == min_r&&sec == sec_r)&&mod == 4) // 闹时到了,触发闹铃
TL1 = 0x00;
n_T1 = 12000;
} }}void time_10ms() interrupt 3 //闹铃响2分钟 计12000次{ TR1 = 0; time_h = TH1; time_l = TL1; TH1 = 0xdc+time_h;
//算不算两条指令??YES 3cb0 本来TL0 = 0x00 要加11条指令才能补偿下面从TR1=0后到TR1=1完 TL1 = 0x0b+time_l;
//但是实验板上的是11.0592 变成了 4C00H TR1=1; //启动计时器
TF1=0; //计时器溢出归位 n_T1--; if((n_T1%50) == 0) //响的时间间隔为500ms
bell = ! if(n_T1 &= 0) //响够了 {
bell = 1; //不响
n_T1 = 12000; }}
假设数码管是普通的7段数码管,按键分别是启动、停止、继续。晶振是11.0592MHz,程序采用定时器中断方式,可以每个中断周期设置为10ms,在中断中设置计数器,在主程序中进行判断,如果计数器的值大于100,则主程序将秒数增加1,并重新显示秒数,同时将计数器的值减去100.具体程序要根据你现有的硬件连接关系确定。如还不清楚,QQ.
其他1条回答
为您推荐:
其他类似问题
您可能关注的内容
秒表的相关知识
换一换
回答问题,赢新手礼包基于51单片机的电子秒表实训报告(含有程序和图)_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于51单片机的电子秒表实训报告(含有程序和图)
&&实训报告
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩20页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 共阳数码管段码表 的文章

 

随机推荐