用51单片机设计了一个简单的倒计时器,但数码管有点小问题,请教高手
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用51单片机设计了一个简单的倒计时器,但数码管有点小问题,请教高手相关的知识,希望对你有一定的参考价值。
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]=0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F;
uchar data1[]=5,9;
sbit a=P1^0;
sbit b=P1^1;
sbit c=P1^2;
sbit d=P1^3;
sbit e=P3^0;
sbit f=P3^2;
void keyscan();
void display();
void delayms(uint t)
uint a,b;
for(a=t;a>0;a--)
for(b=125;b>0;b--);
void display()
uchar i;
P2=0X01;
for(i=0;i<2;i++)
P0=table[data1[i]];
P2=~(P2<<i);
delayms(5);
P2=~P2;
while(!(data1[1]||data1[0]))
TR0=0;
e=0;
f=0;
P2=0XFC;
P0=0X3F;
void main()
// delayms(1);
TMOD=0x01;
ET0=1;
EA=1;
TH0=0X3C;
TL0=0XB0;
TR0=1;
while(1)
keyscan();
display();
void timer0() interrupt 1 using 0
uchar count;
count++;
if(count==20)
count=0;
data1[1]--;
if(data1[1]==-1)
data1[1]=9;
data1[0]--;
else
TH0=0X3C;
TL0=0XB0;
void keyscan()
uchar num;
// uchar m,n;
if(a==0)
delayms(10);
if(a==0)
TR0=0;
num++;
while(a==0);
if(num==1)
if(b==0)
delayms(5);
if(b==0)
while(!b);
data1[1]++;
if(data1[1]==10)
data1[1]=0;
data1[0]++;
if(data1[0]==6)
data1[0]=1;
if(c==0)
delayms(10);
if(c==0)
while(!c);
data1[1]--;
if(data1[1]==255)
data1[1]=9;
data1[0]--;
if(d==0)
TR0=1;
num=0;
当每次按下按键时,左侧数码管都会抖动一次,如何改程序能克服抖动,电路图如下,如果必要的话可以改电路图
0到59秒的倒计时,当倒计时到0时,点亮二极管
数码管按键定时器的应用
利用 8051 单片机设计秒表,包括 3 个按键、3 位数码管。按键分别用于启动、暂停、
显示学号,时间用数码管显示。开始后显示学号后 3 位。按启动键下后,显示 0.00 以 0.01
秒的频率从 0.00 递增,期间按暂停键时暂停,再次按暂停继续递增,当递增到 9.99 以后循
环。按显示学号键,显示学号。
1、仿真电路:
2、程序设计:
(1)目录结构:
(2)主函数:
#include <reg52.h> #include<display.c> #include<key.c> unsigned int cp; void display(void); void key(void); /*Timer0中断服务函数*/ void timer0_isr(void) interrupt 1 { TH0=(65535-2000)/256; //重装初值 TL0=(65535-2000)%256; //重装初值 cp++; //2000代表2ms,1000ms=1s if(mode == 2)cp=0;//按下暂停按键后,mode为2 else{ if(cp>=5) //0.01s到了 { cp=0; xiaoshu++; } if(xiaoshu>=100) //1s到了 { xiaoshu=0; sec++; //秒+1 flash=~flash; } if(sec>=10) sec=0; //10S到了 } P0=0xff; display(); //调用display函数 } /*******timer0初始化函数********/ void timer0_init(void) { TMOD=0x01; //T0工作方式1 TH0=(65535-2000)/256; //对机器脉冲计数2000个积满溢出引发中断 TL0=(65535-2000)%256; EA=1; //开总中断 ET0=1; //开T0中断 TR0=1; //启动定时器 } /******主函数********/ void main() { timer0_init(); //调用timer0_init 中断函数 while(1) { key(); //调用按键函数 } }
(3)显示函数:
不同的mode值对应不同的显示(学号OR秒显示)
#include <reg52.h> unsigned char i,j,xuehao = 113,xiaoshu = 0,sec = 0,flash,mode; unsigned char code seven_seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void display(void) { if(mode == 0)//mode初始化默认为零,显示学号 { switch(i) { case 0:P0 = seven_seg[xuehao%10];P1 = 0x04;break;//个位 case 1:P0 = seven_seg[xuehao/10%10];P1 = 0x02;break;//十位 case 2:P0 = seven_seg[xuehao/100];P1 = 0x01;break;//百 } i++; if(i>=3)i = 0; } if(mode == 1) { switch(j) { case 0:P0 = seven_seg[xiaoshu%10];P1 = 0x04;break; case 1:P0 = seven_seg[xiaoshu/10];P1 = 0x02;break; case 2:P0 = seven_seg[sec]&(0x7F | flash);P1 = 0x01;break; } j++; if(j>=3)j = 0; } if(mode == 2) { switch(j) { case 0:P0 = seven_seg[xiaoshu%10];P1 = 0x04;break; case 1:P0 = seven_seg[xiaoshu/10];P1 = 0x02;break; case 2:P0 = seven_seg[sec]&(0x7F | flash);P1 = 0x01;break; } j++; if(j>=3)j = 0; } }
(4)按键:
按键的主要作用是使mode得知改变,通过修改mode的值,使display执行相应的显示函数
#include <reg52.h> sbit key1 = P2^3; //启动 sbit key2 = P2^4;//暂停 sbit key3 = P2^5;//显示学号 unsigned char mode; void delay(unsigned int x)//delay函数实现短暂的延时(不精确,通过程序的执行次数累积出延时的时间) { while(x--); } void key(void)//采用按键按下有效的方式 { if(key1 == 0) //启动键(如果按键按下) { delay(400); //消抖 if(key1 == 0)//消抖后,如果确定按键真的按下了 { mode=1; } while(key1 == 0);//再按,不起作用,一直执行while } if(key2 == 0) //暂停键 { delay(400); //消抖 if(key2 == 0) { mode = 2; } while(key2 == 0);//再按,不起作用 } if(key3 == 0) //显示学号 { delay(400); //消抖 if(key3 == 0) { mode = 0; } while(key3 == 0);//再按,不起作用 } }
以上是关于用51单片机设计了一个简单的倒计时器,但数码管有点小问题,请教高手的主要内容,如果未能解决你的问题,请参考以下文章
利用51单片机,4个数码管设计一个计时器,要求在数码管上显示的数据从0开始每1秒钟加1。
怎样用51单片机实现累加计时和倒计时,并用六个共阴极数码管显示出来。用两个按键分别切换。
单片机STC15定时器(1)中断,数码管自动加1的电子钟,为啥不自动加1