要求用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;
}
按键你自己更改,这个程序里的数码管扫描程序很经典,按键程序写的很搓,不过对付你的课程设计是根本都木有问题的!!!!!!!!!!!