51单片机数码管显示程序

#include <reg51.h>
sbit dula=P2^6;
sbit wela=P2^7;
sbit P34=P3^4;
  char Tab [10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Dat[4]={0xf7,0xfb,0xfd,0xfe};
    unsigned char Second=0;
unsigned long i,c=0;

void main()
{        
        char t;
    char b[2];
TMOD=0x01;        
    TR0=1;            
    TH0=(65536-46080)/256;
    TL0=(65536-46080)%256;
    ET0=1;                            //允许T0中断
    EA=1;                       //允许所有中断


    
   while(1)
    {


  
 
    b[3]=c/1000;     //千
  b[2]=c/100%10;    //百
 b[1]=c/10%10;     //十
  b[0]=c%10;       //个
for(t=0;t<2;t++){ //t是多少个数码管显示
    
        P0=Tab[b[t]];
dula=1;dula=0;
    
    P0=Dat[t];
    wela=1;wela=0;
for(i=0;i<2;i++);
    P0=0xFF;    
    
}}}


/*定时器0中断服务子程序*/

void time0() interrupt 1
{
    
    TH0= (65536-46080)/256;
    TL0= (65536-46080)%256;
        i++;
    if(i==1){
        i=0;
    c++;
    if(c>=20) c=0;        //计数到20秒自动回0
    }
}


        

    

这段代码是一个基于单片机的数字时钟,具体实现了以下功能:

  1. 通过四个共阳数码管显示当前时刻,每秒更新一次;
  2. 使用定时器0作为计时器,每隔50ms产生一次中断,从而实现秒表计时功能;
  3. 将计时结果(单位为秒)以“xx.xx”形式显示在第一个数码管上,最多可以计时20秒。

下面是对这段代码的详细分析:

首先,在 main 函数中,定义了一些变量,包括:

  • Tab:数字 0~9 在数码管上的显示码表;
  • Dat:数码管控制位模式表;
  • Second:用于存储当前时间的秒数,初始值为 0;
  • i:用于计时的计数器,初始值为 0;
  • c:用于秒表计时的计数器,初始值为 0。

接着,在 main 函数中,初始化定时器0,并开启 T0 中断和全局中断使能。

随后进入主循环,其中先通过将计数值 c 格式化为四个数字,存储在数组 b 中。循环遍历数组 b,依次将每个数字通过选择相应的码表值和数码管控制位模式,发送给数码管进行显示。

在 T0 中断服务子程序 time0 中,首先重新加载定时器初值,然后每隔一定周期执行一次计时操作:将计数值 i 加 1,如果 i 达到指定阈值(50ms),则将当前秒表计数值 c 加 1,并判断是否超过20秒,如果超过则将其清零。

需要注意的是,此代码仅仅是一个简单的实现,还存在一些问题。例如,由于使用了延时函数,这会影响程序的实时性。而且,由于只在主循环中更新时钟显示,如果程序在处理其他任务时比较繁忙,则可能导致时钟显示出现明显的卡顿或错误。因此,在实际应用中需要对代码进行进一步的优化和改进。

根据提供的引用内容,我们可以使用定时器来实现51单片机数码管秒表的功能。具体步骤如下: 1. 首先需要设置定时器的工作模式和计数值,以控制秒表的计时精度和时间范围。可以使用定时器的模式1或模式3,计数值为65536-定时器初值。 2. 在定时器中断服务函数中,每次计时完成后,将计时器清零,并将计时器的值转换为数码管可以显示的格式,例如BCD码或十进制数。 3. 将转换后的计时器值通过数码管进行显示。 4. 可以通过按键来控制秒表的启动、停止、复位等功能。 下面是一个简单的51单片机数码管秒表的代码示例,其中使用定时器0的模式1进行计时,计时精度为1ms,使用4位共阳数码管进行显示: ```c #include <reg52.h> #define uint unsigned int #define uchar unsigned char sbit D1 = P2^0; // 数码管位选引脚 sbit D2 = P2^1; sbit D3 = P2^2; sbit D4 = P2^3; sbit S1 = P3^0; // 按键引脚 sbit S2 = P3^1; sbit S3 = P3^2; uint cnt = 0; // 计时器计数值 uchar flag = 0; // 秒表状态标志,0表示停止,1表示计时中 void init_timer0() // 初始化定时器0 { TMOD &= 0xF0; // 设置定时器0为模式1 TH0 = 0xFC; // 设置定时器初值,计数器从65536-TH0开始计数,1ms中断一次 TL0 = 0x67; ET0 = 1; // 允许定时器0中断 EA = 1; // 允许总中断 TR0 = 1; // 启动定时器0 } void display(uint num) // 数码管显示函数 { uchar code table[] = { // 数码管段码表 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F }; uchar digit[4]; // 存储转换后的数码管显示值 digit[0] = num % 10; digit[1] = num / 10 % 10; digit[2] = num / 100 % 10; digit[3] = num / 1000 % 10; D1 = 1; P0 = table[digit[0]]; D1 = 0; // 显示个位 D2 = 1; P0 = table[digit[1]]; D2 = 0; // 显示十位 D3 = 1; P0 = table[digit[2]]; D3 = 0; // 显示百位 D4 = 1; P0 = table[digit[3]]; D4 = 0; // 显示千位 } void main() { init_timer0(); // 初始化定时器0 while (1) { if (!S1) { // 按下S1启动/停止秒表 flag = !flag; while (!S1); // 等待按键释放 } if (!S2) { // 按下S2复位秒表 cnt = 0; flag = 0; display(cnt); while (!S2); // 等待按键释放 } if (flag) { // 秒表计时中 display(cnt); } } } void timer0_isr() interrupt 1 // 定时器0中断服务函数 { TH0 = 0xFC; // 重新设置定时器初值 TL0 = 0x67; cnt++; // 计数器加1 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值