久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2132|回復: 2
打印 上一主題 下一主題
收起左側

電子1302時鐘的困惑

[復制鏈接]
跳轉到指定樓層
樓主
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit sclk = P1^0;                                                                //1302時鐘端口
sbit dio = P1^1;                                                                //1302數據端口
sbit ce = P1^2;                                                                        //1302使能
sbit wela = P2^7;                                                                //位選
sbit dula = P2^6;                                                                //段選

sbit KEY1=P3^0;                                                                        //按鍵 設置/確認
sbit KEY2=P3^1;                                                                        //按鍵 加
sbit KEY3=P3^2;                                                                        //按鍵 減

uchar snum,fnum;

char shi,fen,miao;

uchar ss;

char FunctionKeyNum=0;                                //功能鍵鍵值
char FuncTempNum=0;                                        //功能鍵臨時鍵值
typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};        //鍵值狀態值


/***********寫時分秒地址************/
#define write_shi  0x84
#define write_fen  0x82
#define write_miao 0x80
#define write_ram  0xc0
/***********讀時分秒地址************/
#define read_shi  0x85
#define read_fen  0x83
#define read_miao 0x81
#define read_ram  0xc1
                  // 0     1    2    3    4     5    6    7    8   9
uchar d[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共陰不帶小數點
//uchar dd[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};  //        共陰帶小數點


void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=120;y>0;y--);
}


void t0_init()  //定時50ms一個中斷 //
{
  TMOD |= 0X01;          // 這樣第2~8bit原來是什么還是什么,不影響,第1bit賦值為1; TMOD=0x01 這樣是給2~8bit賦值為0,第1bit賦值為1。//
  TH0 = (65536-46080)/256;                //        11.0592MHz除12為921600Hz,就是一秒921600次機器周期,50ms=46080次機器周期。 //
  TL0 = (65536-46080)%256;                //           256(D)=0100(H),這里01就是高8位的數據,00就是低8位的數據,        //
  EA = 1;                                                //         15536(D)里有多少個256,就相當于高8位有多少數值,就是除,商存入高8位寄存器后余下的數存入低8位即可//
  ET0 = 1;
  TR0 = 1;                                                                                               
}
void t1_init()
{
        TMOD |= 0x10;
        TH1 = 0xDC;
        TL1 = 0x00;
        TR1 = 1;       
}

void temer0() interrupt 1
{
  TH0=(65536-46080)/256;
  TL0=(65536-46080)%256;
  ss++;
  if(ss==20)
  ss=0;

}        





void display(uchar shi,uchar fen,uchar miao)                          //顯示函數
{
        if(FunctionKeyNum==0)
        {
                snum=30;
                fnum=30;
        }
       
        if(FunctionKeyNum==1)
        {
                fnum++;
                snum=30;
        }
       
        if(FunctionKeyNum==2)
        {
                snum++;
                fnum=30;
        }
       
       
        if(snum>=30)
        {       
                if((shi/10)<1)         //如果小時十位小于1,
                {
                wela=1;
                P0=0xfe;                //第1位
                wela=0;
                  
                dula = 1;
                 P0=0xff;           // 小時十位就不顯示
                dula = 0;
       
                }
               
                else
                {
                wela=1;
                P0=0xfe;          //第1位
                wela=0;

                dula=1;                       
                P0=d[shi/10];
                dula=0;

                          P0=0xff;  //消隱  關閉位選
                delay(2);
                }
          
                        wela=1;
                        P0=0xfd;           //第2位
                        wela=0;

                        dula=1;
                        P0=d[shi%10];                       
                        dula=0;                                       
                        P0=0xff;
                        delay(2);
       
       
                if(snum==60)
                        snum=0;
        }               


        //        if(miao%2==0)         //if(miao%2==0) 1秒閃爍1次
                if(ss>=10)                 //        這里寫為ss>=10,閃爍頻率可調
                {                                  
            wela=1;
                P0=0xfb;                //第3位
                wela=0;

                dula=1;
                P0=0x40;          //第三位數碼管顯示“— ”
               
                dula=0;
                P0=0xff;
                delay(2);
       
                }

                else
                {
                wela=1;
                P0=0xfb;   //第3位
                wela=0;

                dula=1;
                P0=0;          //第三位數碼管不顯示
                dula=0;
                P0=0xff;
                delay(2);       
                }
       
       
        if(fnum>=30)
        {
                wela=1;
                P0=0xf7;         //第4位
                wela=0;
                 
                dula=1;
                P0=d[fen/10];
                dula=0;
                P0=0xff;
                delay(2);
               
               
                wela=1;
                P0=0xef;         //第5位
                wela=0;
               
                dula=1;
                P0=d[fen%10];
                dula=0;
                  P0=0xff;
                delay(2);
       
               
                if(fnum==60)
                        fnum=0;
        }
               
        //        if(miao%2==0)         //if(miao%2==0) 1秒閃爍1次
                if(ss>=10)                 //if(ss>=10)閃爍頻率可調
                {
                wela=1;
                P0=0xdf;          //第6位
                wela=0;
                dula=1;
                P0=0x40;          //第六位數碼管顯示“— ”
                dula=0;
                P0=0xff;

                delay(2);
                }

                else
                {
                wela=1;
                P0=0xdf;   //第6位
                wela=0;
                dula=1;
                P0=0;          //第六位數碼管不顯示
                dula=0;
                P0=0xff;

                delay(2);
                }
               
               
                wela=1;
                P0=0xbf;                //第7位
                wela=0;
               
            dula=1;
                P0=d[miao/10];                           //秒十位
                dula=0;
                P0=0xff;
                delay(2);
       

                wela=1;
                P0=0x7f;                          //第8位
                wela=0;

                dula=1;
                P0=d[miao%10];                         //秒個位
                dula=0;
                P0=0xff;
                delay(2);               
                                  
               
       
       
}  



