Altium Designer画的8位共阳数码管显示51单片机时钟原理图和PCB图如下:(51hei附件中可下载工程文件)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar sec,min,hour;//定义时、分、秒变量
- uchar counter10ms0,counter10ms1; //定义T0和T1的10ms计数变量
- uchar counter05s0;//定义0.5秒变量
- uchar KeyCounter; //定义保存功能按键计数值变量
- uchar OldKey; //定义保存按键状态变量
- bit AddFlag,SubbFlag;//定义加、减按键标志
- bit FlashFlag; //定义闪烁标志
- sbit LED1=P1^0;
- sbit LED2=P1^1;
- sbit LED3=P1^2;
- sbit LED4=P1^3;
- uchar Disbuff[8]={0,0,10,0,0,10,0,0};//定义数码管显示缓冲区单元
- uchar code DisCode[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //共阳数码管段码,0~9及“-”“熄灭”字符的字型码
- sbit LED=P3^4; //工作指示灯
- /****************************************
- * 延时函数Delaynms(uint dly) *
- * 延时时间 dly x 1ms 12MHz *
- ****************************************/
- void Delaynms(uint dly)
- {
- uchar i;
- while(dly--)
- for(i=0;i<123;i++);
- }
- /***************************************/
- /****************************************
- * 显示函数Display() *
- * 功能:根据将8个数码管显示一遍 *
- ****************************************/
- void Display(void)
- {
- uchar i,n=0x01;
- for(i=0;i<8;i++)
- {
- P0=DisCode[Disbuff[i]]; //送段码
- P2=~n; //开位选
- Delaynms(1); //延时
- n=n<<1; //位选移位
- P0=0xff; //段码低电平全灭
- P2=0xff; //经过非门后变成高电平,使得位选关闭
- }
- }
- /****************************************/
- /****************************************
- * BIN码变换成BCD码函数TimeDataBin2Bcd() *
- * 功能:将时、分、秒分离出十位和个位 *
- ****************************************/
- void TimeDataBin2Bcd()
- {
- Disbuff[0]=hour/10;//分离小时十位
- Disbuff[1]=hour%10;//分离小时个位
- Disbuff[3]=min/10;//分离分钟十位
- Disbuff[4]=min%10;//分离分钟个位
- Disbuff[6]=sec/10;//分离秒十位
- Disbuff[7]=sec%10;//分离秒个位
- }
- /***************************************/
- /****************************************
- * 读入按键函数ReadKey() *
- * 功能:若有按键按下,返回按键值 *
- * 若没有按键按下,返回255 *
- ****************************************/
- uchar ReadKey()
- {
- uchar Key;
- Key=P3&0xe0; //读入按键值 P3&1110 0000
- if(Key!=0xe0)
- { //若有键按下
-
- Delaynms(10);
- Key=P3&0xe0; //重新读入按键值
- if(Key!=0xe0)
- { //若有键按下
- if((Key!=0xe0)&&(OldKey==0xe0)) //判断是否下降沿
- {
- OldKey=Key; //保存本次按键值
- return(Key); //返回按键值
- }
- }
- }
- OldKey=Key; //无键按下,保存本次按键值,返回255
- return(255); //不能够删,否则出错
- }
- /***************************************/
- /****************************************
- * 按键分析函数KeyAnalysis(uchar Key) *
- * 功能:对功能键计数 *
- * 对加、减键设标志 *
- ****************************************/
- void KeyAnalysis(uchar Key)
- {
- if(Key!=255)
- { //有键按下
- switch(Key)
- {
- case 0x60: KeyCounter++; //功能键按下 0110 0000 因为85行Key=P3&0xe0; //重新读入按键值
- if(KeyCounter==3)KeyCounter=0;
- break;
- case 0xa0: if(KeyCounter!=0)AddFlag=1;break; //+键按下 1010 0000
- case 0xc0: if(KeyCounter!=0)SubbFlag=1;break; //-键按下 1100 0000
- }
- }
- }
- /***************************************/
- /****************************************
- * 时间调整函数AdjTime() *
- * 功能:对分钟、小时加、减设置 *
- * *
- ****************************************/
- void AdjTime()
- {
- if(KeyCounter==1)
- { //设置分钟
- if(AddFlag)
- { //分钟+设置
- AddFlag=0; //标志位要清零 ,否则影响下次按键判断
- min++;
- if(min==60)min=0;
- }
- if(SubbFlag)
- { //分钟-设置
- SubbFlag=0; //标志位要清零 ,否则影响下次按键判断
- min--;
- if(min==255)min=59; //分钟减到0的时候,unsigned char型的变量回到255
- }
- }
- if(KeyCounter==2)
- { //设置小时
- if(AddFlag)
- { //小时+设置
- AddFlag=0;
- hour++;
- if(hour==24)hour=0;
- }
- if(SubbFlag)
- { //小时-设置
- SubbFlag=0;
- hour--;
- if(hour==255)hour=23;
- }
- }
- }
- /***************************************/
- /****************************************
- * 闪烁控制函数FlashControl() *
- * 功能:对调整的分钟、小时进行熄灭设置 *
- * *
- ****************************************/
- void FlashControl()
- {
- if(FlashFlag)
- {
- if(KeyCounter==1)
- {
- Disbuff[3]=11; //DisCode[11]=0x00,数码管灭
- Disbuff[4]=11;
- }
- if(KeyCounter==2)
- {
- Disbuff[0]=11;
- Disbuff[1]=11;
- }
- }
- }
- /******************************?????*********/
- /*void LEDFLASH(void)
- {
- LED1=~LED1;
- LED2=~LED2;
- LED3=~LED3;
- LED4=~LED4;
-
- }
- */
- void main(void)
- {
- uchar Key;
- P1=0XF0; //时分间隔的两个LED灯亮
- TMOD=0x11; //定时器0,1都设置为工作方式一
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- TH1=(65536-10000)/256;
- TL1=(65536-10000)%256;
- ET0=1;ET1=1; //开定时器0,1的中断
- EA=1; //开总中断
- while(1)
- {
- Key=ReadKey(); //读取按键,检测按键是否按下
- KeyAnalysis(Key); //判断哪个按键按下
- if(KeyCounter==0) //假如没有按下功能键
- { TR0=1; //启动定时器0,秒计数
- TR1=0;
- TimeDataBin2Bcd(); //分离变量以便后面数码管的显示
- }
- else
- {
- TR0=0; //关闭定时器0,
- TR1=1; //启动定时器1
- AdjTime(); //调整时间
- TimeDataBin2Bcd(); //分离变量以便后面数码管的显示
- FlashControl(); //对调整的分钟、小时进行熄灭数码管设置
- }
- Display(); //显示数码管
- }
- }
- void Timer0(void) interrupt 1
- {
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- counter10ms0++;
-
- if(counter10ms0==50)
- {
- counter10ms0=0;
- counter05s0++;
- LED=0; //LED=P3^4; //工作指示灯亮
- if(counter05s0==2) //1s到来
- {
- counter05s0=0;
- sec++;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
电子时钟资料全.zip
(2.56 MB, 下载次数: 181)
|