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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機學習:使用DS1302芯片制作電子鐘

[復制鏈接]
跳轉到指定樓層
樓主
ID:161768 發(fā)表于 2017-1-14 23:30 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
百度ds1302 寫道
DS1302 是美國DALLAS公司推出的一種高性能、低功耗、帶RAM的實時時鐘電路,它可以對年、月、日、周日、時、分、秒進行計時,具有閏年補償功能,工作電壓為2.5V~5.5V。采用三線接口與CPU進行同步通信,并可采用突發(fā)方式一次傳送多個字節(jié)的時鐘信號或RAM數(shù)據(jù)。DS1302內部有一個31×8的用于臨時性存放數(shù)據(jù)的RAM寄存器。DS1302是DS1202的升級產(chǎn)品,與DS1202兼容,但增加了主電源/后備電源雙電源引腳,同時提供了對后備電源進行涓細電流充電的能力。
DS1302的引腳排列,其中Vcc1為后備電源,VCC2為主電源。在主電源關閉的情況下,也能保持時鐘的連續(xù)運行。DS1302由Vcc1或Vcc2兩者中的較大者供電。當Vcc2大于Vcc1+0.2V時,Vcc2給DS1302供電。當Vcc2小于Vcc1時,DS1302由Vcc1供電。X1和X2是振蕩源,外接32.768kHz晶振。RST是復位/片選線,通過把RST輸入驅動置高電平來啟動所有的數(shù)據(jù)傳送。RST輸入有兩種功能:首先,RST接通控制邏輯,允許地址/命令序列送入移位寄存器;其次,RST提供終止單字節(jié)或多字節(jié)數(shù)據(jù)傳送的方法。當RST為高電平時,所有的數(shù)據(jù)傳送被初始化,允許對DS1302進行操作。如果在傳送過程中RST置為低電平,則會終止此次數(shù)據(jù)傳送,I/O引腳變?yōu)楦咦钁B(tài)。上電運行時,在Vcc>2.0V之前,RST必須保持低電平。只有在SCLK為低電平時,才能將RST置為高電平。I/O為串行數(shù)據(jù)輸入輸出端(雙向),后面有詳細說明。SCLK為時鐘輸入端。 下圖為DS1302的引腳功能圖
.....................................................................................



我在淘寶上花了幾塊錢買了個山寨的1302模塊,湊合著可以用,
但是模塊上的sclk,io,RST這3個腳沒有上拉電阻,自己加上去了,汗!
不加上拉電阻,顯示的時鐘很容易發(fā)生錯誤
好了不多說,貼代碼
本程序只顯示時間,沒有年份和月份...
  1. #include "my51.h"
  2. #include "smg.h"
  3. #include "ds1302.h"

  4. void main()                           //ds1302顯示時鐘
  5. {
  6.     ds1302_initSet();//初始化
  7.         //ds1302_stop();   停掉1302,進入省電模式
  8.     while(1)
  9.     {
  10.         ds1302_readRTC();_nop_();        //讀取時鐘數(shù)據(jù)
  11.         displaySMG(ds1302_processTimeData());//處理數(shù)據(jù)并送數(shù)碼管顯示
  12.     }
  13. }
復制代碼

  1. #ifndef _DS1302_H
  2. #define _DS1302_H

  3. #include "my51.h"

  4. sbit rst=P3^4;  //片選總線
  5. sbit sda=P3^5; //數(shù)據(jù)總線
  6. sbit scl=P3^6;  //時鐘線

  7. extern u8 data smgWela[7];         //數(shù)碼管顯示參數(shù)
  8. extern u8 data timeData[7];  //年,周,月,日,時,分,秒的初值

  9. //void ds1302_setUnCharger()    //充電控制,禁止充電
  10. //void ds1302_stop() ;                 //暫停ds1302,進入超低功耗模式
  11. u8* ds1302_processTimeData();   //處理時鐘數(shù)據(jù),送給數(shù)碼管顯示
  12. void ds1302_readRTC();     //讀取所有時鐘數(shù)據(jù)的BCD碼
  13. void ds1302_initSet() ;     //設置初始化數(shù)據(jù)
  14. u8 ds1302_readData(u8 addr); //從ds1302讀一個字節(jié),讀的時候會先寫地址
  15. void ds1302_writeByte(u8 dat);   //寫一個字節(jié)
  16. void ds1302_writeData(u8 addr,u8 dat); //向指定地址寄存器寫數(shù)據(jù)

  17. #endif