void write_1302(uchar add,dat)                 //寫1302函數  
{
        uchar i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        _nop_();
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;                        //把字節存儲在dio中
                        else
                        dio=0;
                temp>>=1; //右移
                sclk=1;         //數據在上升沿時,DS1302讀取數據
                _nop_();
        }
        temp=dat;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        ce=0;                //數據傳送結束
        sclk=0;
}
uchar read_1302(uchar add)                                   //讀1302函數               
{
        uchar dat,dat1,i,temp;
        temp=add;
        ce=0;
        _nop_();
        sclk=0;
        _nop_();
        ce=1;
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if((temp&0x01)==0x01)
                        dio=1;
                        else
                        dio=0;
                temp>>=1;
                sclk=1;
                _nop_();
        }
        for(i=0;i<8;i++)
        {
                sclk=0;
                _nop_();
                if(dio) 請問這句什么意思
                    dat|=0x80;          
                if(i<7)
                        dat>>=1;
                sclk=1;
        }
        dat1=dat/16;
        dat=dat%16;
        dat=dat1*10+dat;           //這三句功能是什么
        ce=0;
        sclk=0;
        return dat;
}                       



void init_1302()                                                        //初始化函數 設置時間
{       
        write_1302(0x8e,0x00);                                        //保護取消,可以進行寫操作
        write_1302(write_miao,0x57);       
        write_1302(write_fen,0x55);
        write_1302(write_shi,0x15);
        write_1302(0x8e,0x80);                                        //保護啟動,不能進行寫操作
}         

void read_sf()
{
        shi=read_1302(read_shi);
        fen=read_1302(read_fen);
        miao=read_1302(read_miao);
        display(shi,fen,miao);

}

