目录
一、Keil新建项目
1. 项目创建
打开keil
点击project
项目名称可以自己起,不用加后缀,路径放到自己找得到的地方。
搜索AT89C51------>点击OK
点击是
点击
新建.c文件(如果用c语言编程的话)
2. 用前调试
点击(管它叫锤子)
我一般用12MHz
选OUTPUT,勾上,选OK
3. 软件部分代码
#include<reg51.h>
#define uChar unsigned char
#define uInt unsigned int
uChar a[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uChar b[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uChar second=50,minute=59,hour=16,year=22,month=12,day=25,count;
sbit Key1 = P3^0; //减一
sbit Key2 = P3^1; //调位
sbit Key3 = P3^2; //加一
sbit Key4 = P3^3; //切换
sbit Buzzer=P1^1;
/*********************延迟函数********************/
void Delay(uInt t)
{
while(t)
{
t--;
}
}
/*********************时分秒显示函数*******************/
void Dispaly1(uChar second,uChar minute,uChar hour)
{
/*********************第一位数码管*********************/
P2=b[0];
P0=a[hour/10];
Delay(10);
/*********************第二位数码管*********************/
P2=b[1];
P0=a[hour%10];
Delay(10);
/*********************第三位数码管*********************/
P2=b[2];
P0=0x40;
Delay(10);
/*********************第四位数码管*********************/
P2=b[3];
P0=a[minute/10];
Delay(10);
/*********************第五位数码管*********************/
P2=b[4];
P0=a[minute%10];
Delay(10);
/*********************第六位数码管*********************/
P2=b[5];
P0=0x40;
Delay(10);
/*********************第七位数码管*********************/
P2=b[6];
P0=a[second/10];
Delay(10);
/*********************第八位数码管*********************/
P2=b[7];;
P0=a[second%10];
Delay(10);
}
/*********************年月日显示函数********************/
void Dispaly2(uChar year,uChar month,uChar day)
{
P2=b[0];
P0=a[year/10];
Delay(10);
P2=b[1];
P0=a[year%10];
Delay(10);
P2=b[2];
P0=0x40;
Delay(10);
P2=b[3];
P0=a[month/10];
Delay(10);
P2=b[4];
P0=a[month%10];
Delay(10);
P2=b[5];
P0=0x40;
Delay(10);
P2=b[6];
P0=a[day/10];
Delay(10);
P2=b[7];
P0=a[day%10];
Delay(10);
}
/*********************时钟按键扫描函数*********************/
void Keyscan1()
{
static uChar i=0,j=0;
/*时钟数值加一减一功能*/
if(Key2==0)
{
Delay(10);
if(Key2==0)
while(!Key2);
i++;
j++;
}
// 加加
if(j%4==1)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
second++;
if(second==60)// 如果满60秒,分钟加一,秒钟清零,下边逻辑相同
{
second=00;
minute++;
}
}
}
if(j%4==2)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
minute++;
if(minute==60)
{
minute=00;
hour++;
}
}
}
if(j%4==3)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
hour++;
if(hour==24)
{
hour=00;
day++;
}
}
}
// 减减
if(i%4==1)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
second--;
if(second==0)
{
second=60;
minute--;
}
}
}
if(i%4==2)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
minute--;
if(minute==0)
{
minute=0;
hour--;
}
}
}
if(i%4==3)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
hour--;
if(hour==0)
{
hour=0;
day--;
}
}
}
}
/*日期按键扫描函数*/
void Keyscan2()
{
static uChar n=0,m=0;
/*日期加一减一功能*/
if(Key2==0)
{
Delay(10);
if(Key2==0)
while(!Key2);
n++;
m++;
}
// 加加
if(n%4==1)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
day++;
if(day==30)
{
day=0;
month++;
}
}
}
if(n%4==2)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
month++;
if(month==12)
{
month=1;
year++;
}
}
}
if(n%4==3)
{
if(Key3==0)
{
Delay(10);
if(Key3==0)
while(!Key3);
year++;
if(year==99)
year=0;
}
}
// 减减
if(m%4==1)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
day--;
if(day==0)
{
day=30;
month--;
}
}
}
if(m%4==2)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
month--;
if(month==0)
{
month=12;
year--;
}
}
}
if(m%4==3)
{
if(Key1==0)
{
Delay(10);
if(Key1==0)
while(!Key1);
year--;
if(year==0)
year=1;
}
}
}
/***************主函数***************************/
void main()
{
TMOD=0x01; /*定时器以方式一工作*/
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;/*10ms计时*/
EA=1;
ET0=1;/*允许定时器0中断*/
TR0=1;/*打开定时器0*/
while(1)
{
static uChar h=0;
/*时钟和日期切换功能*/
if(Key4==0)
{
Delay(10);
if(Key4==0)
while(!Key4);
h++;
}
if(h%2==0)/*如果按键偶数次则显示时钟*/
{
Dispaly1(second,minute,hour);
Keyscan1();
}
if(h%2==1)/*如果按键奇数次则显示日期*/
{
Dispaly2(year,month,day);
Keyscan2();
}
}
}
/**********************中断函数**************************/
void time0_int(void) interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
count++;
if(count==100)
{
count=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
day++;
if(day==30)
{
day=0;
month++;
if(month==12)
{
month=0;
year++;
if(year==99)
{
year=0;
}
}
}
}
}
}
}
/*判断整点提醒*/
if(second==00&&minute==00)
Buzzer=1;
else
Buzzer=0;
}
4. 最后
点击
二、Protues创建
1. 新建项目
一路next到finish
2. 硬件电路图
三、仿真结果
双击单片机,找到.hex后缀的文件(在keil生成的Object文件夹下)
记得同样的晶振频率12MHz
点击确定
仿真结果
按键4控制日期、时间的切换,按键2负责选位,按键1 进行减操作,按键3进行加操作
显示时间
显示日期
调整时间
调整日期
四、几个小疑问
1. 怎么计1秒钟
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;/*10ms计时*/
定时器工作原理:
如果你选的单片机的晶振一定,比如12MHZ来说吧,机器周期是1us,就是说每1us产生一次计数,就拿50ms来说,这是你想要的计时,意思是,对机器周期进行50000计数就可以得到我想要的,可T0是一个可以对机器周期能进行65536次计数,也就是说我想要的50MS不能让T0溢出,怎么办,那么先给这个定时器里面放些数,放多少,就是我们想要的50MS在加上一个多少就能等于65536,也就是65536和50000的差值,这个值就是我们说的初值。
为什么除以256,因为我们的计时器是两个8位组成的,那么要把那些差值装进这两个8位,那么低8位最多能装256个机器周期,那么256计满了就用高8位的,就是说低8位满一次高8位加1,那么高8位装多少,低8位就满了几次,算法就是用差值除一下256取其整数,剩下的,就是还剩了小于256次数的就放在低8位,就是差值的余数。如果我要放一个超过256的数,肯定是超过先放高八位,把剩下的部分放在低八位中了,TH0=(65536-50000)/256就是把T0中放不下的部分放在TL0中,再把剩下的部分放在TH0中。
void timer(0) interrupt 1
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
flag++;
if(flag==20)//当定时到1秒时执行花括号里面的语句
{}
}