復制代碼


  1. #include "ds1302.h"

  2. data u8 timeData[7]={10,6,4,17,11,20,55};
  3. code u8 writeAddr[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//寫年周月日時分秒寄存器地址指令
  4. code u8 readAddr[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};//讀的指令地址

  5. void ds1302_writeData(u8 addr,u8 dat) //向指定地址寄存器寫數(shù)據(jù)
  6. {
  7.     rst=0; _nop_();
  8.     scl=0; _nop_();
  9.     rst=1; _nop_();
  10.     ds1302_writeByte(addr); //先寫入地址
  11.     ds1302_writeByte(dat);
  12.     rst=0;_nop_(); //關閉
  13.     sda=1;         //釋放
  14.     scl=1;
  15. }

  16. void ds1302_writeByte(u8 dat)   //寫一個字節(jié)
  17. {
  18.     u8 i=0;
  19.     for(i=0;i<8;i++)
  20.     {
  21.         scl=0;              //時鐘線拉低
  22.         sda=dat&0x01;                 //數(shù)據(jù)從最低位開始賦值
  23.         dat>>=1;
  24.         scl=1;_nop_();      //上升沿寫入一位  
  25.     }
  26. }

  27. u8 ds1302_readData(u8 addr) //從ds1302讀一個字節(jié),讀的時候會先寫地址
  28. {
  29.     u8 i,value=0;
  30.     rst=0;_nop_();
  31.     scl=0;_nop_();
  32.         sda=1;_nop_();
  33.     rst=1;_nop_();
  34.     ds1302_writeByte(addr); //先寫入要讀的地址
  35.         _nop_();
  36.         sda=1;_nop_();
  37.     for(i=0;i<8;i++)
  38.     {
  39.         value>>=1;
  40.         scl=0;_nop_();  //下降沿開始后提取有效數(shù)據(jù)
  41.         if(sda)         //讀數(shù)據(jù)
  42.         {
  43.             value|=0x80;//高電平手動置位保存數(shù)據(jù),
  44.         }               //低電平數(shù)據(jù)value最高位默認已經(jīng)是0
  45.         scl=1;          //為下一次讀取數(shù)據(jù)做準備
  46.     }
  47.     rst=0;
  48.     return value;
  49. }

  50. void ds1302_initSet()      //設置初始化數(shù)據(jù)
  51. {
  52.     u8 i,j;
  53.     for(i=0;i<7;i++)//將初始化數(shù)據(jù)處理成BCD碼
  54.     {
  55.         j = timeData[i] / 10;
  56.         timeData[i]=timeData[i]%10;
  57.         timeData[i]=timeData[i]+j*16;
  58.     }
  59.         ds1302_writeData(0x8e,0x00);  //清除寫保護
  60.     for(i=0;i<7;i++)
  61.     {   //將時鐘日歷數(shù)據(jù)經(jīng)過轉換后的BCD碼寫到7個時鐘日歷寄存器中
  62.         ds1302_writeData(writeAddr[i],timeData[i]);
  63.     }
  64.         ds1302_writeData(0x90,0x5c); //禁止充電,降低功耗,針對不可充電電池
  65.         //ds1302_writeData(0x90, 0xa6);//開啟充電,用一個二極管,用4k電阻
  66.         ds1302_writeData(0x8e,0x80); //使能寫保護
  67. }
  68.    
  69. void ds1302_readRTC()     //讀取所有時鐘數(shù)據(jù)的BCD碼
  70. {
  71.     u8 i;
  72.     for(i=0;i<7;i++)
  73.     {   //讀取的時候會把時鐘日歷的7個寄存器中的數(shù)據(jù)全部讀取,并保存到timeData[]
  74.         timeData[i]=ds1302_readData(readAddr[i]);
  75.     }
  76. }

  77. u8* ds1302_processTimeData()  //顯示時鐘,暫時只顯示時間
  78. {
  79.     smgWela[5]=timeData[6] & 0x0f;//提取低4位
  80.     smgWela[4]=timeData[6] >> 4;//提取高4位
  81.     smgWela[3]=timeData[5]& 0x0f;
  82.     smgWela[2]=timeData[5]>> 4;
  83.     smgWela[1]=timeData[4]& 0x0f;
  84.     smgWela[0]=timeData[4]>> 4;
  85.         smgWela[6]=0xf5; //0xf5是小數(shù)點的位置
  86.     return smgWela;
  87. }

  88. /*
  89. void ds1302_stop()                  //暫停ds1302
  90. {
  91.    ds1302_writeData(0x8e,0x00); //清除寫保護
  92.    ds1302_writeData(writeAddr[6],0x80); //暫停ds1302,進入超低功耗模式
  93.    ds1302_writeData(0x8e,0x80); //使能寫保護
  94. } */

  95. /*   
  96. void ds1302_setUnCharger()          //充電控制,禁止充電
  97. {
  98.    ds1302_writeData(0x8e,0x00); //清除寫保護
  99.    ds1302_writeData(0x90,0x5c); //禁止充電,降低功耗
  100.    ds1302_writeData(0x8e,0x80); //使能寫保護
  101. }*/

復制代碼
  1. #ifndef _51SMG_H_
  2. #define _51SMG_H_

  3. #include "my51.h"

  4. sbit dula =P2^6;                  //段選鎖存器控制  控制筆段
  5. sbit wela =P2^7;                  //位選鎖存器控制  控制位置
  6. extern u8 data smgWela[7]; //第一位到第六位,最后一個是小數(shù)點位置控制

  7. #define dark        0x11//在段中,0x11是第17號元素,0x00是低電平,數(shù)碼管不亮,即table[17]
  8. #define dotDark 0xff//小數(shù)點全暗

  9. void displaySMG(u8* pWela); //數(shù)碼管顯示函數(shù),參數(shù)是數(shù)組指針

  10. #endif
復制代碼


  1. #include "smg.h"
  2. #include "my51.h"

  3. static u8 code table[]= {                 //0~F外加小數(shù)點和空輸出的數(shù)碼管編碼
  4.         0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
  5.         0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
  6.         0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
  7.         0x39 , 0x5e , 0x79 , 0x71 , // C D E F
  8.         0x80 , 0x00 ,0x40           // . 空 負號    空為第17號元素
  9. };

  10. /*  由于此表只能一次顯示一個小數(shù)點,故已注釋掉,僅供查詢
  11.         例如想要第一個和第六個數(shù)碼管小數(shù)點同時點亮,
  12.         則執(zhí)行 pWela->dot = 0xfe & 0xdf  即可
  13.         u8 code dotTable[]={   //小數(shù)點位置,某一位置0時,小數(shù)點亮
  14.         0xff ,                 //全暗
  15.         0xfe , 0xfd , 0xfb ,   //1 2 3
  16.         0xf7 , 0xef , 0xdf     //4 5 6                    
  17. };*/

  18. u8 data smgWela[7]={0,0,0,0,0,0,0}; //第一位到第六位,最后一個是小數(shù)點位置控制

  19. //P0口的數(shù)碼管位選控制鎖存器只用了低6位,我們保留高2位的數(shù)據(jù),留作它用
  20. void displaySMG(u8* pWela)
  21. {
  22.         u8 i=0;        
  23.     //控制6位數(shù)碼管顯示函數(shù),不顯示的位用參數(shù)dark
  24.     u8 preState=P0|0x3f;  //保存高2位狀態(tài),其中最高位是ADC0804的片選信號
  25.         wela=0;dula=0;_nop_();//先鎖定數(shù)據(jù),防止吳亮及位選鎖存器高2位數(shù)據(jù)被改變
  26.                
  27.         P0=0;                                 //由于數(shù)碼管是共陰極的,陽極送低電平,燈不亮
  28.     dula=1;_nop_();
  29.     dula=0;                                 //段選數(shù)據(jù)清空并鎖定

  30.     P0=preState;                    //共陰極數(shù)碼管是陰極置高不亮,低6位置1,高2位保留        
  31.     wela=1;_nop_();                  //注:wela和dula上電默認為1                 
  32.     wela=0;                                    //位選鎖定,初始保留高2位的數(shù)據(jù),低6位置高不亮

  33.         for(i=0;i<6;i++)          //顯示6位數(shù)碼管
  34.         {
  35.                 P0=table[pWela[i]]|(((1<<i) &="" pwela[6])?0x00:0x80);
  36.             dula=1;_nop_();             //送段數(shù)據(jù),疊加小數(shù)點的顯示,0x00點亮小數(shù)點
  37.             dula=0;
  38.             
  39.                    P0=preState&~(1<<i); 不影響高2位數(shù)據(jù),低6位是數(shù)碼管位選,低電平有效
  40.             wela=1;        _nop_();         //送位選號
  41.             wela=0;        
  42.             delayms(1);                         //稍作延時,讓燈管亮起來                        
  43.                 {  //消除疊影及誤亮,陰極置1不亮,低6位置1,高2位保留并鎖定
  44.                 P0=preState;
  45.                 wela=1;        _nop_();                        
  46.                 wela=0;        
  47.             }
  48.         }
  49. }
復制代碼




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

使用道具 舉報

沙發(fā)
ID:95809 發(fā)表于 2017-1-16 17:44 來自手機 | 只看該作者
1302的精度還是不錯的,主要看晶振。另外晶振不要外接電容。現(xiàn)在價格大約5毛一片,比3231便宜多了,
回復

使用道具 舉報

板凳
ID:23303 發(fā)表于 2017-5-28 16:13 | 只看該作者
新手下載學習一下,謝謝!
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av黄色在线 | 国产精品久久久久影院色老大 | 久久精品视频在线播放 | 久久99这里只有精品 | 欧美一区二区在线播放 | 中文字幕日韩一区 | 狠狠伊人| 国产精品欧美日韩 | 欧美成年网站 | 韩国久久 | 最新免费av网站 | 视频在线观看一区二区 | 狠狠操狠狠操 | 在线观看视频一区 | 精品伊人| 久久国内精品 | 久久极品| 成人在线视频网站 | 五月婷婷 六月丁香 | 日本精品视频在线 | 亚洲乱码一区二区三区在线观看 | 五月天婷婷综合 | 国产亚洲精品精品国产亚洲综合 | 精品国产网 | av在线播放一区二区 | 亚洲精品综合 | 在线一级片 | 成人亚洲网站 | 久久亚洲综合 | 一区二区国产精品 | 视频一区二区在线观看 | 亚洲在线免费观看 | 亚洲欧美在线一区 | 一级毛片播放 | 中文字幕免费 | 日韩欧美成人精品 | 国产精品久久久久久久久久 | 日本精品视频在线观看 | av激情在线| 一区二区三区四区在线播放 | 超碰地址 |