本帖最后由 diehualong 于 2018-12-22 23:19 编辑
#include<reg52.h>
#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();
}
|