51单片机8位7段数码管时钟
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg52.h>
- #include"intrins.h"
- #define uint unsigned int
- #define uchar unsigned char
- sbit fmq=P3^0; //蜂鸣器控制
- char table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, 0xff, 0xc6, 0xc7, 0x88,}; //共阳极数码管编码 “0-9”
- // 0 1 2 3 4 5 6 7 8 9 不显示 C L A
- uchar val[8]={0,0,0,0,0,0,11,12}; //数码管显示缓冲区
- uint count=0; //
- char shi=0,fen=0,miao=0; //时分秒变量
- char nzshi=0,nzfen=0,nzmiao=0; //闹钟时分秒变量
- uchar wei=0x01,duan=0; // 控制数码管段 和位显示的变量
- void led() //数码管扫描函数
- {
- P0=0Xff;
- P2=wei;
- if((duan==1)||(duan==3)) //这里是加小数点用的
- {
- P0=(table[val[duan]]&0x7f);
- }
- else
- {
- P0=table[val[duan]];
- }
-
- duan++;
- if(duan>7)
- duan=0;
- wei=_crol_(wei,1);
- }
- void time0init() //定时器0初始化
- {
- TMOD=0X01;
- TH0=(65536-2000)/256;
- TL0=(65536-2000)%256;
- ET0=1;
- TR0=1;
- EA=1;
- }
- uchar keytime=0; //按键
- uint bjtime=0; //报警计时变量
- bit sjbs=0; //按键A 控制时间走停的变量
- void time0() interrupt 1 // 定时器0中断服务函数
- {
- TH0=(65536-2000)/256;
- TL0=(65536-2000)%256;
- if(sjbs)
- {
- count++;
- }
- bjtime++;
- keytime++;
- led(); //2ms扫描一次数码管显示
- }
- uchar key() //按键扫描程序
- {
- static uchar kzt=0;
- uchar sb=25;
- switch(kzt)
- {
- case 0:
- P1=0xff;
- if(P1!=0xff)
- {
- kzt=1;
- return 25;
- }
- break;
- case 1:
- P1=0xff;
- if(P1!=0xff)
- {
- switch(P1)
- {
- case 0xfe:
- sb=1;
- break;
- case 0xfd:
- sb=2;
- break;
- case 0xfb:
- sb=3;
- break;
- case 0xf7:
- sb=4;
- break;
- case 0xef:
- sb=5;
- break;
- case 0xdf:
- sb=6;
- break;
- case 0xbf:
- sb=7;
- break;
- case 0x7f:
- sb=8;
- break;
- }
- kzt=2;
- return sb;
- }
- else
- {
- kzt=0;
- return 25;
- }
- break;
- case 2:
- P1=0xff;
- if(P1==0xff)
- {
- kzt=0;
- return 25;
- }
- break;
- }
- return 25;
- }
-
- void sj() //时分秒时间更新
- {
- if(count>499)
- {
- count=0;
- miao++;
- if(miao>59)
- {
- miao=0;
- fen++;
- if(fen>59)
- {
- fen=0;
- shi++;
- if(shi>23)
- {
- shi=0;
- }
- }
- }
-
- }
-
- }
- void main()
- {
- uchar keycode=25,zt=1;
- bit bjbs=0;
- fmq=1;
- time0init(); //初始化定时器0
- while(1)
- {
- if(keytime>9) //20ms 扫描一次按键
- {
- keytime=0;
- keycode=key();
- }
-
- if(((fen==0)&&(miao==0))||((shi==nzshi)&&(fen==nzfen)&&(miao==nzmiao)))
- { // 判断整点 判断是否到闹钟时间
- bjbs=1;
- fmq=0;
- bjtime=0;
- }
-
-
- if(bjbs) //报警处理
- {
- if(bjtime>30000)
- {
- fmq=1;
- bjbs=0;
- }
- if((keycode>1)&&(keycode<5)) //只要在鸣叫时调节就停止鸣叫
- {
- bjbs=0;
- fmq=1;
- }
- }
-
-
-
- switch(zt)
- {
- case 1: // 时钟显示
-
- val[0]=shi/10; //显示数据更新
- val[1]=shi%10;
-
- val[2]=fen/10;
- val[3]=fen%10;
-
- val[4]=miao/10;
- val[5]=miao%10;
-
- val[6]=11;
- val[7]=12;
-
- if(keycode==1) //A 时间运行与暂停
- {
- sjbs=!sjbs;
- keycode=25;
- }
- sj();
-
- if(keycode==2) //B 秒加1
- {
- miao++;
- if(miao>59)
- {
- miao=0;
- }
- keycode=25;
- }
-
- if(keycode==3)//C分 加1
- {
- fen++;
- if(fen>59)
- {
- fen=0;
- }
- keycode=25;
- }
-
- if(keycode==4)//D 时加1
- {
- shi++;
- if(shi>23)
- {
- shi=0;
- }
- keycode=25;
- }
-
- if(keycode==5) //E 进入闹钟设置状态
- {
- zt=2;
- keycode=25;
- }
-
- break;
-
-
- case 2: //闹钟显示与调节
-
- sj(); //时间更新
- val[0]=nzshi/10; //显示数据更新
- val[1]=nzshi%10;
-
- val[2]=nzfen/10;
- val[3]=nzfen%10;
-
- val[4]=nzmiao/10;
- val[5]=nzmiao%10;
-
- val[6]=13;
- val[7]=12;
- if(keycode==2) //B 闹钟秒加1
- {
- nzmiao++;
- if(nzmiao>59)
- {
- nzmiao=0;
- }
- keycode=25;
- }
-
- if(keycode==3) //C 闹钟分加1
- {
- nzfen++;
- if(nzfen>59)
- {
- nzfen=0;
- }
- keycode=25;
- }
-
- if(keycode==4) //D 闹钟时加1
- {
- nzshi++;
- if(nzshi>23)
- {
- nzshi=0;
- }
- keycode=25;
- }
-
- if(keycode==5) //E 进入时钟显示状态
- {
- zt=1;
- keycode=25;
- }
- break;
-
- }
-
- }
- }
复制代码
所有资料51hei提供下载:
时钟.rar
(87.8 KB, 下载次数: 44)
|