本帖最后由 diehualong 于 2018-12-22 23:19 编辑
#include
#define uchar unsigned char
#define uint unsigned int
sbit we = P2^7;
sbit du = P2^6;
sbit key_1 = P3^4;
sbit key_2 = P3^5;
sbit key_3 = P3^6;
sbit key_4 = P3^7;
uchar n1 = 0;//控制多长时间闪烁一次。
uchar shi = 0;
uchar shi_1,shi_2;
uchar fen = 0;
uchar fen_1,fen_2;
uchar miao = 0;
uchar miao_1,miao_2;
uchar n = 0;
bit shezhi = 0;
bit flag = 0;//控制设置时某些位的闪烁
uchar m = 0;//不亮的位置
uchar code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x40, //"-"
};
uchar code pos[] = {
0xfe,
0xfd,
0xfb,
0xf7,
0xef,
0xdf
};
一部分:参数初始化函数
void init()
{
TMOD = 0x11;//将定时器0和定时器1设为工作方式1,16位定时器
TH0 = 0x4B;
TL0 = 0xFC; //设置定时器0的中断周期是50ms
TH1 = 0x4B;
TL1 = 0xFC; //设置定时器1的中断周期是50ms
PT0 = 1; //设置定时器0中断的优先级高于定时器1中断
ET0 = 1; //开启定时器0中断
ET1 = 1; //开启定时器1中断
TR1 = 1; //定时器1开始计数
TR0 = 1; //定时器0开始计数
EA = 1; //开启总中断
}
第二部分:关于数码管点亮的函数
//--------------将小时对应的数码管的点亮的函数---------------//
voidhour_display()
{
shi_1 = shi/10; //将小时的十位数字赋值给shi_1
shi_2 = shi%10; //将小时的个位数字赋值给shi_2
P0 = pos[0];
we = 1;
we = 0;
P0 = leddata[shi_1];
du = 1;
du = 0;
delay(1); //将最左边的数码管点亮并显示小时的十位数字
P0 = pos[1];
we = 1;
we = 0;
P0 = leddata[shi_2];
du = 1;
du = 0; //将左边第二个数码管点亮并显示小时的个位数字
delay(1);
}
//----------------将分钟对应的数码管的点亮的函数----------------//
voidfen_display()
{
fen_1 = fen/10; //将分钟的十位数字赋值给fen_1
fen_2 = fen%10; //将分钟的个位数字赋值给fen_2
P0 = pos[2];
we = 1;
we = 0;
P0 = leddata[fen_1];
du = 1;
du = 0;
delay(1); //将左边第三个数码管点亮并显示分钟的十位数字
P0 = pos[3];
we = 1;
we = 0;
P0 = leddata[fen_2];
du = 1;
du = 0;
delay(1); //将左边第四个数码管点亮并显示分钟的个位数字 }
//-------------将秒数对应的数码管的点亮的函数-------------//
voidmiao_display()
{
miao_1 = miao/10; //将秒数的十位数字赋值给miao_1
miao_2 = miao%10; //将秒数的个位数字赋值给miao_2
P0 = pos[4];
we = 1;
we = 0;
P0 = leddata[miao_1];
du = 1;
du = 0;
delay(1); //将右边第二个数码管点亮并显示秒数的十位数字
P0 = pos[5];
we = 1;
we = 0;
P0 = leddata[miao_2];
du = 1;
du = 0;
delay(1); //将右边第一个数码管点亮并显示秒数的个位数字
}
//------------判断当参数shezhi等于1时将小时、分钟、秒数所对应的数码管点亮并显示出相应数字的函数-------------//
void alldis()
{
if(shezhi == 0) //当参数shezhi等于0的时候所有数码管被点亮,并
{ //将小时、分钟、秒数所对应数码管显示出对应的数字
hour_display();
fen_display ();
miao_display();
}
}
//------------判断当参数shezhi等于0时将要修改的位(即小时或分钟或秒数对应的某两位数码管)出现闪烁效果的函数--------------//
void fourdis()
{
if(shezhi == 1)
{
P0 = 0xff;
we = 0; //将所有的数码管关闭,以防受到前一次数码管打开
we = 1; //的影响,并为下面出现闪烁效果做准备
if(flag == 0) //判断当参数flag等于0时将所有数码管点亮
{
hour_display();
fen_display ();
miao_display();
}
if(flag == 1) //判断当数码管等于1时使需要修改的位置(即小时
{ //或分钟或秒数对应的某两位数码管)关闭
if(m == 0) //判断当参数m为0时将小时对应的两位数码管关闭
{
fen_display ();
miao_display();
}
if(m == 1) //判断当参数m为1时将分钟对应的两位数码管关闭
{
hour_display();
miao_display();
}
if(m == 2) //判断当参数m为2时将秒数对应的两位数码管关闭
{
hour_display();
fen_display ();
}
}
}
}
//------------------汇总以上将数码管点亮的函数(数码管的状态将随参数的改变而变化----------------------//
void display()
{
alldis() ;
fourdis();
}
第三部分:延时类函数
//---------通过数码管显示来做到延迟的函数,为按键延时消抖做准备---------//
voiddelay0(uchar z)
{
for(;z > 0;z--)
display(); //将数码管以现在的状态点亮的函数
}
//------毫秒级延时函数;当z = 1时,即delay(1)代表运行时间为1ms-----//
void delay(uintz)
{
uint x,y;
for(x = z;x > 0;x--)
for(y = 114;y > 0;y--);
}
第四部分:中断类函数
//-------------------定时器0中断函数(控制每秒秒数增1,秒数、分钟为60进制,小时为24进制)----------------------//
void timer_0()interrupt 1
{
TH0 = 0x4B;
TL0 = 0xFC; //将定时器0设置为计时50ms中断1次
n++; //参数n存储定时器0中断次数,来计时是否过1s
n1++; //参数n1存储定时器0中断次数控制数码管闪烁频率
if(n1 == 5) //当n1等于5时将要修改位对应的数码管点亮(或关闭)
flag = ~flag,n1 = 0;
if(n >= 20) //当n等于20时说明已中断1s,将n清零并使秒数增1
{
n = 0;
miao++;
}
if(miao >= 60) //当秒数等于60时使秒数清零并使分钟增1,使秒数满
{ //足60进制
miao = 0;
fen++;
}
if(fen >= 60) //当分钟等于60时使分钟清零并使小时增1,使分钟满 { //足60进制
fen = 0;
shi++;
}
if(shi >= 24) //当小时等于24时使小时清零,使小时满足24进制
shi = 0;
}
//-----定时器1中断函数,每50ms中断1次,判断是否有按键按下-----//
void timer1()interrupt 3
{
TH1 = 0x4B;
TL1 = 0xFC; //将定时器1设置为50ms计数
if(key_3 == 0) //判断K3按键是否按下
{
m = 0;
delay0(10); //按键延时消抖
if(key_3 == 0)
shezhi = ~shezhi; //打开数值设置或者关闭数值设置
delay0(10); //延时消抖
// while(!key_3)
// display();
}
if(key_4 == 0&&shezhi == 1) //判断在开启设置数值状态K4是否按下
{
delay0(10); //按键延时消抖
if(key_4 == 0)
m++; //当K4按键按下使闪烁位后移两个
if(m >= 3) //当闪烁位超过秒数两位时时,使之重新回
m = 0; //到小时对应的两位数码管使之闪烁
delay0(10); //按键延时消抖
// while(!key_4)
// display();
}
if(key_2 == 0&&shezhi == 1)//判断在开始数值设置K2是否按下
{
//--------此参数flag可以设置当按键按下时对应数码管是否闪烁---------//
flag = 1;
delay0(8); //延时消抖
if(key_2 == 0)
{
if(m == 0) //当m等于0,说明此时设置的是小时,
shi++; //小时数值上增1
if(m == 1) //当m等于1,说明此时设置的是分钟,
fen++; //分钟数值上增1
if(m == 2) //当m等于2,说明此时设置的是秒数,
miao++; //秒数数值上增1
}
//------这条语句可使在设置数值状态下,长按按键时数值连续增长------//
delay0(8); //按键消抖延时
//------------------------------------------------------------------------------------------//
//---这两条语句可以使在设置数值状态下,长按按键闪烁位也只增1---//
// while(!key_2)
// display();
//------------------------------------------------------------------------------------------//
}
if(key_1 == 0&&shezhi == 1) //判断在开始数值设置K1是否按下
{
//--------此参数flag可以设置当按键按下时对应数码管是否闪烁---------//
flag = 0; //此时对应的数码管处于长亮状态
delay0(8); //按键延时消抖
if(key_1 == 0)
{
if(m == 0) //当m等于0,说明此时设置的是小时,
shi--; //小时数值减1
if(shi == 255)
shi = 23;
if(m == 1) //当m等于1,说明此时设置的是分钟,
fen--; //分钟数值减1
if(fen == 255)
fen = 59;
if(m == 2) //当m等于2,说明此时设置的是秒数
miao--; //秒数数值减1
if(miao == 255)
miao = 59;
}
//------这条语句可使在设置数值状态下,长按按键时数值连续增长------//
delay0(8);
//------------------------------------------------------------------------------------------//
//---这两条语句可以使在设置数值状态下,长按按键闪烁位也只增1---//
//while(!key_1)
// display();
//------------------------------------------------------------------------------------------//
}
}void main()
{
init();
while(1)
display();
}