自己做的小时钟--没用时钟芯片。。。 注: 时钟精度取决于晶振精度(这是用单片机产生时钟的) 功能详见资料和源程序。。。。 本人是新手,请别介意
长按P2.5的按键,进入下一项调整;
在正常显示状态下,短按2.2的按键进行亮度调整;
在调时状态下,短按2.2的按键进行加1调整;
在闹钟鸣响状态下,轻触单片机的3.3进行关闭闹钟;程序下载:http://www.51hei.com/bbs/dpj-186560-1.html
单片机源程序如下:
- /*********************************************************************************************
- 程序名: 数码管时钟 ZJW48
- 编写人: 张晋玮
- 编写时间: 2020年5月2日
- 硬件支持: 一定要用型号为4563BS的数码管,否则可能无法正常显示
- 接口说明: 无
- /*********************************************************************************************
- 说明:先要把STC12C5608AD的头文件复制到Keil/C51/INC里
- (如果有的话就不用)
- /*********************************************************************************************/
- #include <STC12C5630AD.H>
- /**********************************************************************************************/
- //-------程序调试设置项-------
- #define LI 5 //设置LED显示的亮度(值域:1~9)
- #define DELAY 9 //设置每一个点显示的时间长度(1~20)
- /**********************************************************************************************/
- sbit LED_H1 =P2 ^ 0; //设置LED数码管连接的I/O口
- sbit LED_H2 =P3 ^ 7; //设置LED数码管连接的I/O口
- sbit LED_H3 =P2 ^ 7; //设置LED数码管连接的I/O口
- sbit LED_H4 =P2 ^ 6; //设置LED数码管连接的I/O口
- sbit LED_L1 =P1 ^ 7; //设置LED数码管连接的I/O口
- sbit LED_L2 =P1 ^ 0; //设置LED数码管连接的I/O口
- sbit LED_L3 =P1 ^ 3; //设置LED数码管连接的I/O口
- sbit LED_L4 =P1 ^ 5; //设置LED数码管连接的I/O口
- sbit LED_L5 =P1 ^ 6; //设置LED数码管连接的I/O口
- sbit LED_L6 =P1 ^ 1; //设置LED数码管连接的I/O口
- sbit LED_L7 =P1 ^ 2; //设置LED数码管连接的I/O口
- sbit LED_L8 =P1 ^ 4; //设置LED数码管连接的I/O口
- sbit BEEP = P2 ^ 4; //扬声器
- sbit KEY1 = P2 ^ 5; //按键1(M键)
- sbit KEY2 = P2 ^ 2; //按键2(+键)
- sbit KEY3 = P3 ^ 3; //按键3(关蜂鸣器键)
- #define P3M0SET 0x08 //设置I/O口工作方式//00001000(左到右,高到低位)
- #define P3M1SET 0x80 //设置I/O口工作方式//10000000
- #define P1M0SET 0x00 //设置I/O口工作方式//00000000
- #define P1M1SET 0x00 //设置I/O口工作方式//00000000
- #define P2M0SET 0x00 //设置I/O口工作方式//00000000
- #define P2M1SET 0xc1 //设置I/O口工作方式//11000001
- unsigned char TIME_FH,TIME_FM,TIME_HH,TIME_MM,TIME_SS=0;
- unsigned char cou = 0; // 软计数器,对50ms时基信号累加到1s
- unsigned char PWM; //显示亮度
- unsigned char MENU=0; //菜单值
- bit r=1; //秒点闪烁标志位
- unsigned char code disdata[]={
- 0x3f,0x06,0x5b,0x4f,0x66,
- 0x6d,0x7d,0x07,0x7f,0x6f //无小数点数码管段码表(0~9)
- };
- /*********************************************************************************************/
- void delay (unsigned int a){ // 用于点扫描的延时
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < DELAY; i++);
- }
- }
- /*********************************************************************************************/
- void MCU_YS (unsigned int a){
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < 600; i++);
- }
- }
- /*********************************************************************************************/
- void dis_off (void){
- P3 = ~P3M1SET; //关所有显示
- P1 = ~P1M1SET;
- P2 = ~P2M1SET;
- delay(10-PWM);
- }
- /*********************************************************************************************/
- void displayHH1 (unsigned char d){ //第1列横向显示程序
- unsigned char i;
- i = d & 0x01;
- if(i == 0x01){
- LED_H1 = 1;LED_L1 = 0;}delay(PWM);dis_off();
- i = d & 0x02;
- if(i == 0x02){
- LED_H1 = 1;LED_L2 = 0;}delay(PWM);dis_off();
- i = d & 0x04;
- if(i == 0x04){
- LED_H1 = 1;LED_L3 = 0;}delay(PWM);dis_off();
- i = d & 0x08;
- if(i == 0x08){
- LED_H1 = 1;LED_L4 = 0;}delay(PWM);dis_off();
- i = d & 0x10;
- if(i == 0x10){
- LED_H1 = 1;LED_L5 = 0;}delay(PWM);dis_off();
- i = d & 0x20;
- if(i == 0x20){
- LED_H1 = 1;LED_L6 = 0;}delay(PWM);dis_off();
- i = d & 0x40;
- if(i == 0x40){
- LED_H1 = 1;LED_L7 = 0;}delay(PWM);dis_off();
- i = d & 0x80;
- if(i == 0x80){
- LED_H1 = 1;LED_L8 = 0;}delay(PWM);dis_off();
- }
- /*********************************************************************************************/
- void displayHH2 (unsigned char d){ //第2列横向显示程序
- unsigned char i;
- i = d & 0x01;
- if(i == 0x01){
- LED_H2 = 1;LED_L1 = 0;}delay(PWM);dis_off();
- i = d & 0x02;
- if(i == 0x02){
- LED_H2 = 1;LED_L2 = 0;}delay(PWM);dis_off();
- i = d & 0x04;
- if(i == 0x04){
- LED_H2 = 1;LED_L3 = 0;}delay(PWM);dis_off();
- i = d & 0x08;
- if(i == 0x08){
- LED_H2 = 1;LED_L4 = 0;}delay(PWM);dis_off();
- i = d & 0x10;
- if(i == 0x10){
- LED_H2 = 1;LED_L5 = 0;}delay(PWM);dis_off();
- i = d & 0x20;
- if(i == 0x20){
- LED_H2 = 1;LED_L6 = 0;}delay(PWM);dis_off();
- i = d & 0x40;
- if(i == 0x40){
- LED_H2 = 1;LED_L7 = 0;}delay(PWM);dis_off();
- i = d & 0x80;
- if(i == 0x80){
- LED_H2 = 1;LED_L8 = 0;}delay(PWM);dis_off();
- }
- /*********************************************************************************************/
- void displayHH3 (unsigned char d){ //第3列横向显示程序
- unsigned char i;
- i = d & 0x01;
- if(i == 0x01){
- LED_H3 = 1;LED_L1 = 0;}delay(PWM);dis_off();
- i = d & 0x02;
- if(i == 0x02){
- LED_H3 = 1;LED_L2 = 0;}delay(PWM);dis_off();
- i = d & 0x04;
- if(i == 0x04){
- LED_H3 = 1;LED_L3 = 0;}delay(PWM);dis_off();
- i = d & 0x08;
- if(i == 0x08){
- LED_H3 = 1;LED_L4 = 0;}delay(PWM);dis_off();
- i = d & 0x10;
- if(i == 0x10){
- LED_H3 = 1;LED_L5 = 0;}delay(PWM);dis_off();
- i = d & 0x20;
- if(i == 0x20){
- LED_H3 = 1;LED_L6 = 0;}delay(PWM);dis_off();
- i = d & 0x40;
- if(i == 0x40){
- LED_H3 = 1;LED_L7 = 0;}delay(PWM);dis_off();
- i = d & 0x80;
- if(i == 0x80){
- LED_H3 = 1;LED_L8 = 0;}delay(PWM);dis_off();
- }
- /*********************************************************************************************/
- void displayHH4 (unsigned char d){ //第4列横向显示程序
- unsigned char i;
- i = d & 0x01;
- if(i == 0x01){
- LED_H4 = 1;LED_L1 = 0;}delay(PWM);dis_off();
- i = d & 0x02;
- if(i == 0x02){
- LED_H4 = 1;LED_L2 = 0;}delay(PWM);dis_off();
- i = d & 0x04;
- if(i == 0x04){
- LED_H4 = 1;LED_L3 = 0;}delay(PWM);dis_off();
- i = d & 0x08;
- if(i == 0x08){
- LED_H4 = 1;LED_L4 = 0;}delay(PWM);dis_off();
- i = d & 0x10;
- if(i == 0x10){
- LED_H4 = 1;LED_L5 = 0;}delay(PWM);dis_off();
- i = d & 0x20;
- if(i == 0x20){
- LED_H4 = 1;LED_L6 = 0;}delay(PWM);dis_off();
- i = d & 0x40;
- if(i == 0x40){
- LED_H4 = 1;LED_L7 = 0;}delay(PWM);dis_off();
- i = d & 0x80;
- if(i == 0x80){
- LED_H4 = 1;LED_L8 = 0;}delay(PWM);dis_off();
- }
- /*********************************************************************************************/
- void diplay_data (unsigned char l,unsigned char d){
- switch (l){ //显示的列位置
- case 1: displayHH1(d); break; //将显示数据送入
- case 2: displayHH2(d); break; //将显示数据送入
- case 3: displayHH3(d); break; //将显示数据送入
- case 4: displayHH4(d); break; //将显示数据送入
- }
- }
- /*********************************************************************************************/
- void init (void){ //上电初始化
- P3M0 = P3M0SET;
- P3M1 = P3M1SET;
- P1M0 = P1M0SET;
- P1M1 = P1M1SET;
- P2M0 = P2M0SET;
- P2M1 = P2M1SET;
- ////
- BEEP=1;
- dis_off();
- PWM = LI;
- ////
- AUXR &= 0x7F; //定时器时钟12T模式
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01; //设置定时器模式
- EA = 1; // 开总中断
- TH0 = 0x3C; //设置定时初值
- TL0 = 0xB0; //设置定时初值
- ET0 = 1; // 定时/计数器0允许中断
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ////
- //TIME_HH = 19; //初始时间:19时13分40秒
- //TIME_MM = 13;
- //TIME_SS = 40;
- }
- /*********************************************************************************************/
- void main (void){ //主程序
- init(); //初始化
- while (1){
- switch (MENU){
- case 0:
- TR0 = 1; //定时器0开始计时
- if(r){
- diplay_data (1,disdata[TIME_HH/10]);
- diplay_data (2,disdata[TIME_HH%10]+0x80);
- diplay_data (3,disdata[TIME_MM/10]);
- diplay_data (4,disdata[TIME_MM%10]);
- }else{
- diplay_data (1,disdata[TIME_HH/10]);
- diplay_data (2,disdata[TIME_HH%10]);
- diplay_data (3,disdata[TIME_MM/10]);
- diplay_data (4,disdata[TIME_MM%10]);
- }
- if(KEY1==0){MCU_YS(2000);if(KEY1==0){MENU++;}}
- if(KEY2==0){MCU_YS(85);if(KEY2==0){PWM++;if(PWM>=10){PWM=1;}}}
- break;/// MENU为0时 (正常显示状态)
- case 1:
- BEEP=1;
- TR0 = 0; //关闭定时器0
- diplay_data (1,disdata[TIME_HH/10]);
- diplay_data (2,disdata[TIME_HH%10]+0x80);
- if(KEY1==0){MCU_YS(2000);if(KEY1==0){MENU++;}}
- if(KEY2==0){MCU_YS(85);if(KEY2==0){TIME_HH++;if(TIME_HH>=24){TIME_HH=0;}}}
- break; /// MENU为1时 (小时调整)
- case 2:
- TR0 = 0; //关闭定时器0
- BEEP=1;
- diplay_data (2,0x80);
- diplay_data (3,disdata[TIME_MM/10]);
- diplay_data (4,disdata[TIME_MM%10]);
- if(KEY1==0){MCU_YS(2000);if(KEY1==0){MENU++;}}
- if(KEY2==0){MCU_YS(85); if(KEY2==0){TIME_MM++;if(TIME_MM>=60){TIME_MM=0;}}}
- break; /// MENU为2时 (分钟调整)
-
- case 3:
- BEEP=1;
- TR0 = 0; //关闭定时器0
- diplay_data (1,disdata[TIME_FH/10]);
- diplay_data (2,disdata[TIME_FH%10]+0x80);
- if(KEY1==0){MCU_YS(2000);if(KEY1==0){MENU++;}}
- if(KEY2==0){MCU_YS(85);if(KEY2==0){TIME_FH++;if(TIME_FH>=24){TIME_FH=0;}}}
- break; /// MENU为3时 (闹钟小时调整)
- case 4:
- TR0 = 0; //关闭定时器0
- BEEP=1;
- diplay_data (2,0x80);
- diplay_data (3,disdata[TIME_FM/10]);
- diplay_data (4,disdata[TIME_FM%10]);
- if(KEY1==0){MCU_YS(2000);if(KEY1==0){MENU=0;}}
- if(KEY2==0){MCU_YS(85);if(KEY2==0){TIME_FM++;if(TIME_FM>=60){TIME_FM=0;}}}
- break; /// MENU为4时 (闹钟分钟调整)
- }
- if(TIME_FH+TIME_FM!=0){if(TIME_HH==TIME_FH){if(TIME_MM==TIME_FM){BEEP=0;if(KEY3==1){TIME_FM=0;TIME_FH=0;}}}}
- } //while
- } //main
- /**********************************************************************************************/
- void tiem0(void) interrupt 1{ // T/C0中断服务程序(产生50ms时基信号)
- cou++; // 软计数器加1
- if(cou >= 20){ // 计数值到100(1s)
- cou = 0; // 软计数器清零
- TIME_SS++; // 秒计数器加1(进位50ms*20=1s)
- r=~r; // 秒点闪烁
- if(TIME_SS >= 60){ // 秒计数值到60
- TIME_SS = 0; // 秒计数器清零
- TIME_MM++; // 分计数器加1(进位60s=1m)
- if(TIME_MM >= 60){ // 分计数到60
- TIME_MM = 0; // 分计数器清零
- TIME_HH++; // 时计数器加1(进位60m=1h)
- if(TIME_HH >= 24){ // 时计数到23
- TIME_HH = 0; // 时计数器清零
- }
- }
- }
- }
- TH0 = 0x3C; //设置定时初值
- TL0 = 0xB0; //设置定时初值
- }
- /**********************************************************************************************/
复制代码
|