找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1951|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

STC時(shí)鐘程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:314940 發(fā)表于 2018-4-23 22:51 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
/*************        本程序功能說(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--;
                        }                
                }
        }       
}


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表