求单片机4位数字钟的程序

要求用c语言写,p2.4和p2.5两按键分别控制时钟、分钟加一。中间小数点代表秒闪烁。
(顺便说一下能不能在此数字钟是基础上再让8个流水灯同时显示(只要能动就行),如果不会就算了,写的好我会多给分的!!!)
没人做吗

#include <AT89X52.H>

#define uchar unsigned char

#define FLASH_FREQ 100

sbit KEY1 = P1^4; //定义KEY1 分加1

sbit KEY2 = P1^5; //定义KEY2 秒加1

#define COM1_ON   (P2=0xf7) //1111 1110 //低电平点亮

#define COM2_ON   (P2=0xfb) //1111 1101

#define COM3_ON   (P2=0xfd) //1111 1011

#define COM4_ON   (P2=0xfe) //1111 0111

#define COMS_OFF  (P2=0xff)  /*数码管全灭宏定义*/

#define SEG_PORT  (P0) /*段码数据输出端口*/

uchar code LED_Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳极,COM采用7404取反驱动

#define DISPLAY_BIT 4 //数码管显示位数

uchar DisBuff[DISPLAY_BIT]; //显示缓冲区

bit DisDecemal=0;//是否显示小数点

uchar shi=11,fen=59,miao=49;

void delay(uchar ms)//1ms延时,12MHz

{

uchar i,j;

for(i=ms;i>0;i--)

for(j=122;j>0;j--);

}

void LED_DisplayTimer(uchar LED1,uchar LED2,uchar LED3,uchar LED4)

{

DisBuff[0]=LED_Tab[LED1];

DisBuff[1]=LED_Tab[LED2];

DisBuff[2]=LED_Tab[LED3];

DisBuff[3]=LED_Tab[LED4];

/**************小数点闪烁在这里控制*****/

if(DisDecemal==1)

DisBuff[1]&=0x7f;  //点亮小数点

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

}

void Timer0_Init(void) //@12MHz,STC8952

{

TMOD=0x01; 

TH0=(65536-5000)>>8;    //重装5ms的初值

TL0=(65536-5000);

IE=0x82;

TR0=1;

}

void Display_Scan(void)//共阴极数码管  <5ms调用一次

{

static uchar COM;

COM++;

if(COM>=DISPLAY_BIT) COM=0; //COM的值在0,1,2,3之间切换   

COMS_OFF; //切换前将全部显示暂时关闭,避免虚影,所谓虚影就是数码管看起来"全亮"

switch(COM)

{

case 0:SEG_PORT=DisBuff[0];  //时 十位

COM1_ON;

break;

case 1:SEG_PORT=DisBuff[1]; //时 个位

COM2_ON;

break;

case 2:SEG_PORT=DisBuff[2];   //分 十位

COM3_ON;

break;

case 3:SEG_PORT=DisBuff[3]; //分 个位

COM4_ON;

break;

}

}

void KeyScan(void) //键盘扫描程序

{

if(KEY1==0)

{

delay(5);

if(KEY1==0)

{

shi++;

if(shi==24)

shi=0;

while(!KEY1)//等待按键释放, 仿真按键长时间不释放,影响显示

{

LED_DisplayTimer(shi/10,shi%10,fen/10,fen%10);

}

}

}

else  if(KEY2==0)

{

delay(5);

if(KEY2==0)

{

fen++;

if(fen==60)

fen=0;

while(!KEY2)//等待按键释放

{

LED_DisplayTimer(shi/10,shi%10,fen/10,fen%10);

}

}

}

}

void main()

{

Timer0_Init();

while(1)

{

LED_DisplayTimer(shi/10,shi%10,fen/10,fen%10);

KeyScan(); //键盘扫描

}

}

void Timer0(void) interrupt 1 using 3 //前台程序

{

static uchar flashFREQ;//闪烁频率控制

static uchar mms;//统计中断次数,做时钟的基准源 

flashFREQ++;

mms++;

TH0=(65536-5000)>>8;    //重装5ms的初值

TL0=(65536-5000);

if(mms==200)//5*200=1000

{

mms=0;

miao++;

if(miao==60)

{

miao=0;

fen++;

if(fen==60)

{

fen=0;

shi++;

if(shi==24)

shi=0;

}

}

}

Display_Scan(); //动态扫描数码管 <5ms调用一次

if(flashFREQ>=FLASH_FREQ)   

flashFREQ=0; //闪烁计时

if(flashFREQ>=FLASH_FREQ/2)  //闪烁其实就是一半时间正常显示,一半时间不显示而已,所以我们看起来是闪烁效果

DisDecemal=1;  

else

DisDecemal=0;

}

按键你自己更改,这个程序里的数码管扫描程序很经典,按键程序写的很搓,不过对付你的课程设计是根本都木有问题的!!!!!!!!!!!

温馨提示:内容为网友见解,仅供参考
无其他回答
相似回答