/*******************************************************************************
* 实验名 : 定时器实验
* 使用的IO :
* 实验效果 :1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒,按K2选择
*选择设置加1。
* 注意 :
*******************************************************************************/
#include
#include"lcd.h"
sbit K1=P3^0;
sbit K2=P3^1;
sbit K3=P3^2;
& e5 G& r% \! J# N; l T) lvoid Delay1ms(unsigned int c);
void TimerConfiguration();
void Int0Configuration();
unsigned char Time; //用来计时间的值
unsigned char SetPlace; //设置修改位
4 e+ x( K- C! h6 K2 Y7 B) h
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
unsigned char hour=13,minute=14,second=00;
unsigned char H2[]=" I LOVE YOU!!! "; //可以改成任意16个字符。
unsigned int i;
TimerConfiguration();
Int0Configuration();
LcdInit();
LcdWriteCom(0x84);
LcdWriteData('0'+hour/10);
LcdWriteData('0'+hour%10);
LcdWriteData(':');
LcdWriteData('0'+minute/10);
LcdWriteData('0'+minute%10);
LcdWriteData(':');
LcdWriteData('0'+second/10);
LcdWriteData('0'+second%10);
LcdWriteCom(0xc0);
for(i=0;i<16;i++) //第2行显示的字符
{
LcdWriteData(H2);
}
while(1)
{
if(TR0==0)
{ if(K1==0) //检测按键K1是否按下
{
Delay1ms(10); //消除抖动
if(K1==0)
{
SetPlace++;
Delay1ms(100);
if(SetPlace>=3)
SetPlace=0;
}
while((i<50)&&(K1==0)) //检测按键K1是否松开
{
Delay1ms(1);
i++;
}
i=0;
}
switch(SetPlace)
{case 0 :
{LcdWriteCom(0x8b); //定位置
LcdWriteCom(0x0f);
Delay1ms(100);
if(K2==0) //检测按键K2是否按下
{
Delay1ms(10); //消除抖动
if(K2==0)
{
second++;
Delay1ms(100);
if(second>=60)
second=0;
% a$ o( n0 b6 `# c, }& J; C% B }
}
LcdWriteCom(0x8a); //定位置
LcdWriteData('0'+second/10);
LcdWriteData('0'+second%10);
LcdWriteCom(0x8b);
}break;
case 1 :
{LcdWriteCom(0x88); //定位置
LcdWriteCom(0x0f);
Delay1ms(100);
if(K2==0) //检测按键K2是否按下
{
Delay1ms(10); //消除抖动
if(K2==0)
{
minute++;
Delay1ms(100);
if(minute>=60)
minute=0;
- H+ o9 n9 _+ c- R; e5 r9 T
}
}
LcdWriteCom(0x87); //定位置
LcdWriteData('0'+minute/10);
LcdWriteData('0'+minute%10);
LcdWriteCom(0x88);
}break;
case 2 :
{LcdWriteCom(0x85); //定位置
LcdWriteCom(0x0f);
Delay1ms(100);
if(K2==0) //检测按键K2是否按下
{
Delay1ms(10); //消除抖动
if(K2==0)
{
hour++;
Delay1ms(100);
if(hour>=24)
hour=0;
( b% y. x* J$ I4 Z
}
}
LcdWriteCom(0x84); //定位置
LcdWriteData('0'+hour/10);
LcdWriteData('0'+hour%10);
LcdWriteCom(0x85);
}break;
}
}
! E: J5 ^/ d. q8 ] ^ else
{
LcdWriteCom(0x0c);
if(Time>=20) //一秒钟来到改变数值
{
Time=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
//--显示时钟--//
LcdWriteCom(0x84);
LcdWriteData('0'+hour/10);
LcdWriteData('0'+hour%10);
LcdWriteData(':');
LcdWriteData('0'+minute/10);
LcdWriteData('0'+minute%10);
LcdWriteData(':');
LcdWriteData('0'+second/10);
LcdWriteData('0'+second%10);
}
}
}
- z- ?6 _3 `2 f: C# S/*******************************************************************************
* 函 数 名 : Delay1ms()
* 函数功能 : 延时1ms
* 输 入 : c
* 输 出 : 无
*******************************************************************************/
' j$ ]$ x& A) p! k \* t- Yvoid Delay1ms(unsigned int c) //误差 0us
{
unsigned char a,b;
for (; c>0; c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
1 `1 i- h: c# w0 w4 Y% d& b }
# |0 R: b2 B1 g J; w' Z
}
$ _# c- \/ m$ R: `0 m5 s( u
/*******************************************************************************
* 函 数 名 : TimerConfiguration()
* 函数功能 : 配置定时器值
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
, Q7 P3 ?% y4 W: P" ~. h Nvoid TimerConfiguration()
{
TMOD = 0x01; //选择工作方式1
TH0 = 0x3C; //设置初始值 50ms
TL0 = 0xB0;
EA = 1; //打开总中断
ET0 = 1; //打开定时器0中断
TR0 = 1; //启动定时器0
}
/*******************************************************************************
* 函 数 名 : Timer0()
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
& d: C, ~7 L+ S- i' a3 Q
void Timer0() interrupt 1
{
TH0 = 0x3C; //设置初始值 50ms
TL0 = 0xB0;
Time++;
}
/*******************************************************************************
* 函 数 名 : Int0Configuration()
* 函数功能 : 配置外部中断0
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
+ v: L, A" T& k; l5 `6 m. r* ~2 u
void Int0Configuration()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
EA=1;//打开总中断
}
/*******************************************************************************
* 函 数 名 : Int0() interrupt 0
* 函数功能 : 外部中断0的中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
( P( k5 }& ?5 {8 Z7 gvoid Int0() interrupt 0
{
Delay1ms(10);
if(K3==0)
{
TR0=~TR0;
SetPlace=0;
}
}
. {7 Q+ R A+ H
书上原来的程序,可以实现1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒,按K2选择加1。 但是进入设置后,正在设置的哪一位没有光标提示,不够人性化。我在原程序的基础上,加以修改,进入设置功能后,正在设置哪一位,有了光标闪烁提示。
+ A/ t1 j" u5 x
- I, O) S2 D- x, j
3 o( C! E. E/ \$ p+ [$ D
8 o) i4 f: `% s$ b$ a5 Z3 Q* l% n
' F' ^: Y$ r* |9 W% T9 e0 z( o- R
; X. u1 Z5 M, o" v- w9 W" u2 w$ S' o0 L
0 i" `; V. W# b0 O0 M. `0 E; M
5 ]. W( Y2 t$ l4 `; h4 b4 ^
, Z L, S( S9 h
8 X( I8 F8 f8 l
7 \* I. d6 b3 }) t" }5 m1 Z4 X3 R8 [8 h- h& M! G' K9 q7 {
: P% x2 n. m. A" b2 w# P5 ~, [' H5 f
* F! M9 Q8 a% V; Q
6 q9 w9 H' \& ]$ P% J# X7 w1 K3 X( B e
! }& D) K1 f; A+ o; I% u) v* b
$ b' Z9 d! v$ o
) |" A9 x) K2 W+ p% p2 @' a' p3 D2 ~8 P" ]' O* ~
. n1 Y; i; }9 H4 i' ~
& R( n a8 x; g9 T2 _7 c
C8 e! h) I4 v, n. V
( y1 f) g" r9 X2 S. S- w
6 i4 E/ i N2 K; u
) C' @ T& D; s( a5 R
' {# }7 O8 C' N" M- X3 E5 r3 P) T8 l- m7 J3 v
![]()