c语言单片机计时程序,C51-------时钟程序(C语言编写的单片机时钟)

/*************************************************

作者:罗国辉

****************************************************/

这是我大二的时候第一次学单片机的时候写的第一个程序,后面大三的时候,我们专业才开单片机的课程,又真正系统的学习了一遍,才算是真正对单片掌握了,对我后面的嵌入式开发做了一定的铺垫。不过,建议学单片的读者,一开始不要用C语言去写,一开始最好是用汇编去写程序,这样子,对51片子的一些东西可以更好的理解。

1.原理图:

0818b9ca8b590ca3270a3433284dd417.png

2.程序:

#include

#include

#include

#include

#define LEDcom0 XBYTE[0x4ff0]

#define LEDcom1 XBYTE[0x4ff1]

#define LEDcom2 XBYTE[0x4ff2]

#define LEDcom3 XBYTE[0x4ff3]

#define LEDcom4 XBYTE[0x4ff4]

#define LEDcom5 XBYTE[0x4ff5]

#define LEDcom6 XBYTE[0x4ff6]

#define LEDcom7 XBYTE[0x4ff7]

#define keycom XBYTE[0x2fff]

#define HI ((65536 - 50000) / 256)

#define LO ((65536 - 50000) % 256)

#define _TH0_TL0_ (65536 - 50000)

#define M 20 //中断次数

unsigned char code SEG_TAB_A[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0-9码码值

unsigned char code SEG_TAB_B[10] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //0.-9.码值

static unsigned char hou = 12, min = 0, sec = 0;

unsigned char keyflag=0,keyflag2=0;

void keynum(void);

void readkey0(void);

void readkey1(void);

void readkey2(void);

void readkey3(void);

void readkey4(void);

void readkey5(void);

void readkey6(void);

void readkey7(void);

void Timer0(void) interrupt 1 using 1 //T/C0中断服务程序,定时50ms

{

static unsigned char count = 0; //定义静态变量count,中断记数

TR0 = 0;

TL0 += (_TH0_TL0_ + 9) % 256;

TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY;

TR0 = 1;

count++;

if(keycom==0xfd)

{

keynum();

}

if(count == M)

{

count = 0;

sec++;

if(sec == 60)

{

min++;

sec = 0;

if(min == 60)

{

hou++;

min = 0;

if(hou == 24)

{

hou = 0;

}//if hou=24

}//if min=60

}//if sec=60

}//if count=M

}

void Timer0Init(void) //定时器0

{

TMOD = 0x01;

TH0 = HI; //载入高8位初值

TL0 = LO; //载入低8位初值

TR0 = 1; //启动定时器

EA = 1; //开总中断

ET0 = 1; //开定时器中断.若为0则表示关闭

}

void Delay(unsigned char a)//延时a*1MS

{

unsigned char j;

while(a-- != 0)

{

for (j = 0; j < 125; j++);

}

}

int pkey(void)//判断键是否被按下,通过返回值确定

{

if(keycom!=0xff)

{

Delay(200);

if(keycom!=0xff)

return 1;

else

return 0;

}

else

return 0;

}

void keynum(void)//按键确定

{

keyflag2=1;

TR0 = 0;//定时器关闭

EA = 0;//总中断关闭

ET0 = 0;//定时器中断关闭

while(keyflag2)

{

//Delay(500000);

if(pkey()==1)

{

switch(keycom)

{

case 0x7f:

{ readkey0();} break;

case 0xbf:

{ readkey1();} break;

case 0xdf:

{ readkey2();} break;

case 0xef:

{ readkey3();} break;

case 0xf7:

{ readkey4();} break;

case 0xfb:

{ readkey5();} break;

default: break;

}

}

readkey7();

}

}

/*-----时间调整-------

1=hour+ ; 2=minute+ ; 3=second+ ;4=hour- ;5=minute- ; 6=second-

-----------------------*/

void readkey0()

{

while(keycom==0x7f)

{keyflag=1;}

if(hou==24)

{

hou=0;

}

hou++;

}

void readkey1()

{

while(keycom==0xbf)

{keyflag=2;}

if(min==60)

{

min=0;

}

min++;

}

void readkey2()

{

while(keycom==0xdf)

{keyflag=3;}

if(sec==60)

{

sec=0;

}

sec++;

}

void readkey3()

{

while(keycom==0xef)

{keyflag=4;}

if(hou==0)

{

hou=24;

}

hou--;

}

void readkey4()

{

while(keycom==0xf7)

{keyflag=5;}

if(min==0)

{

min=24;

}

min--;

}

void readkey5()

{

while(keycom==0xfb)

{keyflag=6;}

if(sec==0)

{

sec=24;

}

sec--;

}

/*unsigned char readkey6()

{

while(keycom==0xfe)

{keyflag=6;}

key6++;

if(key7>9)

{

key7=0;

}

}

*/

void readkey7()

{

while(keycom==0xfe)

{keyflag=8;}

keyflag2=0;//退出时间调整,置0

/*中断重启*/

TL0 += (_TH0_TL0_ + 9) % 256;

TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY;

TR0 = 1;

EA = 1;

ET0 = 1;

}

void Disp(void)//数码管显示函数

{

LEDcom0 = SEG_TAB_A[ hou / 10 ];

LEDcom1 = SEG_TAB_A[ hou % 10 ];

LEDcom2 = 0x40;

LEDcom3 = SEG_TAB_A[ min / 10 ];

LEDcom4 = SEG_TAB_A[ min % 10 ];

LEDcom5 = 0x40;

LEDcom6 = SEG_TAB_A[ sec / 10 ];

LEDcom7 = SEG_TAB_A[ sec % 10 ];

}

void main(void) //主函数

{

keycom=1;

Timer0Init();

while(1)

{

Disp();

}

}

--------------------------------------

3.问题:

键盘无反应,请教!

---------------

4.答案:

调试了一下,结果发现了错误原因:

由于按鍵等待时间太少,故readkey7()一进入循环就执行,根本就不能处理其它按鍵,所以只需把readkey7()放到switch()里面即可,用7的键值来确定退出!

-----------------罗国辉  2007.6.21

-----------------------

while(keyflag2)

{

//Delay(5000000);

if(pkey()==1)

{

switch(keycom)

{

case 0x7f:

{ readkey0();} break;

case 0xbf:

{ readkey1();} break;

case 0xdf:

{ readkey2();} break;

case 0xef:

{ readkey3();} break;

case 0xf7:

{ readkey4();} break;

case 0xfb:

{ readkey5();} break;

default:

{ readkey7();} break;

}

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值