可调时钟仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include "reg52.h"
- typedef unsigned char u8; // 定义无符号8位类型
- typedef unsigned short int u16; // 定义无符号16位类型
- typedef unsigned long int u32; // 定义无符号32位类型
- sbit Button1 = P1^0; // 模式按钮
- sbit Button2 = P1^1; // 加号按钮
- sbit Button3 = P1^2; // 减号按钮
- u8 DisBuf[8] = { 12,30,17,30,00,17,00,00 }; // 数码管初始值无显示
- u8 Hour=12,Min=30,Sec=0;
- u32 seconds = 0;
- /********************************************************************
- * 函数功能 :延时函数
- * 入口参数 :None
- * 出口参数 : Time:延时时间
- * 其他描述
- ********************************************************************/
- void Delay_us( u16 Time )
- {
- while( Time-- );
- }
- /********************************************************************
- * 函数功能 :数码管驱动
- * 入口参数 :None
- * 出口参数 : 按键识别码
- * 其他描述
- ********************************************************************/
- void Seg_Drive( void )
- {
- // 共阳极数码管的数码表
- u8 code codebuf[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xbf,0xff};
- u8 i = 0;
- for( i=0;i<8;i++ ) // 有8个为共阴极数码管
- {
- P3 = 0xff; // 关闭显示,消除鬼影
- P3 = ~(1<<i); // 输出片选
- P2 = ~codebuf[DisBuf[i]]; // 根据缓冲区显示数据且数码管显示数字2015.09.15
- Delay_us( 200 ); // 200 us的时间
- }
- }
- /********************************************************************
- * 函数功能 :数据拆分
- * 入口参数 :None
- * 出口参数 : Num:两位数据
- * 其他描述
- ********************************************************************/
- void SegDisp( u8 hour,u8 min,u8 sec )
- {
- DisBuf[0] = hour/10; //
- DisBuf[1] = hour%10; //
- DisBuf[3] = min/10; //
- DisBuf[4] = min%10; //
- DisBuf[6] = sec/10; //
- DisBuf[7] = sec%10; //
- }
-
- /********************************************************************
- * 函数功能 :ScanKey
- * 入口参数 :None
- * 出口参数 : 按键识别码
- * 其他描述 矩阵按键的扫描
- ********************************************************************/
- u8 ScanKey( void )
- {
- if( 0 == Button1 ) return 'M'; // 返回对数据执行的模式M
- if( 0 == Button2 ) return '+'; // 返回对数据执行的加数+
- if( 0 == Button3 ) return '-'; // 返回对数据执行的减数-
- return 0;
- }
- /********************************************************************
- * 函数功能 :按键判断、消除抖动、松手检测
- * 入口参数 :None
- * 出口参数 : 按键识别码
- * 其他描述 :
- ********************************************************************/
- u8 ReadKey( void )
- {
- u8 tmp;
- tmp = ScanKey(); // 读取按键值
- if( 0 == tmp ) return 0; // 判断是否有按键按下
- if( tmp!=ScanKey() ) return 0; // 读回来的值是否与原来相同
- while( 0 != ScanKey() ); // 读回来的按键为0,也就是说是松手检测
- return tmp; // 返回键值
- }
- /********************************************************************
- * 函数功能 :定时器初始化
- * 入口参数 :None
- * 出口参数 : None
- * 其他描述 :
- ********************************************************************/
- void time_init( void )
- {
- TMOD = 0x01; // 设置定时T0器工作方式1
- EA = 1; // 开启T0总中断
- TR0 = 1; // 启动T0定时器
- ET0 = 1; // 开启计数/定时器T0中断
- }
- /********************************************************************
- * 函数功能 :用户程序入口
- * 入口参数 :None
- * 出口参数 : None
- * 其他描述 :
- ********************************************************************/
- void main( void )
- {
- u8 Num = 0;
- static u8 Mode = 0;
-
- time_init(); // 定时器初始化
- while( 1 )
- {
- switch( ReadKey() )
- {
- // 三种模式:时、分、秒
- case 'M': Mode = (Mode+1)%4; break;
- // 时钟调整 增操作
- case '+':
- if( 1 == Mode ) // 小时调整
- {
- Hour = (Hour+1)%24; // 一天 24 小时
- }
- else if ( 2== Mode )
- {
- Min = (Min+1)%60; // 一小时60 分钟
- }
- else if ( 3== Mode )
- {
- Sec = (Sec+1)%60; // 一分钟 60 秒
- }
- break;
-
- // 时钟调整 减操作
- case '-':
- if( 1 == Mode ) // 小时调整
- {
- Hour == 0 ? Hour =23 : Hour--; // 一天 24 小时
- }
- else if ( 2== Mode )
- {
- Min == 0 ? Min =59 : Min--; // 一小时60 分钟
- }
- else if ( 3== Mode )
- {
- Sec == 0 ? Sec =59 : Sec--; // 一分钟 60 秒
- }
- break;
- }
-
- SegDisp(Hour,Min,Sec); // 数码管数据拆分
- Seg_Drive(); // 数码管驱动
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
Chap6_3(可调时钟).rar
(72.38 KB, 下载次数: 26)
|