ice_kkk 2024-01-06 22:57 采纳率: 100%
浏览 16
已结题

关于51单片机 数字时钟的的代码需要注释解析

#关于数字时钟51单片机的问题,在社区里看到的文章 有人能帮我解释一下每一行的意思吗,两个部分的代码拼接起来的可能有些是没定义c
c语言


```c

#include<reg52.h>
sbit k1 = p3^3;//控制开关终止与开始
sbit k2 = P3^0;//控制模式
sbit k3 = P3^1;//控制加
sbit k4 = P3^2;//控制减
sbit LED = P1^7;
unsigned char kz1,kz2,kz3,kz4,kz5,w,k,nz,h;
unsigned char ss = 2, sg = 3, fs = 5, fg = 9, ms = 5, mg = 5;
char SMG[12] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00} ;
char are[] = {0Xfe,0Xfd,0Xfb,0Xf7,0Xef,0Xdf,0Xbf,0X7f};
void zhongduan();
void keykongzhi();
void naoshizhong();
void LedDriver();
void delay_us(unsigned int i)
 //蜂鸣器的延时函数其参数为us(10000)=0.12s 
 /*250hz的周期1/250 所以一个高电平1/500 要发出250hz 需要us(166.667)*/
{
 unsigned int k;
 for (k =0;k<i;k++);
}
while(k1==1)//这里实现每个按键按下会响
 //频率为250hz
{beep=1
 delay_us(166);
 beep=0;
 delay_us(166);
}
while(k2==1)
{beep=1
 delay_us(166);
 beep=0;
 delay_us(166);
}
while(k3==1)
{beep=1
 delay_us(166);
 beep=0;
 delay_us(166);
}
while(k4==1)
{beep=1
 delay_us(166);
 beep=0;
 delay_us(166);
}
void delay(unsigned int i)//电子表会动 能中断且设置时间
 {
 while(i--);
 }
void main()
 {
 zhongduan(); 
 while(1)
 {
 naoshizhong();
 keykongzhi();
 LedDriver();
 }
 }
void naoshizhong()
 {
 P0 = SMG[ss];P2 = are[0]; delay(500); P2 = 0Xff;
 P0 = SMG[sg];P2 = are[1]; delay(500); P2 = 0Xff; 
 P0 = SMG[10];P2 = are[2]; delay(500); P2 = 0Xff;
 P0 = SMG[fs];P2 = are[3]; delay(500); P2 = 0Xff;
 P0 = SMG[fg];P2 = are[4]; delay(500); P2 = 0Xff;
 P0 = SMG[10];P2 = are[5]; delay(500); P2 = 0Xff;
 P0 = SMG[ms];P2 = are[6]; delay(500); P2 = 0Xff;
 P0 = SMG[mg];P2 = are[7]; delay(500); P2 = 0Xff;
 
 }
void keykongzhi()
 {
 
 if(k2 == 0 && kz1 == 0)
 {
 kz1 = 1;
 }
 else if(k2 == 1 && kz1 == 1)
 {
 kz1 = 0;
 w++;
 w &= 0x03;
 } 
 
 
 if(k3 == 0 && kz2 == 0)
 {
 kz2 = 1;
 }
 else if(k3 == 1 && kz2 == 1)
 {
 kz2 = 0;
 
 switch(w)
 { 
 case 1: mg = 0; ms = 0; break;
 case 2: fg ++; break;
 case 3: sg ++; break; 
 }
 
 }
 if(k4 == 0 && kz3 == 0)
 {
 kz3 = 1;
 }
 else if(k4 == 1 && kz3 == 1)
 {
 kz3 = 0;
 
 switch(w)
 { 
 case 1: mg = 0; ms = 0; break;
 case 2: fg --; break;
 case 3: sg --; break; 
 }
 
 }
 if(w == 1 && nz == 0) //时钟调秒
 {
 P0 = SMG[ms]+128;P2 = are[6]; delay(800); P2 = 0Xff;
 P0 = SMG[mg]+128;P2 = are[7]; delay(800); P2 = 0Xff;
 }
 if(w == 2 && nz == 0) //时钟调分
 {
 P0 = SMG[fs]+128;P2 = are[3]; delay(800); P2 = 0Xff;
 P0 = SMG[fg]+128;P2 = are[4]; delay(800); P2 = 0Xff;
 }
 if(w == 3 && nz == 0) //时钟调时
 {
 P0 = SMG[ss]+128;P2 = are[0]; delay(800); P2 = 0Xff;
 P0 = SMG[sg]+128;P2 = are[1]; delay(800); P2 = 0Xff;
 }
 }
void zhongduan()
 {
 TMOD=0X01;
 TH0=0X3C;//50ms
 TL0=0XB0;
 ET0=1;
 TR0=1;
 EA=1;
 }
void LedDriver()
 {
if (k >= 40)
 {
 k = 0;
 mg ++;
 }
 
if (mg >= 10)
 {
 mg = 0;
 ms ++;
 }
 if (ms >= 6)
 {
 ms = 0;
 fg ++;
 }
 if (fg >= 10)
 { 
 fg = 0;
 fs ++;
 }
 if (fs >= 6)
 {
 fs = 0;
 sg ++;
 } 
 if (sg >= 10)
 {
 sg = 0;
 ss ++ ;
 } 
 if (ss ==2 && sg == 4)
 { 
 ss = 0;
 sg = 0;
 } 
 }
void time0() interrupt 1 using 0
 {
 TH0=0X3C;
 TL0=0XB0;
 k ++; 
 }
void key()//设置闹钟函数 以及设置闹钟
{ 
 if(k2==0)
 {
 delay(2);
 if(k2==0)
 {
 while(!k2);
 TR0=0;
 setflag=0;
 if(MODE == 3) MODE = 1;
 else MODE ++; 
 }
 } 
 if(k3==0)
 {
 delay(2);
 if(k3==0)
 {
 while(!k3);
 if(MODE == 1) H_Increase() ;
 if(MODE == 2) M_Increase() ;
 if(MODE == 3) S_Increase() ;
 if(SET_MODE==1)
 {
 set_hour++;
 if(set_hour==24)set_hour=0;
 }
 if(SET_MODE==2)
 {
 set_min++;
 if(set_min==60)set_min=0;
 } 
 
 }
 } 
 if(k4==0)
 {
 delay(2);
 if(k4==0)
 {
 while(!k4);
 if(MODE == 1) H() ;
 if(MODE == 2) M() ;
 if(MODE == 3) S() ;
 if(SET_MODE==1)
 {
 set_hour--;
 if(set_hour==0)set_hour=23;
 }
 if(SET_MODE==2)
 {
 set_min--;
 if(set_min==0)set_min=59;
 } 
 }
 }


  • 写回答

16条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-01-07 12:20
    关注

    引自免费微信小程序:皆我百晓生

    #include<reg52.h> //包含reg52.h头文件,用于定义51的一些特殊功能寄存器
    sbit k1 = p3^3; //定义变量k1,并用sbit关键字声明为单片机P3口的第3位
    sbit k2 = P3^0; //定义变量k2,并用sbit关键字声明为单片机P3口的第0位
    sbit k3 = P3^1; //定义变量k3,并用sbit关键字声明为单片机P3口的第1位
    sbit k4 = P3^2; //定义变量k4,并用sbit关键字声明为单片机P3口的第2位
    sbit LED = P1^7; //定义变量LED,并用sbit关键字声明为单片机P1口的第7位
    unsigned char kz1,kz2,kz3,kz4,kz5,w,k,nz,h; //定义一些无符号字符类型的变量
    
    unsigned char ss = 2, sg = 3, fs = 5, fg = 9, ms = 5, mg = 5; //定义一些无符号字符类型的变量,并初始化
    
    char SMG[12] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00} ; //定义一个数组SMG,用于显示数码管的数值
    char are[] = {0Xfe,0Xfd,0Xfb,0Xf7,0Xef,0Xdf,0Xbf,0X7f}; //定义一个数组are,用于控制数码管的显示位置
    
    void zhongduan(); //声明zhongduan函数
    void keykongzhi(); //声明keykongzhi函数
    void naoshizhong(); //声明naoshizhong函数
    void LedDriver(); //声明LedDriver函数
    void delay_us(unsigned int i); //声明delay_us函数
    
    void delay(unsigned int i); //声明delay函数
    
    void main() //主函数
    {
        zhongduan(); //调用中断函数
        while(1) //无限循环
        {
            naoshizhong(); //调用闹钟函数
            keykongzhi(); //调用按键控制函数
            LedDriver(); //调用LED驱动函数
        }
    }
    
    void naoshizhong() //闹钟函数
    {
        P0 = SMG[ss];P2 = are[0]; delay(500); P2 = 0Xff; //在数码管的第一个位置显示ss,并控制显示位置
        P0 = SMG[sg];P2 = are[1]; delay(500); P2 = 0Xff; //在数码管的第二个位置显示sg,并控制显示位置
        P0 = SMG[10];P2 = are[2]; delay(500); P2 = 0Xff; //在数码管的第三个位置显示10,并控制显示位置
        P0 = SMG[fs];P2 = are[3]; delay(500); P2 = 0Xff; //在数码管的第四个位置显示fs,并控制显示位置
        P0 = SMG[fg];P2 = are[4]; delay(500); P2 = 0Xff; //在数码管的第五个位置显示fg,并控制显示位置
        P0 = SMG[10];P2 = are[5]; delay(500); P2 = 0Xff; //在数码管的第六个位置显示10,并控制显示位置
        P0 = SMG[ms];P2 = are[6]; delay(500); P2 = 0Xff; //在数码管的第七个位置显示ms,并控制显示位置
        P0 = SMG[mg];P2 = are[7]; delay(500); P2 = 0Xff; //在数码管的第八个位置显示mg,并控制显示位置
    }
    
    void keykongzhi() //按键控制函数
    {
        if(k2 == 0 && kz1 == 0)
        {
            kz1 = 1;
        }
        else if(k2 == 1 && kz1 == 1)
        {
            kz1 = 0;
            w++;
            w &= 0x03;
        }
    
        if(k3 == 0 && kz2 == 0)
        {
            kz2 = 1;
        }
        else if(k3 == 1 && kz2 == 1)
        {
            kz2 = 0;
    
            switch(w)
            {
                case 1: mg = 0; ms = 0; break;
                case 2: fg ++; break;
                case 3: sg ++; break;
            }
    
        }
        if(k4 == 0 && kz3 == 0)
        {
            kz3 = 1;
        }
        else if(k4 == 1 && kz3 == 1)
        {
            kz3 = 0;
    
            switch(w)
            {
                case 1: mg = 0; ms = 0; break;
                case 2: fg --; break;
                case 3: sg --; break;
            }
    
        }
        if(w == 1 && nz == 0) //时钟调秒
        {
            P0 = SMG[ms]+128;P2 = are[6]; delay(800); P2 = 0Xff;
            P0 = SMG[mg]+128;P2 = are[7]; delay(800); P2 = 0Xff;
        }
        if(w == 2 && nz == 0) //时钟调分
        {
            P0 = SMG[fs]+128;P2 = are[3]; delay(800); P2 = 0Xff;
            P0 = SMG[fg]+128;P2 = are[4]; delay(800); P2 = 0Xff;
        }
        if(w == 3 && nz == 0) //时钟调时
        {
            P0 = SMG[ss]+128;P2 = are[0]; delay(800); P2 = 0Xff;
            P0 = SMG[sg]+128;P2 = are[1]; delay(800); P2 = 0Xff;
        }
    }
    
    void zhongduan() //中断函数
    {
        TMOD=0X01; //设置定时器0工作在模式1
        TH0=0X3C; //给定时器0的高字节赋初值0x3C
        TL0=0XB0; //给定时器0的低字节赋初值0xB0
        ET0=1; //使能定时器0的中断
        TR0=1; //启动定时器0
        EA=1; //使能总中断
    }
    
    void LedDriver() //LED驱动函数
    {
        if (k >= 40) //当k大于等于40时
        {
            k = 0;
            mg ++; //mg1
        }
    
        if (mg >= 10) //当mg大于等于10时
        {
            mg = 0;
            ms ++; //ms加1
        }
        if (ms >= 6) //当ms大于等于6时
        {
            ms = 0;
            fg ++; //fg加1
        }
        if (fg >= 10) //当fg大于等于10时
        {
            fg = 0;
            fs ++; //fs加1
        }
        if (fs >= 6) //当fs大于等于6时
        {
            fs = 0;
            sg ++; //sg加1
        }
        if (sg >= 10) //当sg大于等于10时
        {
            sg = 0;
            ss ++ ; //ss加1
        }
        if (ss ==2 && sg == 4) //当ss等于2且sg等于4时
        {
            ss = 0; //ss赋值为0
            sg = 0; //sg赋值为0
        }
    }
    
    void delay_us(unsigned int i) //给定时间的延时函数,参数为微秒
    {
        unsigned int k;
        for (k =0;k<i;k++); //执行一段时间的空循环
    }
    //蜂鸣器的延时函数,参数为微秒
    //蜂鸣器的频率为250hz,所以一个高电平1/500,要发出250hz,需要166.667微秒
    while(k1==1) //当k1为1时执行循环
    {
        beep=1; //使蜂鸣器发出声音
        delay_us(166); //延时166微秒
        beep=0; //关闭蜂鸣器
        delay_us(166); //延时166微秒
    }
    
    void delay(unsigned int i) //延时函数,参数为无符号整型数
    {
        while(i--); //执行一段时间的空循环
    }
    
    void time0() interrupt 1 using 0 //定时器中断函数,采用中断号为1的方式
    {
        TH0=0X3C; //给定时器0的高字节赋初值0x3C
        TL0=0XB0; //给定时器0的低字节赋初值0xB0
        k ++; //k加1
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(15条)

报告相同问题?

问题事件

  • 系统已结题 1月22日
  • 已采纳回答 1月14日
  • 赞助了问题酬金15元 1月7日
  • 创建了问题 1月6日