找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1613|回复: 0
收起左侧

C51单片机日历时钟设计

[复制链接]
ID:1028857 发表于 2022-5-23 10:59 | 显示全部楼层 |阅读模式
  • #include "public.h"
  • //共阳极数码管显示编码
  • u16 code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  • //数码管显示内容
  • bit smg_show_flag = 1;
  • bit smg_show_flag1 = 1;
  • //数码管显示功能,1:数码管显示年月日,2:数码管显示时分秒,3:串口输出日期
  • u8 smg_show_mode = 1;
  • u8 time_buf[50]={0};
  • //定义年月日变量
  • u16  year = 2021;
  • u16 month = 7;
  • u16 day = 3;
  • //定义时分秒变量
  • u16 hour=3,min=12,sec,ssec;
  • //延时函数
  • void delay(u8 i)
  • {
  •    u8 k;
  •         for(k=0;k<i;k++);
  • }
  • /*********************************************************************
  •         函数名字:TIM0_IT_Init
  •         函数功能:定时器0的中断初始化函数
  • **********************************************************************/
  • void Timer0Init(void)
  • {
  •         //1.配置定时器0为工作方式1
  •         TMOD |= 0x01;
  •         //2.配置TH和TL确定定时时长,50ms
  •         //单片机时钟频率为12000000Hz,定时器时钟频率=单片机时钟频率/12=1000000Hz
  •         //50ms = 50/1000 = 1/20s,所以50ms定时器计数值为1000000/20 = 50000
  •         //由于定时器是自加计数
  •         TH0 = (65535-50000) / 256;
  •         TL0 = (65535-50000) % 256;
  •         //3.启动定时器0开始计数
  •         TR0 = 1;
  •         //4.清零定时器0的溢出标志位
  •         TF0 = 0;
  •         //5.打开定时器0中断
  •         ET0 = 1;
  •         //6.打开全局中断
  •         EA = 1;
  • }
  • //定时器1的初始化函数
  • void Timer1Init()
  • {
  •         TMOD|=0X10;
  •         TH1=0Xd8;
  •         TL1=0Xf0;
  •         ET1=1;
  •         EA=1;
  •         TR1=1;
  • }
  • /*********************************************************************
  •         函数名字:smg_display_date
  •         函数功能:数码管显示日期函数
  •         参数:显示的内容标志:1:年,0:月和日
  • **********************************************************************/
  • void smg_display_date(u8 showflag)
  • {
  •         u8 i;
  •         if(showflag == 1)
  •         {
  •                 for(i=0; i<4; i++)
  •                 {
  •                         switch(i)
  •                         {
  •                                 //进行数码管位选1,点亮第1位数码管
  •                                 case 0:        WEI1 = 0,WEI2 = 1,WEI3 = 1,WEI4 = 1;SMG_PORT = table[year/1000%10];break;
  •                                 //进行数码管位选2,点亮第2位数码管
  •                                 case 1:        WEI1 = 1;WEI2 = 0;WEI3 = 1,WEI4 = 1;SMG_PORT = table[year/100%10];break;
  •                                 //进行数码管位选3,点亮第3位数码管
  •                                 case 2:        WEI1 = 1;WEI2 = 1;WEI3 = 0,WEI4 = 1;SMG_PORT = table[year/10%10];break;
  •                                 //进行数码管位选4,点亮第4位数码管
  •                                 case 3:        WEI1 = 1;WEI2 = 1;WEI3 = 1,WEI4 = 0;SMG_PORT = table[year%10];break;
  •                         }
  •                         //点亮延时2ms
  •                 delay(2000);
  •                         //关显示
  •                         SMG_PORT = 0xff;
  •                 }
  •         }
  •         else if(showflag == 0)
  •         {
  •                 for(i=0; i<4; i++)
  •                 {
  •                         switch(i)
  •                         {
  •                                 //进行数码管位选1,点亮第1位数码管
  •                                 case 0:        WEI1 = 0,WEI2 = 1,WEI3 = 1,WEI4 = 1;SMG_PORT = table[month/10%10];break;
  •                                 //进行数码管位选2,点亮第2位数码管
  •                                 case 1:        WEI1 = 1;WEI2 = 0;WEI3 = 1,WEI4 = 1;SMG_PORT = table[month%10];break;
  •                                 //进行数码管位选3,点亮第3位数码管
  •                                 case 2:        WEI1 = 1;WEI2 = 1;WEI3 = 0,WEI4 = 1;SMG_PORT = table[day/10%10];break;
  •                                 //进行数码管位选4,点亮第4位数码管
  •                                 case 3:        WEI1 = 1;WEI2 = 1;WEI3 = 1,WEI4 = 0;SMG_PORT = table[day%10];break;
  •                         }
  •                         //点亮延时2ms
  •                         delay(2000);
  •                         //关显示
  •                         SMG_PORT = 0xff;
  •                 }
  •         }
  • }
  • void smg_display_time(u8 showflag1)
  • {
  •         u8 i;
  •         if(showflag1 == 1)
  •         {
  •                 for(i=0; i<4; i++)
  •                 {
  •                         switch(i)
  •                         {
  •                                 //进行数码管位选1,点亮第1位数码管
  •                                 case 0:        WEI1 = 0,WEI2 = 1,WEI3 = 1,WEI4 = 1;SMG_PORT = table[min/10%10];break;
  •                                 //进行数码管位选2,点亮第2位数码管
  •                                 case 1:        WEI1 = 1;WEI2 = 0;WEI3 = 1,WEI4 = 1;SMG_PORT = table[min%10];break;
  •                                 //进行数码管位选3,点亮第3位数码管
  •                                 case 2:        WEI1 = 1;WEI2 = 1;WEI3 = 0,WEI4 = 1;SMG_PORT = table[sec/10%10];break;
  •                                 //进行数码管位选4,点亮第4位数码管
  •                                 case 3:        WEI1 = 1;WEI2 = 1;WEI3 = 1,WEI4 = 0;SMG_PORT = table[sec%10];break;
  •                         }
  •                         //点亮延时2ms
  •                                 delay(2000);
  •                         //关显示
  •                         SMG_PORT = 0xff;
  •                 }
  •         }
  •         else if(showflag1 == 0)
  •         {
  •                 for(i=0; i<4; i++)
  •                 {
  •                         switch(i)
  •                         {
  •                                 //进行数码管位选1,点亮第1位数码管
  •                                 case 0:        WEI1 = 0,WEI2 = 1,WEI3 = 1,WEI4 = 1;SMG_PORT = table[hour/10%10];break;
  •                                 //进行数码管位选2,点亮第2位数码管
  •                                 case 1:        WEI1 = 1;WEI2 = 0;WEI3 = 1,WEI4 = 1;SMG_PORT = table[hour%10];break;
  •                                 //进行数码管位选3,点亮第3位数码管
  •                                 case 2:        WEI1 = 1;WEI2 = 1;WEI3 = 0,WEI4 = 1;SMG_PORT = table[min/10%10];break;
  •                                 //进行数码管位选4,点亮第4位数码管
  •                                 case 3:        WEI1 = 1;WEI2 = 1;WEI3 = 1,WEI4 = 0;SMG_PORT = table[min%10];break;
  •                         }
  •                         //点亮延时2ms
  •                         delay(2000);
  •                         //关显示
  •                         SMG_PORT = 0xff;
  •                 }
  •         }
  • }
  • /*********************************************************************
  •         函数名字:USART_Init
  •         函数功能:串口初始化函数,没有开启串口中断
  • **********************************************************************/
  • void USART_Init(void)
  • {
  •            T2MOD =0;     //自动重载
  •     T2CON = 0x30;     //T2用做发送接收时钟
  •     TH2 = 0xFF;      //9600波特率,11.0592Mhz晶振
  •     TL2 = 0xDC;
  •     RCAP2H = 0xFF;
  •     RCAP2L = 0xDC;
  •     SCON = 0x50;     //串口方式1,1个起始位,1个停止位,8位数据,可变波特率
  •     PCON = 0X00;    //波特率不加倍
  •     TR2 = 1;          //启动T2
  • //    ES = 1;         //开串口中断
  • //    EA = 1;
  • }
  • /*********************************************************************
  •         函数名字:Send_Byte
  •         函数功能:发送字符函数
  • **********************************************************************/
  • void Send_Byte(u8 da)
  • {
  •         //发送字符H
  •         SBUF = da;
  •         //等待发送完成
  •         while(TI != 1);
  •         //清空发送标志位
  •         TI = 0;
  • }
  • /*********************************************************************
  •         函数名字:Send_Str
  •         函数功能:发送封装发送字符串函数符函数
  • **********************************************************************/
  • void Send_Str(u8  *str)
  • {
  •         u8 i;
  •         for(i=0; str[ i]!='\0'; i++)
  •                 Send_Byte(str[ i]);
  • }
  • //按键函数
  • void key_san()
  • {
  •   if(KEY1==0)
  •                 {
  •                   Send_Str("        当前运行的功能为A\r\n");
  •                         delay(200);
  •                         if(KEY1==0)
  •                         {
  •                                 smg_display_date(smg_show_flag);
  •                         }
  •                 }
  •                         if(KEY2==0)
  •                 {
  •                         Send_Str("        当前运行的功能为B\r\n");
  •                                 delay(200);
  •                         if(KEY2==0)
  •                         {
  •                                 smg_display_time(smg_show_flag1);
  •                         }
  •     }
  •                 if(KEY3==0)
  •                 {
  •                         Send_Str("        当前运行的功能为C\r\n");
  •                         delay(200);
  •                         if(KEY3==0)
  •                         {
  •                         sprintf(time_buf, "当前时间为%d年%d月%d日%d时%d分%d秒\r\n",year,month,day,hour,min,sec);
  •                    Send_Str(time_buf);
  •                         }
  •     }
  • }
  • /*********************************************************************
  •         函数名字:timer0_irq
  •         函数功能:定时器0的中断服务函数
  • **********************************************************************/
  • void timer0_irq(void) interrupt 1
  • {
  •         static u8 i = 0;
  •         //循环给定时器0装入初值
  •         TH0 = (65535-50000) / 256;
  •         TL0 = (65535-50000) % 256;
  •         //让计数值自加
  •         i++;
  •         //40*50=2000ms,即2秒的延时
  •         if(i == 40)
  •         {
  •                 //清空计数值,让程序进行下一次1秒的延时
  •                 i = 0;
  •                 //每2秒钟切换数码管显示的内容
  •                 smg_show_flag=~smg_show_flag;
  •                 smg_show_flag1=~smg_show_flag1;
  •         }
  • }
  • //定时器1的中断服务函数
  • void Timer0() interrupt 3
  • {
  •                         TH1=0Xd8;
  •                         TL1=0Xf0;
  •                         ssec++;
  •                         if(ssec>=100)
  •                         {
  •                         ssec=0;
  •                         sec++;
  •                         if(sec>=60)
  •                         {
  •                         sec=0;
  •                         min++;
  •                         if(min>=60)
  •                         {
  •                         min=0;
  •                         hour++;
  •                         if(hour>=24)
  •                         {
  •                         hour=0;
  •                   }
  •                         }
  •                 }
  •         }
  • }

仿真原理图

仿真原理图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表