|
/************* 本程序功能說(shuō)明 **************
用STC的MCU的IO方式控制74HC595驅(qū)動(dòng)8位數(shù)碼管。
采用定時(shí)器0產(chǎn)生時(shí)鐘時(shí)間
編寫(xiě)者:dengchao
MCU: STC12C2052AD-DIP20
OSC:11.0592MHz
實(shí)現(xiàn)功能:三個(gè)按鍵效時(shí),可以實(shí)現(xiàn)加或減1;連續(xù)加減
調(diào)整時(shí),相應(yīng)內(nèi)部閃爍
特點(diǎn):無(wú)需任何延時(shí)函數(shù),
一個(gè)定時(shí)實(shí)現(xiàn)按鍵消抖和不同時(shí)間的產(chǎn)生
總只需6個(gè)IO口
程序核心思路:圍繞一個(gè)1MS的核心來(lái)產(chǎn)生什么何時(shí)間
******************************************/
#include "reg51.h"
//新一代 1T 8051系列 單片機(jī)系統(tǒng)管理特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
//sfr PCON = 0x87; //Power Control SMOD SMOD0 LVDF POF GF1 GF0 PD IDL 0001,0000
// 7 6 5 4 3 2 1 0 Reset Value
sfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000
//-----------------------------------
sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ - DPS 0000,0000
/************* 本地常量聲明 **************/
unsigned char code duan[]={
// 0 1 2 3 4 5 6 7 8 9 A B C D E F 消隱
0x3F,0x06,0x5B,0x4f,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; //段碼
unsigned char code wei[]={0x01,0x02,0x04,0x08}; //位碼
//秒 分 時(shí)
unsigned char y3,y4,y5,y6,k1,k2,k3,k4,k5,i,sec,minu,hour;
unsigned int j,sw1,sw2;
/************* 本地變量聲明 **************/
sbit sh_cp = P3^7; //pin 11 SRCLK Shift datala clock
sbit st_cp = P3^5; //pin 12 RCLk store (latch) clock
sbit ds = P3^4; //pin 14 SER datala input
void display(void); //595驅(qū)動(dòng)數(shù)碼管動(dòng)態(tài)顯示函數(shù)
void disp595(unsigned char datal); //寫(xiě)一個(gè)字節(jié)到595芯片
void display1(void); //顯示緩沖區(qū)
sbit key1 = P3^2; //功能設(shè)置鍵
sbit key2 = P3^3; //加計(jì)數(shù)鍵
sbit key3 = P3^1; //減計(jì)數(shù)鍵
void time_out(void); //時(shí)、分、秒產(chǎn)生函數(shù)
void dinshiqi_init(void); //定時(shí)器初始化
void key1_scan(void); //三個(gè)獨(dú)立按鍵掃描
void key2_scan(void); //時(shí)、分加減函數(shù)判斷
void key3_scan(void); //時(shí)、分鍵按一下1S后,0.2S連續(xù)加減數(shù)據(jù)
unsigned char led_1111[4];//顯示緩沖
bit y1, y2; //20ms定時(shí)器標(biāo)志
/******************主函數(shù)*****************/
void main(void)
{
dinshiqi_init(); //定時(shí)器初始化
for(i=0; i<4; i++)
led_1111[i] = 0x00; //上電消隱
y3 = 0;
while(1)
{
while(!y2) ; //等待20ms到
y2 = 0;
time_out();
display1();
key1_scan();
}
}
/****************定時(shí)器初始化函數(shù)******************/
void dinshiqi_init(void)
{
AUXR &= 0x7F; //定時(shí)器時(shí)鐘12T模式
TMOD &= 0xF0; //設(shè)置定時(shí)器模式
TMOD |= 0x01; //設(shè)置定時(shí)器模式
TH0 = (65536 - 922) / 256;
TL0 = (65536 - 922) % 256;
ET0 = 1;
TR0 = 1;
EA = 1;
sec = 0;
minu = 30;
hour = 12;
sw2 = 0;
k5 = 0; //時(shí)、分設(shè)置切換寄存器
y4 = 0; //加鍵或減鍵按1S的計(jì)時(shí)寄存器
}
/*************** 秒 分 時(shí) 產(chǎn)生函數(shù)**************/
void time_out(void)
{
sw1++;
if(sw1>50)
{
sw1 = 0;
sec++; //秒
if(sec>60)
{
sec = 0;
minu++; //分
if(minu>60)
{
minu = 0;
hour++; // 時(shí)
if(hour>24)
{
hour=0;
}
}
}
}
if(sw1>25)
y1 = 1; //0.5S閃爍產(chǎn)生和標(biāo)志位
else
y1 = 0;
}
/****************顯示緩沖區(qū)函數(shù)******************/
void display1(void)
{
if(k5 == 0) //k5 = 0正常顯示
{
if(y1==1)
{
led_1111[0] = duan[hour/10]; //時(shí)
led_1111[1] = duan[hour%10];
led_1111[2] = duan[minu/10]; //分
led_1111[3] = duan[minu%10];
}
else
{
led_1111[0] = duan[hour/10] ;
led_1111[1] = duan[hour%10] ;
led_1111[2] = duan[minu/10] ;
led_1111[3] = duan[minu%10] ;
}
}
else
{
if(k5 == 1) //k5 = 1 時(shí)閃爍,進(jìn)入“時(shí)”加減
{
if(y1==1)
{
led_1111[0] = duan[hour/10];
led_1111[1] = duan[hour%10];
}
else
{
led_1111[0] = duan[hour/10]&0x00;
led_1111[1] = duan[hour%10]&0x00;
}
led_1111[2] = duan[minu/10];
led_1111[3] = duan[minu%10];
}
if(k5 == 2) //k5 = 2 分閃爍,進(jìn)入“分”加減
{
if(y1==1)
{
led_1111[2] = duan[minu/10];
led_1111[3] = duan[minu%10];
}
else
{
led_1111[2] = duan[minu/10]&0x80;
led_1111[3] = duan[minu%10]&0x80;
}
led_1111[0] = duan[hour/10];
led_1111[1] = duan[hour%10];
}
}
}
/***************595驅(qū)動(dòng)數(shù)碼管動(dòng)態(tài)顯示函數(shù)*******************/
void disp595(unsigned char datal) //發(fā)送一個(gè)字節(jié)
{
unsigned char i;
for(i=0; i<8; i++)
{
if(datal & 0x80)
ds = 1;
else
ds = 0;
sh_cp = 1;
sh_cp = 0;
datal = datal << 1;
}
}
/****************顯示掃描函數(shù)******************/
void display(void)
{
if(y1==1)
{
disp595(wei[y3]|0x20); //共陰 輸出位碼
}
else
{
disp595(wei[y3]|0x00); //共陰 輸出位碼
}
disp595(~led_1111[y3]); //共陰 輸出段碼
// disp595(wei[y3]); //共陽(yáng) 輸出位碼
// disp595(~duan[LED8[y3]]); //共陽(yáng) 輸出段碼
st_cp = 1;
st_cp = 0;
y3++;
if(y3>3)
{
y3 = 0;
}
}
/**************T0定時(shí)器函數(shù)****************/
void timer0 (void) interrupt 1 //Timer0 1ms中斷函數(shù)
{
TH0 = (65536 - 922) / 256; //重裝定時(shí)值
TL0 = (65536 - 922) % 256;
display(); //采用定時(shí)器0 1MS接一個(gè)數(shù)碼管,實(shí)現(xiàn)動(dòng)態(tài)顯示
sw2++;
if(sw2>19)
{
sw2 = 0;
y2 = 1; //20ms標(biāo)志
}
}
/******************三個(gè)獨(dú)立按鍵掃描*****************/
void key1_scan(void)
{
if(key1==0) k2 = 1; //功能鍵按下k2 = 1
if(key2==0) k2 = 2; //加鍵按下k2 = 2
if(key3==0) k2 = 3; //減鍵按下k2 = 3
if(key2&key3&key1) //三個(gè)按鍵都不按時(shí),40MS后所有跟按鍵有關(guān)的寄存器清0
{
k4++;
if(k4>2) //40MS后所有跟按鍵有關(guān)的寄存器清0
{
k4 = 0;
k2 = 0;
k3 = 0;
y4 = 0;
y5 = 0;
}
}
else
{
if(k2!=k3) //k3 為按鍵消抖寄存器
{
k3 = k2;
if(k2==1)
{
k5++;
if(k5==3)
{
k5 = 0;
sec = 0;
}
}
key2_scan(); //按一次響應(yīng)一次
}
key3_scan(); //加鍵或減鍵按1S后連續(xù)加或減數(shù)據(jù)
}
}
/*********** 時(shí)、分 鍵按一下1S后,0.2S連續(xù)加減數(shù)據(jù)**********/
void key3_scan(void)
{
if(y5==0)
{
if((k2==2)|(k2==3))
{
y4++;
if(y4>50)
{
y4 = 0;
y5 = 1;
}
}
}
if(y5==1) //1S到后,進(jìn)入0.2s加減數(shù)據(jù)
{
y6++;
if(y6>10)
{
y6=0;
key2_scan();
}
}
}
/****************** 時(shí)、分 加減函數(shù)判斷****************/
void key2_scan(void)
{
if(k5==1)
{
if(k2==2)
{
hour++;
if(hour>23) //時(shí)
hour = 0;
}
if(k2==3)
{
if(hour==0)
hour = 23;
else
{
hour--;
}
}
}
if(k5==2)
{
if(k2==2)
{
minu++;
if(minu>59) //分
minu = 0;
}
if(k2==3)
{
if(minu==0)
minu = 59;
else
{
minu--;
}
}
}
}
|
|