用KEIL编写C语言程序实现:单片机是AT89C51,实现一个计时器,数码管为6为的,有三个按键接在P0上。

三个按键分别为开始、暂停、加\减。当系统复位后,初试时间为00.00.00,按下开始按键,显示为23.59.59,默认以减计时器,每秒减一,计时期间任何时候按下暂停按钮,计时停止,并保持,再次按下开始按钮,继续计时。用PROTUS仿真,图为

按照你的要求写的程序如下,你拿去测试吧!

 

#include "REG52.H"

sbit SHUG_01 = P2^0;    //数码管1

sbit SHUG_02 = P2^1;    //数码管2

sbit SHUG_03 = P2^2;    //数码管3

sbit SHUG_04 = P2^3;    //数码管4

sbit SHUG_05 = P2^4;    //数码管5

sbit SHUG_06 = P2^5;    //数码管6


 

sbit    KEY0_01 = P0^0;    //按键  启动或停止

sbit    KEY0_02 = P0^1;    //按键  加

sbit    KEY0_03 = P0^2;    //按键减


 

#define     LED_DATA        P1      //P1数据端口

unsigned char value_temp = 0;

unsigned char value_shio = 23;

unsigned char value_feno = 59;

unsigned char value_miao = 59;


 

unsigned char code   value_tab0[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //共阳极

unsigned char code   value_tab1[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //共阳极 

 

/*

 * 延时1ms延时子函数

**/

void Delay_1ms(unsigned int Time)

{

 unsigned int x, y;

 for(x = Time; x > 0; x--)

  for(y = 120; y > 0; y--);

}


 

/*

 * 按键开关【启动和停止】子函数

**/

void Scan_keyoutCmd(void)

{

 if(KEY0_01 == 0)           

 {

  Delay_1ms(10);         

  if(KEY0_01 == 0)           

  {

   TR0 = ~ TR0;   

  }

  while(KEY0_01 == 0);         

 } 


 

 if(KEY0_02 == 0)           

 {

  Delay_1ms(10);           

  if(KEY0_02 == 0)           

  {

   value_miao--;   

   if(value_miao == -1)

   {

    value_feno--;

    value_miao = 59;

    if(value_feno == 0)

    {

     value_shio--;

     value_feno = 59;

     if(value_shio == 0)

     {

      value_shio = 23;

     }

    } 

   }

   while(KEY0_02 == 0);       

  }

 } 


 

 if(KEY0_03 == 0)           

 {

  Delay_1ms(10);         

  if(KEY0_03 == 0)         

  {

   value_miao++;   

   if(value_miao == 60)

   {

    value_miao = 0;

    value_feno++;

    if(value_feno == 60)

    {

     value_feno = 0;

     value_shio++; 

     if(value_shio == 24)

     {

      value_shio = 0;

     }

    } 

   }

    while(KEY0_03 == 0);          //检测松手

  }

 } 

}


 

/*

 * 程序运行【启动和停止】子函数

**/

void Disp_layledketCmd(void)

{

 /***小时***/

 SHUG_01 = 1;   

 LED_DATA = value_tab0[value_shio / 10];   /*******小时的十位数显示***************/

 Delay_1ms(5);

 SHUG_01 = 0;

 SHUG_02 = 1;

 LED_DATA = value_tab1[value_shio % 10];   /*******小时的个位数显示***************/

 Delay_1ms(5);

 SHUG_02 = 0;


 

 /***分钟***/

    SHUG_03 = 1;   

 LED_DATA = value_tab0[value_feno / 10];   /*******分钟的十位数显示***************/

 Delay_1ms(5);

 SHUG_03 = 0;

 SHUG_04 = 1;

 LED_DATA = value_tab1[value_feno % 10];   /*******分钟的个位数显示***************/

 Delay_1ms(5);

 SHUG_04 = 0;


 

 /***秒钟***/

    SHUG_05 = 1;   

 LED_DATA = value_tab0[value_miao / 10];   /*******秒钟的十位数显示***************/

 Delay_1ms(5);

 SHUG_05 = 0;

 SHUG_06 = 1;

 LED_DATA = value_tab0[value_miao % 10];   /*******秒钟的个位数显示***************/

 Delay_1ms(5);

 SHUG_06 = 0;

}


 

void Tero_Init(void)

{

 TMOD = 0x01;

 TH0 = (65536 - 50000) / 256;

 TL0 = (65536 - 50000) % 256;

 ET0 = 1;

 TR0 = 1;

 EA = 1;

}


 

/*

 * 函数主体

**/

int main(void)

{

 P1 = P2 = P3 = 0x00;

 Tero_Init();

 

 while(1)

 {

  Scan_keyoutCmd();

  Disp_layledketCmd();  //执行应运程序 

 } 

}


 

/*

 * 定时器中断服务程序

**/

void Tmero()interrupt 1

{

 TH0 = (65536 - 50000) / 256;

 TL0 = (65536 - 50000) % 256;

 value_temp++;

 if(value_temp == 20)

 {

  value_temp = 0;

  value_miao--;

  if(value_miao == 0)

  {

   value_feno--;

   value_miao = 59;

   if(value_feno == 0)

   {

    value_shio--;

    value_feno = 59;

    if(value_shio == 0)

    {

     value_shio = 23;

    }

   }


 

  }

 } 

}

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-12-13
你可以参考下面这个程序,这个是加计时器.把对应端口改下,计时改减就可以了.
数码管的显示网上大把,移植一下就可以了.
//--------LCD 1601 clock----------------------------------------
//---modified from a LCD1602 program,2012/11/21-----------------
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
//----P3: key input for modify timer ---------------------------
#define KEY_IO P3
#define LCD_IO P0
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
//----P1.2: timer speaker output-------------------------------
sbit SPK = P1^2;
//----P2.4: timer LED indicator output------------------------
sbit LED = P2^4;
bit new_s, modify = 0;
char t0, sec = 50, min = 59, hour = 23;
//char code LCD_line1[] = "Designed by ZELD";
char code LCD_line2[] = "Timer: 00:00:00 ";
char Timer_buf[] = "23:59:50";
//---------------------------------------------------
void delay(uint z)
{
uint x, y;
for(x = z; x > 0; x--) for(y = 100; y > 0; y--);
}
//---------------------------------------------------
void W_LCD_Com(uchar com) //写指令
{
LCD_RS = 0; LCD_IO = com; // LCD_RS和R/W都为低电平时,写入指令
LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲
}
//---------------------------------------------------
void W_LCD_Dat(uchar dat) //写数据
{
LCD_RS = 1; LCD_IO = dat; // LCD_RS为高、R/W为低时,写入数据
LCD_EN = 1; delay(5); LCD_EN = 0; //用EN输入一个高脉冲
}
//---------------------------------------------------
void W_LCD_STR(uchar *s) //写字符串
{
while(*s) W_LCD_Dat(*s++);
}
//---------------------------------------------------
void W_BUFF(void) //填写显示缓冲区
{
Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;
Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;
Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;
// W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);
//1602 start from address C0H(second row),1601 start from 40H-------
W_LCD_Com(0x80 + 7); W_LCD_STR(Timer_buf);

}
//---------------------------------------------------
uchar read_key(void)
{
uchar x1, x2;
KEY_IO = 255;
x1 = KEY_IO;
if (x1 != 255) {
delay(100);
x2 = KEY_IO;
if (x1 != x2) return 255;
while(x2 != 255) x2 = KEY_IO;
if (x1 == 0x7f) return 0;
else if (x1 == 0xbf) return 1;
else if (x1 == 0xdf) return 2;
else if (x1 == 0xef) return 3;
else if (x1 == 0xf7) return 4;
}
return 255;
}
//---------------------------------------------------
void Init()
{
LCD_RW = 0;
W_LCD_Com(0x38); delay(50);
W_LCD_Com(0x0c);
W_LCD_Com(0x06);
W_LCD_Com(0x01);
// W_LCD_Com(0x80); W_LCD_STR(LCD_line1);
// W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);
W_LCD_Com(0x80); W_LCD_STR(LCD_line2);
TMOD = 0x01; //T0定时方式1
TH0 = 0x4c;
TR0 = 1; //启动T0
PT0 = 1; //高优先级, 以保证定时精度
ET0 = 1;
EA = 1;
}
//---------------------------------------------------
void main()
{
uint i, j;
uchar Key;
Init();
while(1) {
//-------------------------------
if (new_s) { //如果出现了新的一秒, 修改时间
new_s = 0; sec++; sec %= 60;
if(!sec) { min++; min %= 60;
if(!min) { hour++; hour %= 24;}
}
W_BUFF(); //写显示
//-------------------------------
if (!sec && !min) { //整点报时
for (i = 0; i < 200; i++) {
SPK = 0; for (j = 0; j < 100; j++);
SPK = 1; for (j = 0; j < 100; j++);
} }
}
//-------------------------------
Key = read_key(); //读出按键
switch(Key) { //分别处理四个按键
case 0: modify = 1; break;
case 1: if(modify) {min++; min %= 60; W_BUFF(); break;}
case 2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}
case 3: modify = 0; break;
} }
}
//---------------------------------------------------
void timer0(void) interrupt 1 //T0中断函数, 50ms执行一次
{
TH0 = 0x4c;
t0++; t0 %= 20; //20, 一秒钟
if(t0 == 0) {new_s = 1; LED = ~LED;}
if(modify) LED = 0;
}
//===================================================
相似回答