软件(Keil uVision4 + Proteus 8 Professional + stc-isp-15xx-v6.85p)
图标
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
“万年历”设计任务书
功能简述
数码管以3秒的间隔交替显示日期和时间,并且时间可以修改。
系统硬件部分主要由单片机最小系统、数码管显示、按键模块、LED显示等模块组成。系统组成框图如图 1 所示:
图 1 系统组成框图
|
设计任务及要求
一、显示界面
1. 当前日期界面
把考试当日的年、月、日数据显示在数码管上,当前日期(以2023年1月12日为例)界面如图 2 所示
图 2 日期显示图
|
|
2. 当前时间显示界面
把从当前时间的时、分、秒数据显示在数码管上,当前日期(以9时31分30秒为例)界面如图 3 所示:
图 2 时间显示图
|
3、设置时间
设置界面分小时设置界面和分钟设置界面,小时设置界面如图4所示,分钟设置界面如图5所示。
图 3 修改小时图
|
图 4 小时设置界面
|
图 3 修改分钟图
|
|
二、整分
LED
显示模块
当时间达到整分时,8个LED灯以0.2秒的间隔时间向左流水2次。
三、按键设置模块
按键模块采用矩阵按键,系统初始时,当前日期、时间每隔3秒轮流显示,当系统显示当前温度界面时,按S2、S3无效,当第1次按下S1时,系统显示设置小时界面,此时按S2,小时增1,按S3小时减1,当第2次按下S1时,系统显示设置分钟界面,此时按S2,分钟增1,按S3分钟减1,当第3次按下S1时,系统回到当前日期、时间显示界面。按键流程如图6所示。
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
led.c
#include<reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "SEG.h"
#include "key.h"
/*
1.数码管显示
display_dat, seg_fresh P0:s1-s8 P2:a-e
2.字符解析显示码值
char_to_code,display_code,
3.定时器
初始化,函数声明 ,写中断函数
4.3s交替显示日期、时间
变量计数,
5.流水灯
变量计数,P1:灯,x=0xfe,0.2s ,fun_led() ,调用
6.按键
P3,key_scan(), flag_mode, key_old , key_new
*/
//sbit LED1=0X90;
//变量区
bit change_mode=0;//日期、时间切换
bit is_min=0;//流水标志
bit is_200ms=0;
char led_count=0;//0-16
char led_x=0xfe;
//key 变量
unsigned char flag_mode=0,key_new,key_old=0;
//函数声明
void TR0_init();
void seg_pro();
void fun_led();
void key_pro();
unsigned char display_dat[8]={0XC6,0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82}; //c0-6
unsigned char display_show[10] ;
char hour=12,minute=59,second=57,month=4,day=18;
int year=2023;
void main()
{
unsigned int i;
unsigned char key_new,key_old=0;
sprintf(display_show,"%02d-%02d-%02d",(int)hour,(int)minute,(int)second);
char_to_code(display_show,display_dat);
SEG_Fresh(display_dat);
TR0_init();
while(1)
{
key_pro(); //按键
seg_pro(); //数码管
fun_led(); //led
}
}
void TR0_init()
{
TMOD=0X01;
TH0=0X3C; TL0=0XB0; TR0=1;
EA=1;ET0=1;
}
void seg_pro()
{
if(flag_mode==0)
{
if(!change_mode)
{
sprintf(display_show,"%02d-%02d-%02d",(int)hour,(int)minute,(int)second);
char_to_code(display_show,display_dat);
SEG_Fresh(display_dat);
}else
{
sprintf(display_show,"%4d%02d%02d",(int)year,(int)month,(int)day);
char_to_code(display_show,display_dat);
SEG_Fresh(display_dat);
}
}else if(flag_mode==1)
{
sprintf(display_show,"E1 %02d",(int)hour);
char_to_code(display_show,display_dat);
SEG_Fresh(display_dat);
}else if(flag_mode==2)
{
sprintf(display_show,"E2 %02d",(int)minute);
char_to_code(display_show,display_dat);
SEG_Fresh(display_dat);
}
}
void fun_led()
{
if(is_200ms) //0.2s
{
is_200ms=0;
if(is_min) //整分
{
P1=led_x;
led_x=_crol_(led_x,1);
if(++led_count==17)
{
led_count=0;
P1=0xff;
is_min=0;
}
}
}
}
void key_pro()
{
key_new=key_can();
switch(key_new ^ key_old & key_new)
{
case 1:
if(++flag_mode==3)
flag_mode=0;
break;
case 2:
if(flag_mode==1)
{
if(++hour==24) hour=0;
}else if(flag_mode==2)
{
if(++minute==60) minute=0;
}
break;
case 3:
if(flag_mode==1)
{
if(--hour==-1) hour=23;
}else if(flag_mode==2)
{
if(--minute==-1) minute=59;
}
break;
}
key_old=key_new;
}
void timer0( ) interrupt 1
{
static unsigned char i=0,j=0,times=0;
TH0=0X3C; TL0=0XB0;
if(++times==20) //1s
{
times=0;
if(++second==60)
{
second=0;
//is_min
if(++minute==60)
{
minute=0;
if(++hour==24)
{
hour=0;
}
}
}
}
if(++i==60)
{
i=0;//3s
change_mode=~change_mode;
}
if(second==0)//整分
{
is_min=1;
}
if(++j==4) //是0.2s
{
j=0;
is_200ms=1;
}
}
seg.c(数码管刷新函数+字符转数码管显示码函数)
#include<reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "SEG.h"
unsigned char code display_code[]={'E',0x86,'C',0XC6,'0',0xC0,'1',0xF9,'2',0xA4,'3',0xB0,'4',0x99,'5',0x92,'6',0x82,'7',0xF8,'8',0x80,'9',0x90,'-',0xbf,' ',0xff};
void SEG_Fresh(unsigned char *p)
{
static char i=0,x=0xfe;
P2=0xff;
P0=x;
P2=p[i];
x=_crol_(x,1);
i++;
if(i==8) i=0;
}
void char_to_code(unsigned char *p,unsigned char *q)
{
static unsigned char i,j,k;
for(i=0,k=0;i<8;i++,k++)
{
for(j=0;j<14;j++)
{
if(p[i]==display_code[2*j])
{
q[k]=display_code[2*j+1];
break;
}
}
}
}
key.c(按键扫描函数)
#include<reg51.h>
#include <intrins.h>
unsigned char key_can()
{
static char i=0,x=0xfe;
for(i=0;i<4;i++)
{
P3=x;
if(P3!=x)
{
switch(P3)
{
case 0x7e: return 1;
case 0x7d: return 2;
case 0x7b: return 3;
}
}
x=_crol_(x,1);
}
return 0x00;
}
2023.4.18