- #include <REGX52.H>
- #include <stdio.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar count=0,minute=0,second=3,flag=0,stop=0;
- uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极
- uchar disbuf[4]={0};//位选定义一个四位的数组,循环扫描显示相应的内容
- sbit buzzer=P2^0;//定义单片机的相应引脚
- sbit P11=P1^1;
- //sbit P12=P1^2;
- sbit light=P1^3;
- sbit jianfenkey=P1^4;
- uchar Jia=0, Jian=0;
- void delay_ms(uint x) //延时消抖函数
- {uint t;
- while(x--) for(t = 0; t < 120; t++);
- }
- void display()//模块化书写函数,进行相应的调用,实现模块化编程
- {
- uchar i,j;
- uchar sel;
- disbuf[0]=second%10; //disbuf[]每一个元素赋值,对秒赋值
- disbuf[1]=second/10;
- disbuf[2]=minute%10;//对分钟赋值
- disbuf[3]=minute/10;
- P2=0XFF; //P2口接数码管的位选端,选择哪个数码管工作 共阴极数码管,位选0时有效 先置FF,使为选段为高电平,数码管不工作
- sel=0x01;//定义一个扫描的位选端
- for(i=0;i<4;i++)
- {
- j=disbuf[i]; //扫描依次显示四个数码管 上面的赋值已经将disbuf数值更改,也就是1~9
- P0=table[j]; //将字形码发送到P0端口,显示位的数据
- P2=(sel^0xff); // ^异或相异为1,保证每次都有一个数码管点亮
- delay_ms(1); // 延时后,防止程序运行太快,跑飞
- P2=0XFF;
- sel=sel<<1; // 左移运算 0x01左移,1将依次在四位上循环
- }
- }
- void modify_time()//更改计时器时间的函数,修改初始定时时间
- {
- if(Jia == 1)
- {
- if(flag==0)//修改秒
- {
- second++;
- if(second==60)//秒的最大为60,然后会发生进位
- {
- second=0;
- disbuf[0]=0;
- disbuf[1]=0;
- }
- }
- else//修改分钟
- {
- minute++;
- if(minute==60)//分钟最大为60,到60以后会发生进位
- {
- minute=0;
- disbuf[2]=0;
- disbuf[3]=0;
- }
- }
- Jia=0;
- }
- else if(Jian==1)
- {
- if(flag==0)//修改秒
- {
- second--;
- if(second==0)//秒的最小为0,然后会发生借位
- {
- second=59;
- disbuf[0]=9;
- disbuf[1]=5;
- minute=minute-1;
- }
- }
- Jian=0;}
- }
- void main(void)//主函数
- {
- TMOD=0x01;//定时器T0,工作方式1,为16位定时器
- TH0=(65536-50000)/256;//高8位赋值
- TL0=(65536-50000)%256;//低8位赋值
- TR0=0;//默认情况下,定时器不工作,在外部的触发情况下,定时器,工作,开始减1运算
- ET0=1;//打开定时器T0的中断
- IT0=1;//设置外部中断0的触发方式
- EX0=1;//打开外部中断的中断
- IT1=1;//设置外部中断0触发方式
- EX1=1;//打开外部中断1中断
- EA=1;//总中断
- while(1)
- {
- if(stop==1)//当计时倒计时完成以后,屏幕闪烁显示
- {
- while(1)
- {
- P2=~P2;
- delay_ms(150);
- }
- }
- else
- display();//调用显示函数,依次减一
- if(!P11)//判断更改时间按键是否按键 进行相应的消抖
- {
- while(!P11)
- delay_ms(10);
- Jia=1;
- if(P11)
- {
-
- modify_time();
- }//调用调日期时间的函数
- }
- if(!jianfenkey)//判断更改时间按键是否按键 进行相应的消抖
- {
- while(!jianfenkey)
- delay_ms(10);
- Jian = 1;
- if(jianfenkey)
- {
- modify_time();}//调用调时间的函数
- }
- }
- }
- void inter1() interrupt 1//定时器T0的中断
- {
- count++;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- if(count==20)//50ms 20次即为1s
- {
- count=0;
- second--;
- if(second==0)//该处的程序结构应该仔细看下
- {
- if(minute!=0)//防止minute最后为0的时候,还执行minute--,使程序出错。
- {
- minute--;
- second=60;
- second--;
- if(second==0)
- {
- if(minute==0)
- {
- second=0;
- minute=0;
- TR0=0;
- count=0;
- buzzer=0;
- light=0;
- stop=1;
- }
- }
- }
- else
- {
- second=0;
- minute=0;
- TR0=0;
- count=0;
- buzzer=0;
- light=0;
- stop=1;
- }
- }
- }
- }
-
- void inter0() interrupt 0//外部中断0
- {
- flag=~flag;//flag参数的作用,是修改定时时间的时,确定是分钟位还是小时位。
-
- }
- void inter2() interrupt 2//外部中断1
- {
- TR0=~TR0;//按键3,奇数次按下,定时器开始工作,偶数次关闭。
- }
复制代码 |