void KeyScan(void)
{
        static uchar KeyStateTemp1 = 0;                  //按鍵狀態臨時存儲值1
        static uchar KeyStateTemp2 = 0;                  //按鍵狀態臨時存儲值2
        static uchar KeyStateTemp3 = 0;                  //按鍵狀態臨時存儲值3
        static uchar KeyTime = 0;                          //按鍵延時時間
        bit KeyPressTemp1;                                          //按鍵是否按下存儲值1
        bit KeyPressTemp2;                                          //按鍵是否按下存儲值2
        bit KeyPressTemp3;                                          //按鍵是否按下存儲值3

if(KEY1==0)
   {
   delay(10);
   if(KEY1==0)
         FuncTempNum++;
         if(FuncTempNum>3)  FuncTempNum = 0;
   }


if(FuncTempNum)                                                                //只有功能鍵被按下后,增加和減小鍵才有效
        {
                KeyPressTemp2 = KEY2;                                        //讀取I/O口的鍵值
                switch(KeyStateTemp2)
                {       
                        case StateInit:                                                //按鍵初始狀態
                                if(!KeyPressTemp2)                                //當按鍵按下,狀態切換到確認態
                                        KeyStateTemp2 = StateAffirm;
                                break;
                        case StateAffirm:                                        //按鍵確認態
                                if(!KeyPressTemp2)
                                {
                                        KeyTime = 0;
                                        KeyStateTemp2 = StateSingle;//切換到單次觸發態       
                                }
                                else KeyStateTemp2 = StateInit; //按鍵已抬起,切換到初始態
                                break;
                        case StateSingle:                                        //按鍵單發態
                                if(KeyPressTemp2)                                //為什么按下時間小于1s
                                {
                                        KeyStateTemp2 = StateInit;  //按鍵釋放,則回到初始態
                                        if(FunctionKeyNum == 1)                //若功能鍵第一次按下
                                        {
                                        fen++;
                                        fen=fen/10*16+fen%10;                //轉為16進制
                                        if(fen==0x60)
                                            fen=0x00;
                                           write_1302(write_fen,fen);        //寫入1302
                                        read_sf();                                        //讀出時間,然后顯示
                                        }
                                        if(FunctionKeyNum == 2)                //若功能鍵第二次按下
                                        {
                                                shi++;
                                                shi=shi/10*16+shi%10;                //轉為16進制
                                                if(shi==0x24)
                                                        shi=0x00;
                                                write_1302(write_shi,shi);
                                                read_sf();

                                        }
                                        }
                                        else if(++KeyTime > 100)        //按下時間大于1s(100*10ms)
                                        {
                                                KeyStateTemp2 = StateRepeat;//狀態切換到連發態
                                                KeyTime = 0;       
                                        }
                                break;
                        case StateRepeat:                                        //按鍵連發態               
                                if(KeyPressTemp2)
                                        KeyStateTemp2 = StateInit;        //按鍵釋放,則進初始態
                                else                                                        //按鍵未釋放
                                {
                                        if(++KeyTime > 10)                        //按鍵計時值大于100ms(10*10ms)
                                        {
                                                KeyTime = 0;       
                                                if(FunctionKeyNum == 1)        //若功能鍵第一次按下
                                                {
                                        fen++;
                                        fen=fen/10*16+fen%10;                //轉為16進制
                                        if(fen==0x60)
                                            fen=0x00;
                                           write_1302(write_fen,fen);        //寫入1302
                                        read_sf();                                        //讀出時間,然后顯示
                                                }
                                               
                                                if(FunctionKeyNum == 2)        //若功能鍵第二次按下
                                                {
                                                shi++;
                                                shi=shi/10*16+shi%10;                //轉為16進制
                                                if(shi==0x24)
                                                        shi=0x00;
                                                write_1302(write_shi,shi);
                                                read_sf();
                                                }
                                        }
                                        break;
                                }
                                break;
                        default: KeyStateTemp2 = KeyStateTemp2 = StateInit; break;
                }


                KeyPressTemp3 = KEY3;                                                //讀取I/O口的鍵值
                switch(KeyStateTemp3)
                {       
                        case StateInit:                                                        //按鍵初始狀態
                                if(!KeyPressTemp3)                                        //當按鍵按下,狀態切換到確認態
                                        KeyStateTemp3 = StateAffirm;
                                break;
                        case StateAffirm:                                                //按鍵確認態
                                if(!KeyPressTemp3)
                                {
                                        KeyTime = 0;
                                        KeyStateTemp3 = StateSingle;        //切換到單次觸發態       
                                }
                                else KeyStateTemp3 = StateInit;         //按鍵已抬起,切換到初始態
                                break;
                        case StateSingle:                                                //按鍵單發態
                                if(KeyPressTemp3)                                        //按下時間小于1s
                                {
                                        KeyStateTemp3 = StateInit;          //按鍵釋放,則回到初始態
                                        if(FunctionKeyNum == 1)                        //若功能鍵第一次按下
                                        {
                                                fen--;
                                                fen=fen/10*16+fen%10;                //轉為16進制
                                                if(fen==-1)
                                                fen=0x59;
                                                write_1302(write_fen,fen);
                                                read_sf();
                                        }
                                        if(FunctionKeyNum == 2)                        //若功能鍵第二次按下
                                        {
                                                shi--;
                                                shi=shi/10*16+shi%10;                //轉為16進制
                                                if(shi==-1)
                                                shi=0x23;
                                                write_1302(write_shi,shi);
                                                read_sf();
                                        }
                                }
                                else if(++KeyTime > 100)                        //按下時間大于1s(100*10ms)
                                {
                                        KeyStateTemp3 = StateRepeat;        //狀態切換到連發態
                                        KeyTime = 0;       
                                }
                                break;
                        case StateRepeat:                                                //按鍵連發態               
                                if(KeyPressTemp3)
                                        KeyStateTemp3 = StateInit;                //按鍵釋放,則進初始態
                                else                                                                //按鍵未釋放
                                {
                                        if(++KeyTime > 10)                                //按鍵計時值大于100ms(10*10ms)
                                        {
                                                KeyTime = 0;       
                                                if(FunctionKeyNum == 1)                //若功能鍵第一次按下
                                                {
                                                        fen--;
                                                        fen=fen/10*16+fen%10;                //轉為16進制
                                                        if(fen==-1)
                                                        fen=0x59;
                                                        write_1302(write_fen,fen);
                                                        read_sf();
                                                }
                                                if(FunctionKeyNum == 2)                //若功能鍵第二次按下
                                                {
                                                        shi--;
                                                        shi=shi/10*16+shi%10;                //轉為16進制
                                                        if(shi==-1)
                                                        shi=0x23;
                                                        write_1302(write_shi,shi);
                                                        read_sf();
                                                }
                                        }
                                        break;
                                }
                                break;
                        default: KeyStateTemp3 = KeyStateTemp3 = StateInit; break;
                }
        }
}


