仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
原理: 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。led数码管由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只需引出它们的各个笔划,公共电极。LED数码管以发光二极管作为发光单元,颜色有单红, 黄,蓝,绿,白,黄绿等效果。单色,分段全彩管可用大楼,道路,河堤轮廓亮化,LED数码管可均匀排布形成大面积显示区域,可显示图案及文字,并可播放不同格式的视频文件。
(仅写所用到的主要原理,不要介绍单片机本身的特点)
(4) 电路原理图
(5) 所用主要元器件清单
序号 名称 规格型号 数量 备注
1 MCU STC89C51 1
2 晶振 11.0592MHz 1
3 数码管 2位共阴数码管 3
4 芯片 74HC595 2
5 按键 6*6*5 4
6 上拉电阻 10k 1
7 复位电路 10uf 1
8 电阻 5.1k 1
9 电阻 100 1
10 蜂鸣器 Buz 1
(6) 软件框图
单片机源程序如下:
- #include<reg51.h> //包含51单片机头文件
- #define uchar unsigned char//把unsigned char 定义为uchar
- #define uint unsigned int//把unsigned int定义为uint
- /*定义外部按键接口*/
- sbit K1=P3^3; //调整
- sbit K2=P3^0; //确定
- sbit K3=P3^2; //加
- sbit K4=P3^1; //减
- sbit BUZZ=P1^7; //蜂鸣器
- uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xf7,0XAF,0XFF}; //共阳数码管编码
- uchar Show_table[6];//定义显示数组
- uchar temp_time=0,time_1s=0,time_1m=0,time_1h=0;//定义中间时间变量
- int hour_shi=0,hour_ge=0,mine_shi=0,mine_ge=0;//定义时间变量
- uchar w = 0;
- uchar mode=0;
- uchar zhengdian_flag=0; //整点报时标志
- uchar flash_time=0;
- bit flash_flag=0;
- uchar key_num=0;
- /*定时器0初始化*/
- void Time0_init()
- {
- TMOD |= 0x01; //使用模式1,16位定时器
- TH0 = (65536-50000)/256; //定时器装入初始值50ms
- TL0 = (65536-50000)%256;//装入定时器低八位计数值
- EA = 1; //总中断
- ET0 = 1;//定时器0初始化
- TR0 = 1;//打开定时器
-
- }
- void Delay_ms(uint i)//1ms延时
- {
- uchar x,j;//定义两个无符号字符型变量
- for(j=0;j<i;j++)//循环j=0,只要j<i,j就加一直到j大于i
- for(x=0;x<=148;x++);//循环x=0,只x<=0,x就减一直到x大于148
- }
- /*独立按键程序*/
- void KeyRead()
- {
- static uchar key_up=1;//按键松开标志
- if(key_up&&(K1==0||K2==0||K3==0||K4==0))
- {
- Delay_ms(2);//去除抖动
- key_up=0;
- if(K1==0)key_num=1;
- else if(K2==0)key_num=2;
- else if(K3==0)key_num= 3;
- else if(K4==0)key_num= 4;
-
- }else if(K1==1&&K2==1&&K3==1&&K4==1)// 无按键按下
- {
- key_up=1;
- key_num= 0;
- }
- else
- {key_num= 0;}
- }
- void display(void)//数码管显示程序
- {
- static uchar step=0;
- P0 = 0xff; //关闭数码管显示
- switch(step++) //依次传送数据
- {
- case 0:P2=0x01;P0 = table[Show_table[0]];
- break;
- case 1:P2=0x02;P0 = table[Show_table[1]];
- break;
- case 2:P2=0x04;P0 = table[Show_table[2]];
- break;
- case 3:P2=0x08;P0 = table[Show_table[3]];
- break;
- case 4:P2=0x10;P0 = table[Show_table[4]];
- break;
- case 5:P2=0x20;P0 = table[Show_table[5]];
- break;
- }
- if(step>5)step=0; //一共6位数码管 ,超过了就从0 开始
- }
- //*************************************
- //主函数
- ///***********************************
- void main(void)
- {
- Time0_init(); //初始化定时器
- while(1)
- {
- KeyRead();//读取按键值
- switch(key_num)
- {
- case 1: //调整按键
- mode++;
- if(mode>4)mode=1;
- break;
- case 2: //确定按键
- mode=0;
- break;
- case 3: //增加按键
- if(mode==1)
- {
- hour_shi++;
- if(hour_shi>2)hour_shi=0;
- }
- else if(mode==2)
- {
- hour_ge++;
- if(hour_shi<2)
- {
- if(hour_ge>9)hour_ge=0;
- }
- else
- {
- if(hour_ge>3)hour_ge=0;
- }
- }
- else if(mode==3)
- {
- mine_shi++;
- if(mine_shi>5)mine_shi=0;
- }
- else if(mode==4)
- {
- mine_ge++;
- if(mine_ge>9)mine_ge=0;
- }
- break;
- case 4: //减少按键
- if(mode==1)
- {
- hour_shi--;
- if(hour_shi<0)hour_shi=2;
- }
- else if(mode==2)
- {
- hour_ge--;
- if(hour_shi<2)
- {
- if(hour_ge<0)hour_ge=9;
- }
- else
- {
- if(hour_ge<0)hour_ge=3;
- }
- }
- else if(mode==3)
- {
- mine_shi--;
- if(mine_shi<0)mine_shi=5;
- }
- else if(mode==4)
- {
- mine_ge--;
- if(mine_ge<0)mine_ge=9;
- }
- break;
- }
- if(mode==0)//正常显示模式
- {
- Show_table[0]=hour_shi;
- Show_table[1]=hour_ge;
- Show_table[2]=mine_shi;
- Show_table[3]=mine_ge;
- hour_shi=time_1h/10;
- hour_ge=time_1h%10;
- mine_shi=time_1m/10;
- mine_ge=time_1m%10;
- }
- else//设定模式
- {
- if(flash_flag)//首先亮,这里其实就是利用程序循环3000次来达到延时的效果
- {
- if(mode==1)
- {
- Show_table[3]=mine_ge;
- Show_table[mode-1]=hour_shi;
- }
- else if(mode==2)
- {
- Show_table[0]=hour_shi;
- Show_table[mode-1]=hour_ge;
- }
- else if(mode==3)
- {
- Show_table[1]=hour_ge;
- Show_table[mode-1]=mine_shi;
- }
- else if(mode==4)
- {
- Show_table[2]=mine_shi;
- Show_table[mode-1]=mine_ge;
- }
- }
- else//然后熄灭,这样就闪烁了, 这里其实就是利用程序循环6000次来达到延时的效果
- {
- Show_table[mode-1]=18; //查数码管表
- }
- time_1h=hour_shi*10+hour_ge;
- time_1m=mine_shi*10+mine_ge;
- }
-
- Show_table[4]=time_1s/10;
- Show_table[5]=time_1s%10;
- display();//显示时间数据
- }
- }
- //定时器0中断
- void time0(void)interrupt 1
- {
- static uchar temp_3s=0;
- if(mode==0)
- {
- flash_time=0;
- temp_time++;
- if(temp_time>=20)//1s=20*50ms
- {
- temp_time=0;
- time_1s++;
- if(time_1s>=60)
- {
- time_1s=0;
- time_1m++;
- if(time_1m>=60)
- {
- time_1m=0;
- time_1h++;
- BUZZ=0; //打开蜂鸣器
- zhengdian_flag=1;
- if(time_1h>=23)
- {
- time_1h=0;
- }
- }
- }
- }
- }
- flash_time++;
- if(flash_time>2)
- {
- flash_flag=~flash_flag;
- flash_time=0;
- }
- if(zhengdian_flag)
- {
- temp_3s++;
- if(temp_3s>=60)//3000MS=50*60
- {
- zhengdian_flag=0;
- temp_3s=0;
- BUZZ=1;//3S后蜂鸣器关闭
- }
- }
- else
- {
- temp_3s=0;
- }
- TH0=(65536-50000)/256;//重新装入计数器初值高八位
- TL0=(65536-50000)%256;//重新装入计数器初值低八位
- }
复制代码 Keil代码与Proteus仿真下载:
5-数码管时钟.zip
(249.22 KB, 下载次数: 70)
|