標(biāo)題: 51單片機的時鐘C語言程序,四個按鍵控制 [打印本頁]
作者: diehualong 時間: 2018-12-22 23:17
標(biāo)題: 51單片機的時鐘C語言程序,四個按鍵控制
本帖最后由 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;//控制設(shè)置時某些位的閃爍
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
};
一部分:參數(shù)初始化函數(shù)
void init()
{
TMOD = 0x11;//將定時器0和定時器1設(shè)為工作方式1,16位定時器
TH0 = 0x4B;
TL0 = 0xFC; //設(shè)置定時器0的中斷周期是50ms
TH1 = 0x4B;
TL1 = 0xFC; //設(shè)置定時器1的中斷周期是50ms
PT0 = 1; //設(shè)置定時器0中斷的優(yōu)先級高于定時器1中斷
ET0 = 1; //開啟定時器0中斷
ET1 = 1; //開啟定時器1中斷
TR1 = 1; //定時器1開始計數(shù)
TR0 = 1; //定時器0開始計數(shù)
EA = 1; //開啟總中斷
}
第二部分:關(guān)于數(shù)碼管點亮的函數(shù)
//--------------將小時對應(yīng)的數(shù)碼管的點亮的函數(shù)---------------//
voidhour_display()
{
shi_1 = shi/10; //將小時的十位數(shù)字賦值給shi_1
shi_2 = shi%10; //將小時的個位數(shù)字賦值給shi_2
P0 = pos[0];
we = 1;
we = 0;
P0 = leddata[shi_1];
du = 1;
du = 0;
delay(1); //將最左邊的數(shù)碼管點亮并顯示小時的十位數(shù)字
P0 = pos[1];
we = 1;
we = 0;
P0 = leddata[shi_2];
du = 1;
du = 0; //將左邊第二個數(shù)碼管點亮并顯示小時的個位數(shù)字
delay(1);
}
//----------------將分鐘對應(yīng)的數(shù)碼管的點亮的函數(shù)----------------//
voidfen_display()
{
fen_1 = fen/10; //將分鐘的十位數(shù)字賦值給fen_1
fen_2 = fen%10; //將分鐘的個位數(shù)字賦值給fen_2
P0 = pos[2];
we = 1;
we = 0;
P0 = leddata[fen_1];
du = 1;
du = 0;
delay(1); //將左邊第三個數(shù)碼管點亮并顯示分鐘的十位數(shù)字
P0 = pos[3];
we = 1;
we = 0;
P0 = leddata[fen_2];
du = 1;
du = 0;
delay(1); //將左邊第四個數(shù)碼管點亮并顯示分鐘的個位數(shù)字 }
//-------------將秒數(shù)對應(yīng)的數(shù)碼管的點亮的函數(shù)-------------//
voidmiao_display()
{
miao_1 = miao/10; //將秒數(shù)的十位數(shù)字賦值給miao_1
miao_2 = miao%10; //將秒數(shù)的個位數(shù)字賦值給miao_2
P0 = pos[4];
we = 1;
we = 0;
P0 = leddata[miao_1];
du = 1;
du = 0;
delay(1); //將右邊第二個數(shù)碼管點亮并顯示秒數(shù)的十位數(shù)字
P0 = pos[5];
we = 1;
we = 0;
P0 = leddata[miao_2];
du = 1;
du = 0;
delay(1); //將右邊第一個數(shù)碼管點亮并顯示秒數(shù)的個位數(shù)字
}
//------------判斷當(dāng)參數(shù)shezhi等于1時將小時、分鐘、秒數(shù)所對應(yīng)的數(shù)碼管點亮并顯示出相應(yīng)數(shù)字的函數(shù)-------------//
void alldis()
{
if(shezhi == 0) //當(dāng)參數(shù)shezhi等于0的時候所有數(shù)碼管被點亮,并
{ //將小時、分鐘、秒數(shù)所對應(yīng)數(shù)碼管顯示出對應(yīng)的數(shù)字
hour_display();
fen_display ();
miao_display();
}
}
//------------判斷當(dāng)參數(shù)shezhi等于0時將要修改的位(即小時或分鐘或秒數(shù)對應(yīng)的某兩位數(shù)碼管)出現(xiàn)閃爍效果的函數(shù)--------------//
void fourdis()
{
if(shezhi == 1)
{
P0 = 0xff;
we = 0; //將所有的數(shù)碼管關(guān)閉,以防受到前一次數(shù)碼管打開
we = 1; //的影響,并為下面出現(xiàn)閃爍效果做準(zhǔn)備
if(flag == 0) //判斷當(dāng)參數(shù)flag等于0時將所有數(shù)碼管點亮
{
hour_display();
fen_display ();
miao_display();
}
if(flag == 1) //判斷當(dāng)數(shù)碼管等于1時使需要修改的位置(即小時
{ //或分鐘或秒數(shù)對應(yīng)的某兩位數(shù)碼管)關(guān)閉
if(m == 0) //判斷當(dāng)參數(shù)m為0時將小時對應(yīng)的兩位數(shù)碼管關(guān)閉
{
fen_display ();
miao_display();
}
if(m == 1) //判斷當(dāng)參數(shù)m為1時將分鐘對應(yīng)的兩位數(shù)碼管關(guān)閉
{
hour_display();
miao_display();
}
if(m == 2) //判斷當(dāng)參數(shù)m為2時將秒數(shù)對應(yīng)的兩位數(shù)碼管關(guān)閉
{
hour_display();
fen_display ();
}
}
}
}
//------------------匯總以上將數(shù)碼管點亮的函數(shù)(數(shù)碼管的狀態(tài)將隨參數(shù)的改變而變化----------------------//
void display()
{
alldis() ;
fourdis();
}
第三部分:延時類函數(shù)
//---------通過數(shù)碼管顯示來做到延遲的函數(shù),為按鍵延時消抖做準(zhǔn)備---------//
voiddelay0(uchar z)
{
for(;z > 0;z--)
display(); //將數(shù)碼管以現(xiàn)在的狀態(tài)點亮的函數(shù)
}
//------毫秒級延時函數(shù);當(dāng)z = 1時,即delay(1)代表運行時間為1ms-----//
void delay(uintz)
{
uint x,y;
for(x = z;x > 0;x--)
for(y = 114;y > 0;y--);
}
第四部分:中斷類函數(shù)
//-------------------定時器0中斷函數(shù)(控制每秒秒數(shù)增1,秒數(shù)、分鐘為60進制,小時為24進制)----------------------//
void timer_0()interrupt 1
{
TH0 = 0x4B;
TL0 = 0xFC; //將定時器0設(shè)置為計時50ms中斷1次
n++; //參數(shù)n存儲定時器0中斷次數(shù),來計時是否過1s
n1++; //參數(shù)n1存儲定時器0中斷次數(shù)控制數(shù)碼管閃爍頻率
if(n1 == 5) //當(dāng)n1等于5時將要修改位對應(yīng)的數(shù)碼管點亮(或關(guān)閉)
flag = ~flag,n1 = 0;
if(n >= 20) //當(dāng)n等于20時說明已中斷1s,將n清零并使秒數(shù)增1
{
n = 0;
miao++;
}
if(miao >= 60) //當(dāng)秒數(shù)等于60時使秒數(shù)清零并使分鐘增1,使秒數(shù)滿
{ //足60進制
miao = 0;
fen++;
}
if(fen >= 60) //當(dāng)分鐘等于60時使分鐘清零并使小時增1,使分鐘滿 { //足60進制
fen = 0;
shi++;
}
if(shi >= 24) //當(dāng)小時等于24時使小時清零,使小時滿足24進制
shi = 0;
}
//-----定時器1中斷函數(shù),每50ms中斷1次,判斷是否有按鍵按下-----//
void timer1()interrupt 3
{
TH1 = 0x4B;
TL1 = 0xFC; //將定時器1設(shè)置為50ms計數(shù)
if(key_3 == 0) //判斷K3按鍵是否按下
{
m = 0;
delay0(10); //按鍵延時消抖
if(key_3 == 0)
shezhi = ~shezhi; //打開數(shù)值設(shè)置或者關(guān)閉數(shù)值設(shè)置
delay0(10); //延時消抖
// while(!key_3)
// display();
}
if(key_4 == 0&&shezhi == 1) //判斷在開啟設(shè)置數(shù)值狀態(tài)K4是否按下
{
delay0(10); //按鍵延時消抖
if(key_4 == 0)
m++; //當(dāng)K4按鍵按下使閃爍位后移兩個
if(m >= 3) //當(dāng)閃爍位超過秒數(shù)兩位時時,使之重新回
m = 0; //到小時對應(yīng)的兩位數(shù)碼管使之閃爍
delay0(10); //按鍵延時消抖
// while(!key_4)
// display();
}
if(key_2 == 0&&shezhi == 1)//判斷在開始數(shù)值設(shè)置K2是否按下
{
//--------此參數(shù)flag可以設(shè)置當(dāng)按鍵按下時對應(yīng)數(shù)碼管是否閃爍---------//
flag = 1;
delay0(8); //延時消抖
if(key_2 == 0)
{
if(m == 0) //當(dāng)m等于0,說明此時設(shè)置的是小時,
shi++; //小時數(shù)值上增1
if(m == 1) //當(dāng)m等于1,說明此時設(shè)置的是分鐘,
fen++; //分鐘數(shù)值上增1
if(m == 2) //當(dāng)m等于2,說明此時設(shè)置的是秒數(shù),
miao++; //秒數(shù)數(shù)值上增1
}
//------這條語句可使在設(shè)置數(shù)值狀態(tài)下,長按按鍵時數(shù)值連續(xù)增長------//
delay0(8); //按鍵消抖延時
//------------------------------------------------------------------------------------------//
//---這兩條語句可以使在設(shè)置數(shù)值狀態(tài)下,長按按鍵閃爍位也只增1---//
// while(!key_2)
// display();
//------------------------------------------------------------------------------------------//
}
if(key_1 == 0&&shezhi == 1) //判斷在開始數(shù)值設(shè)置K1是否按下
{
//--------此參數(shù)flag可以設(shè)置當(dāng)按鍵按下時對應(yīng)數(shù)碼管是否閃爍---------//
flag = 0; //此時對應(yīng)的數(shù)碼管處于長亮狀態(tài)
delay0(8); //按鍵延時消抖
if(key_1 == 0)
{
if(m == 0) //當(dāng)m等于0,說明此時設(shè)置的是小時,
shi--; //小時數(shù)值減1
if(shi == 255)
shi = 23;
if(m == 1) //當(dāng)m等于1,說明此時設(shè)置的是分鐘,
fen--; //分鐘數(shù)值減1
if(fen == 255)
fen = 59;
if(m == 2) //當(dāng)m等于2,說明此時設(shè)置的是秒數(shù)
miao--; //秒數(shù)數(shù)值減1
if(miao == 255)
miao = 59;
}
//------這條語句可使在設(shè)置數(shù)值狀態(tài)下,長按按鍵時數(shù)值連續(xù)增長------//
delay0(8);
//------------------------------------------------------------------------------------------//
//---這兩條語句可以使在設(shè)置數(shù)值狀態(tài)下,長按按鍵閃爍位也只增1---//
//while(!key_1)
// display();
//------------------------------------------------------------------------------------------//
}
}
void main()
{
init();
while(1)
display();
}
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |