使用芯片STC89C52RC, 2个锁存器
6个带小数点共阴极数码管显示一个24时制时钟
没有时钟芯片,所以掉电后时间会复位
原理图为TX-1C开发板
暂时显示了半小时,一秒不差,
未验证有无其他bug,代码贴上来,欢迎高手指点
==============================
最终显示的<时.分.秒>是 16.31.37 形式
#include <reg52.h> #include "MY51.H" void show(); uint8 shi=15; //初始时间15:45:00 按复位按钮对时 uint8 fen=45; uint8 miao=0; void main() { startT0(1000); //开始定时器 while(1) { show(); } } void show() //显示时钟 { uint8 oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela; //oneWela是最左边的数码管 sixWela =miao%10; fiveWela=miao/10; foreWela=fen%10; threeWela=fen/10; twoWela=shi%10; oneWela=shi/10; displaySMG(oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela,0xf5); //0xf5小数点位置 } void T0_Work() //T0定时器调用的工作函数 { miao++; if(miao>59) { miao=0; fen++; } if(fen>59) { fen=0; shi++; } if(shi>23) { shi=0; } }
#ifndef _MY51_H_ #define _MY51_H_ #include <math.h> #include <intrins.h> typedef int int16 ; typedef int INT16 ; typedef unsigned int uint16 ; typedef unsigned int UINT16 ; typedef unsigned short uint ; typedef unsigned short UINT ; typedef unsigned short word ; typedef unsigned short WORD ; typedef unsigned long uint32 ; typedef unsigned long UINT32 ; typedef unsigned long DWORD ; typedef unsigned long dword ; typedef signed long int32 ; typedef signed long INT32 ; typedef float float32 ; typedef double double64 ; typedef signed char int8 ; typedef signed char INT8 ; typedef unsigned char byte ; typedef unsigned char BYTE ; //WINDOWS的windef.h里面是这么定义的 typedef unsigned char uchar ; typedef unsigned char UCHAR ; typedef unsigned char UINT8 ; typedef unsigned char uint8 ; typedef unsigned char BOOL ; //windows中定义BOOL为int typedef unsigned char bool ; //bool是c++的内置类型 #define TRUE 1 #define true 1 #define FALSE 0 #define false 0 #define open 1 //open和close用于 标志打开和关闭状态 #define OPEN 1 #define close 0 #define CLOSE 0 #define lock 0 #define start 1 #define START 1 #define stop 0 #define STOP 0 uint8 dulaIndex=0; //数码管0~F段编码索引号 uint8 welaIndex=0; //0~5位的数码管位索引号 sbit dula =P2^6; //段选锁存器控制 控制笔段 sbit wela =P2^7; //位选锁存器控制 控制位置 #define led P1 //灯总线控制 sbit led0=P1^0; //8个led灯 sbit led1=P1^1; sbit led2=P1^2; sbit led3=P1^3; sbit led4=P1^4; sbit led5=P1^5; sbit led6=P1^6; sbit led7=P1^7; sbit keyS2=P3^4; //4个独立按键 sbit keyS3=P3^5; sbit keyS4=P3^6; sbit keyS5=P3^7; void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot); void delayms(uint16 ms); void T0_Work(); ////////////////////////////////////////////////////////////////////////// void delayms(uint16 ms) //软延时函数 { uint16 i,j; for(i=83;i>0;i--) { for(j=ms;j>0;j--) {} } } /////////////////////////////////////////////////////////////////////////// #define dark 0x11 //也就是索引第17号元素0x00,共阴极数码管正极全部输入低电平 uint8 code table[]= { //0~F外加小数点和空输出的数码管编码 0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3 0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7 0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B 0x39 , 0x5e , 0x79 , 0x71 , // C D E F 0x80 , 0x00 // . 空 空时是第0x11号也就是第17号元素 }; ///////////////////////////////////////////////////////////////////////////// uint8 TH0Cout=0 ; //初值 uint8 TL0Cout=0 ; uint16 T0IntCout=0; //中断计数 uint16 T0IntCountAll=0; //(N-1)/65536+1; //总中断次数 bool bT0Delay=false; //使用延时函数标志,初始未用 bool bT0Over=false; //中断处理函数执行结果之一 void startT0(uint32 ms) //开启定时器 { float32 t=ms/1000.0; //定时时间 double64 fox =11.0592*(pow(10,6)); //晶振频率 uint32 N=(t*fox)/12 ; //定时器总计数值 TH0Cout =(65536-N%65536)/256; //装入计时值零头计数初值 TL0Cout =(65536-N%65536)%256; T0IntCountAll=(N-1)/65536+1; //总中断次数 TMOD=TMOD | 0x01; //设置定时器0的工作方式为1 EA =open; //打开总中断 ET0=open; //打开定时器中断 TH0=TH0Cout; //定时器装入初值 TL0=TL0Cout; TR0=start; //启动定时器 } void delayT0(uint32 ms) //硬延时函数,自己乱写的不好用,求指点 { startT0(ms); //启动定时器 bT0Delay=true; //告诉T0定时器,起用延时模式 while(bT0Over==false); //时间没到的话继续检测 bT0Over=false; //时间到了,让标志复位 } void T0_times() interrupt 1 //T0定时器中断函数 { T0IntCout++; if(T0IntCout==T0IntCountAll) //达到总中断次数值 { T0IntCout=0; //中断次数清零,重新计时 bT0Over=true; //时间真的到了 if(bT0Delay) //本次中断是用来延时的吗 { TR0=stop; //如果是由延时函数开启T0的话,关闭T0 return; } TH0=TH0Cout; //循环定时的话要重装初值,每次定时1秒,重装一次 TL0=TL0Cout; T0_Work(); //工作函数 } } //////////////////////////////////////////////////////////////////////////////// void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot) { //控制6位数码管显示函数,不显示的位用参数 dark dula=1; //小数点 P0=table[16]; dula=0; P0=0xff; wela=1; P0=dot; wela=0; delayms(1); dula=1; P0=table[oneWela]; //送段数据 dula=0; P0=0xff; //送位数据前关闭所有显示,防止打开位选锁存后段选数据通过位选锁存器 wela=1; P0=0xfe; wela=0; delayms(1); dula=1; P0=table[twoWela]; dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(1); dula=1; P0=table[threeWela]; dula=0; P0=0xff; wela=1; P0=0xfb; wela=0; delayms(1); dula=1; P0=table[fourWela]; dula=0; P0=0xff; wela=1; P0=0xf7; wela=0; delayms(1); dula=1; P0=table[fiveWela]; dula=0; P0=0xff; wela=1; P0=0xef; wela=0; delayms(1); dula=1; P0=table[sixWela]; dula=0; P0=0xff; wela=1; P0=0xdf; wela=0; delayms(1); } #endif