void ExecuteKeyNum()
{
        if(TF1)
        {
                TF1 = 0;
                TH1 = 0xDC;
                TL1 = 0x00;
                KeyScan();
        }

        switch (FuncTempNum)
        {
                case 1:        FunctionKeyNum = 1;
                                write_1302(0x8e,0x00);                //寫保護取消
                                write_1302(write_miao,0x80); //  寫秒80,時鐘停止走時;
                break;
               
                case 2: FunctionKeyNum = 2;

                break;
               
                case 3:
                                FunctionKeyNum = 0;
                                write_1302(write_miao,0x00);
                                write_1302(0x8e,0x60);                //保護啟動
                                FuncTempNum =0;
                break;


        }
}


void main()
{
        t0_init();
        t1_init();
        init_1302();                          
        while(1)
        {
           read_sf();
           ExecuteKeyNum();
        }
       
}

紅字的地方是不太懂得地方,請教各位大神


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

使用道具 舉報

沙發
ID:231633 發表于 2017-9-7 17:51 | 只看該作者

解答一下你這個問題吧。
       第一個  if(dio) ,就是如果接收數據的IO口是1,那么表示接收到的數據就是1,需要給dat的最高位“加上”1,因為下面緊接著的右移,就會把這個1帶走到她應該待的地方。dio 為低電平,那么就是0了,dat的最高位就默認是一個0,那么右移過去的就是0。循環8次后,進行8位數據的接收。
      下面那三句話,是把一個BCD碼轉換為十進制的過程。你可以那一個筆手工算一下, 0X34 ,經過三句程序后,會變為十進制數字  34 。再深入解釋一下有點多, dat/16 是右移4位的意思, dat%16 就保留了低四位 ,最后的是組合了一下。
      歡迎加我QQ號,一起交流更多的技術問題。 1827702167

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:111634 發表于 2017-9-9 11:16 | 只看該作者
本帖最后由 zl2168 于 2017-9-9 16:52 編輯

具有校正功能的時鐘1302(LCD1602顯示)
Proteus仿真,確認有效。
實例91 帶校正時鐘1302(LCD1602顯示).rar (52.68 KB, 下載次數: 7)

以上摘自張志良編著《80C51單片機仿真設計實例教程——基于Keil CProteus》清華大學出版社ISBN 978-7-302-41682-1書中電路和程序設計有詳細說明,程序語句條條有注解。仿真電路和Hex文件能在清華出版社網站免費下載,程序源代碼只能到書上看了。到圖書館借,或到新華書店翻閱,或到網上書店打折購買。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产免费拔擦拔擦8x高清 | 久久9久| 性欧美精品一区二区三区在线播放 | 久久精品国产一区二区三区不卡 | 日本精品在线观看 | 色婷婷综合久久久中字幕精品久久 | 午夜在线视频一区二区三区 | 中文字幕在线电影观看 | 亚洲 中文 欧美 日韩 在线观看 | 精品免费国产一区二区三区四区介绍 | 亚洲免费人成在线视频观看 | 涩涩视频网站在线观看 | 日韩成人高清 | 欧美精品一区二区免费 | 亚洲天堂999 | 亚洲一区在线免费观看 | 一区视频| 在线视频国产一区 | 四虎在线视频 | 日韩成人在线电影 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 99福利视频导航 | 日日草夜夜草 | 久久精品av麻豆的观看方式 | 99re国产精品| 成人免费视频 | 成人免费视频一区二区 | 欧美寡妇偷汉性猛交 | 激情黄色在线观看 | 婷婷综合色 | 国产激情片在线观看 | 高清亚洲| 欧美日韩国产高清 | 一区二区福利视频 | 国产在线精品一区二区三区 | 波多野吉衣在线播放 | 久久亚洲欧美日韩精品专区 | 日本一区二区不卡 | 在线国产一区二区 | 日韩免费高清视频 | 香蕉久久av|