|
新手练习之如何设计电子时钟。这是没有加FIFO版的,把每个功能是模块化的,可以做为新手的练习。有时间可以加上FIFO,将每次按键 的键值都存放到FIFO内,将底层隔开。这样系统设计就真正意义上实现层次化,底层、界面层、和应用层。
下面是我初步的程序:
/************************************************
//文件名: main.
// 说明: 电子表时钟初始化为2012年10月13日06点00分
四个按键的定义: KEY1 S0 ; KEY2 S1 ; KEY3 S3 ; KEY4 S4 ;
演示步骤: 1. 钟表功能:
初始化主页面上显示2012年10月13日06点00分。 首先四个数码管显示06:04
(1)不对此页面进行设置。查看年月日:按KEY2表示上翻查看日期,再按KEY2上翻查看年;
类似地,按KEY3下翻查看年分显示 2012 ;
再按KEY3表示查看日期,显示 10 -13。
按KEY4跳至功能选择 .
(2)功能模式的选择。按KEY4进入此页的设置(从年开始进行设置),显示--P_
按KEY1键进行功能切换。
显示--P1 表示 钟表校对功能
显示--P2 秒表模式
显示--P3 定时模式
显示--P4 闹钟模式
按KEY4键进入该 模式功能。
*************************************************/
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
//==============变量=================================
uchar SecndCntFl g = 0 ;
uchar SecondFlag = 0; //每秒的标志位
uchar SecndLimtFl g = 0 ; //定时器
uchar Flag_10ms = 0 ;//中断中每10ms +1
uchar FlagCnt_10ms = 0 ;//秒表每10ms
uchar FlagCntOld_10ms = 0 ;
uchar SetMode = 0 ;
//================申明外部变量=======================
extern uchar dataKeyChkBuf ;
extern uchar dataKeyOldBuf ;
extern uchar dataKeyCvtBuf ;
extern DataPort ;
//=================调用函数======================
extern void Init_Key(void);
extern void MnLed(void);
extern voidTime_Process(void);
extern void Time_ProcessDisp(void );
extern void ModeSetDisp (void );
extern void Set_Time(void);
extern void Cnt_Time( void );
extern void CntTime_Disp( void );
extern voidLimt_Time(void) ;
extern voidLimtTime_Disp(void);
extern void Rin_Time(void);
/********************************e**********************************
//函 数 名: T0_Init()
//功能描述: 设置定时器
//说明: 使用定时器0,工作方式1,每10ms产生一次中断
********************************************************************/
void T0_Init(void)
{
TMOD = 0x01 ; // 设置定时器0,工作方式1
TH0 = 0xd8 ;
TL0 = 0xf0 ;
EA = 1 ;// 开总中断
ET0 = 1 ; // 开T0 中断
TR0 = 1 ;// 启动定时器 0
}
void T0_Intr(void) interrupt 1
{
Flag_10ms ++ ; //中断中每10ms +1
TH0 = 0xd8 ;
TL0 = 0xf0 ;
FlagCnt_10ms = ~ FlagCntOld_10ms ; //秒表10ms的标志
if(Flag_10ms == 100) //后期改:中断内尽量少程序
{
Flag_10ms = 0 ;
SecondFlag = ~SecondFlag;//每秒标志位置1
SecndCntFl g = ~SecndCntFl g;//每秒标志位置1
SecndLimtFl g = ~ SecndLimtFl g ;//定时器时间标志
}
}
/*************************************************************
//函 数 名: main()
//功能描述: LED动态扫描主循环
说明 :SetMode 用于模式的选择;
SetMode = 0 显示时间或者是默认时间,即进入钟表模式 (初始化值为0 );
SetMode = 1 进入钟表校对模式 ;
SetMode = 2 进入秒表模式 ;
SetMode = 3进入定时模式 ;
SetMode = 4进入闹钟模式 ;
SetMode = 5进入 模式的选择。
***********************************************************/
voidmain (void)
{
Init_Key() ;
T0_Init() ;
while(1)
{
MnLed();
Time_Process ();
switch( SetMode )
{
case 0 :
{
Time_ProcessDisp();
break ;
}
case 1 :
{
Set_Time();
break ;
}
case 2 :
{
Cnt_Time();
CntTime_Disp();
break ;
}
case 3 :
{
Limt_Time();
LimtTime_Disp();
break ;
}
case 4 :
{
Rin_Time();
break ;
}
case 5 :
{
ModeSetDisp ();
break ;
}
}
}
}
/***************************************************
//文件名称: led.c
//功能说明:数码管动态扫描4位数码管动态扫描,根据LedNum可配置为低于8位
//硬件描述:段口P1,位口P0.0-P0.3
****************************************************/
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
//=====================常量=========================================
#defineLedNum4//数码管个数6
#defineScanTime 10//扫描时间,根据实际情况调整
#defineDataPortP1//段口
#defineComPortP0//位口(4 bit) /响定时器/ 0x ef ,关闭是0xff
//=====================变量=========================================
uchardataLedDispBuff[LedNum]; //Led4Num个数码管//数点缓冲区
uchardataComPortBuf;
uchar data ScanBitCnt;
uchar data ScanTimeCnt;
extern uchardataKeyBuf[4];
//===============数码管码表(共阳极)===============================
uchardataCODE[]={ 0xc0,0xf9,0xa4,0xb0, //0-01-12-23-3
0x99,0x92,0x82,0xf8,//4-45-56-67-7
0x80,0x90,0xff,0x88,//8-89-910-空11-A
0x83,0xc6,0xa1,0x86,//12-b13-C14-D15-E
0x8e,0x8c,0xc1,0x89,//16-F17-P18-U19-H
0xc7,0xbf,0x91,0x92,//20-L21--22-y23-S
0xf7,0x8b,0xc2,0xa3//24-_25-h26-G27-o
};
//===================调用函数=======================================
/********************************************
//*****函数名:MnLed()
//*****函数功能: LED数码管动态扫描扫描函数
//*****输入参数: 无
//*****输出参数:无
**********************************************/
void MnLed(void)
{
ComPortBuf=0xfe;
for(ScanBitCnt = 0;ScanBitCnt <= 3;ScanBitCnt ++)
{
DataPort = CODE[LedDispBuff[ScanBitCnt]];//段选
ComPort=ComPortBuf;//位选
ScanTimeCnt=ScanTime;
while(ScanTimeCnt--);//扫描延时
ComPort=0xff;
ComPortBuf<<=1;
ComPortBuf++;
}
}
/********************************************
//*****函数名:Led4Disp()
//*****函数功能: LED数码管显示内容修改函数
//*****输入参数: 无
//*****输出参数:无
**********************************************/
void LedDisp(uchar i ,uchar j, uchar m ,uchar n)
{
//LedDispBuff[0] = KeyBuf[0];
//LedDispBuff[1] = KeyBuf[1];
//LedDispBuff[2] = KeyBuf[2];
//LedDispBuff[3] = KeyBuf[3];
LedDispBuff[0] = i ;
LedDispBuff[1] = j ;
LedDispBuff[2] = m ;
LedDispBuff[3] = n ;
} |
|