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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

ds1302是如何實現按鍵改時間的,能麻煩大佬看一下嗎?

[復制鏈接]
跳轉到指定樓層
樓主
ID:1149524 發表于 2025-5-4 15:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #include<STDIO.H>
  4. #include<string.h>
  5. #define uchar unsigned  char
  6. #define uint  unsigned   int
  7. sbit k1=P1^0;
  8. /////////////////////////////////////////////////LCD12864串行顯示相關驅動///////////////////////////
  9. uchar code num[]={"0123456789:.-"};//此數組用于顯示數字轉碼
  10. uchar time_buf[8] = {0x20,0x23,0x05,0x04,0x09,0x09,0x55,0x04};//用于DS1302放置設置相關數據,此處初始時間2010年6月1號23點59分55秒 星期二
  11. uchar dis_time_buf[16]={0};//用于放置折分開的DS1302讀回的數據,可用于LCD——12864顯示
  12. //////////第一步,設置LCD12864串行顯示所需的I/O口線,硬件接線圖////////////////////////////////////
  13. sbit   CS    =  P3 ^5;        //片選 高電平有效 單片LCD使用時可固定高電平
  14. sbit   SID   =  P3 ^6;        //數據
  15. sbit   SCLK  =  P3 ^4;        //時鐘
  16. sbit   PSB  =  P3 ^7;        //串并切換,0串,1并
  17. ////////////////DS1302引腳定義硬件接線圖//////////////////////////////////////////////////////////
  18. sbit RST=P2^3;
  19. sbit IO=P2^2;
  20. sbit SCK=P2^1;
  21. //////////////////////////////////////////////////////////////////////////////////////////////////
  22. //LCD_12864專用延時函數
  23. void Delaynms(uint di) //延時
  24. {
  25.         uint da,db;
  26.          for(da=0;da<di;da++)
  27.                    for(db=0;db<10;db++);
  28. }
  29. //LCD_12864專用單字節必用函數
  30. void Send_byte(uchar bbyte) //發送一個字節
  31. {
  32.         uchar i;
  33.          for(i=0;i<8;i++)
  34.            {
  35.                    SID=bbyte&0x80; //取出最高位
  36.                  SCLK=1;
  37.                    SCLK=0;
  38.                    bbyte<<=1; //左移
  39.            }  
  40. }
  41. //LCD_12864寫指令字節必用函數
  42. void Write_char(bit start, uchar ddata) //寫指令或數據
  43. {
  44.         uchar start_data,Hdata,Ldata;
  45.           if(start==0)
  46.                 start_data=0xf8;         //寫指令
  47.     else   
  48.             start_data=0xfa;  //寫數據

  49.           Hdata=ddata&0xf0;                  //取高四位
  50.           Ldata=(ddata<<4)&0xf0;  //取低四位
  51.           Send_byte(start_data);          //發送起始信號
  52.           Delaynms(5); //延時是必須的
  53.           Send_byte(Hdata);              //發送高四位
  54.           Delaynms(1);  //延時是必須的
  55.           Send_byte(Ldata);                  //發送低四位
  56.           Delaynms(1);  //延時是必須的
  57. }
  58. //LCD_12864初始化函數,在顯示之前必需先初始化
  59. void Lcd_init()        //初始化LCD
  60. {        
  61.           PSB=0;//串型模式
  62.           Delaynms(10); //啟動等待,等LCM講入工作狀態
  63.           CS=1;
  64.           Write_char(0,0x30);  //8 位介面,基本指令集
  65.           Write_char(0,0x0c);  //顯示打開,光標關,反白關
  66.           Write_char(0,0x01);  //清屏,將DDRAM的地址計數器歸零  
  67. }
  68. //LCD_12864清屏函數,在需要清屏時調用
  69. void Clr_Scr()//清屏函數
  70. {
  71.         Write_char(0,0x01);
  72. }
  73. //LCD_12864設置顯示行、列函數,X為行,Y為列
  74. void LCD_set_xy( uchar x, uchar y )
  75. {        //設置LCD顯示的起始位置,X為行,Y為列
  76.     uchar address;
  77.         switch(x)
  78.         {  
  79.     case 1: address = 0x80 + y; break;
  80.                 case 2: address = 0x90 + y; break;
  81.            case 3: address = 0x88 + y; break;
  82.                 case 4: address = 0x98 + y; break;
  83.                 default:address = 0x80 + y; break;
  84.         }
  85.     Write_char(0, address);
  86. }
  87. //LCD_12864調用數組顯示字串函數,包括漢字,X,Y為起始位置,S為數組名
  88. void LCD_Write_string(uchar X,uchar Y,uchar *s)
  89. {        //        中英文字符串顯示函數
  90.         LCD_set_xy( X, Y );

  91.     while (*s)
  92.     {
  93.                         Write_char( 1, *s );
  94.                         s++;
  95.                         Delaynms(1);
  96.           }
  97. }
  98. //LCD_12864顯示數字函數,
  99. void LCD_Write_number(uchar s)//數字顯示函數
  100. {        
  101.         Write_char(1,num[s]);
  102.         Delaynms(1);
  103. }
  104. /////////////////////////////////////////////////LCD12864串行顯示相關驅動///////////////////////////
  105. ////////////////////////////////////////////////DS1302驅動代碼/////////////////////////////////////
  106. //DS1302地址定義,必需要有的程序
  107. #define ds1302_sec_add                          0x80                //秒數據地址
  108. #define ds1302_min_add                          0x82                //分數據地址
  109. #define ds1302_hr_add                            0x84                //時數據地址
  110. #define ds1302_date_add                          0x86                //日數據地址
  111. #define ds1302_month_add                  0x88                //月數據地址
  112. #define ds1302_day_add                          0x8a                //星期數據地址
  113. #define ds1302_year_add                          0x8c                //年數據地址
  114. #define ds1302_control_add                0x8e                //控制數據地址
  115. #define ds1302_charger_add                0x90                                          
  116. #define ds1302_clkburst_add                0xbe
  117. //DS1302初始化函數,使用時第一步用此函數初始化
  118. void ds1302_init()
  119. {
  120.         RST=0;                        //RST腳置低
  121.         SCK=0;                        //SCK腳置低
  122. }
  123. //向DS1302寫入一字節數據,addr為地址,d為要寫入的數據
  124. void ds1302_write_byte(uchar addr, uchar d)
  125. {
  126.         uchar i;
  127.         RST=1;                                        //啟動DS1302總線        
  128.         //寫入目標地址:addr
  129.         addr = addr & 0xFE;     //最低位 置零,寄存器 0位為0時寫,為1時讀
  130.         for (i = 0; i < 8; i ++)
  131.         {
  132.                 if (addr & 0x01)            //為0
  133.                 {
  134.                         IO=1;                        //輸入
  135.                         }
  136.                 else
  137.                 {
  138.                         IO=0;
  139.                         }
  140.                 SCK=1;      //產生時鐘
  141.                 SCK=0;
  142.                 addr = addr >> 1;  //右移1位
  143.                 }        
  144.         //寫入數據:d
  145.         for (i = 0; i < 8; i ++) {
  146.                 if (d & 0x01)                  //為0
  147.                 {
  148.                         IO=1;                   //輸入
  149.                         }
  150.                 else
  151.                 {
  152.                         IO=0;
  153.                         }
  154.                 SCK=1;    //產生時鐘
  155.                 SCK=0;
  156.                 d = d >> 1;                   //右移1位
  157.                 }
  158.         RST=0;                //停止DS1302總線
  159. }
  160. //從DS1302讀出一字節數據,addr為地址
  161. uchar ds1302_read_byte(uchar addr)
  162. {
  163.         uchar i,temp;        
  164.         RST=1;                                        //啟動DS1302總線
  165.         //寫入目標地址:addr
  166.         addr = addr | 0x01;    //最低位 置高,寄存器0位為0時寫,為1時讀
  167.         for (i = 0; i < 8; i ++) {
  168.                 if (addr & 0x01)
  169.                 {
  170.                         IO=1;
  171.                         }
  172.                 else
  173.                 {
  174.                         IO=0;
  175.                         }
  176.                 SCK=1;          //產生時鐘
  177.                 SCK=0;
  178.                 addr = addr >> 1;        //右移1位
  179.                 }        
  180.         //輸出數據:temp
  181.         for (i = 0; i < 8; i ++)
  182.         {
  183.                 temp = temp >> 1;        //右移1位
  184.                 if (IO)                 
  185.                 {
  186.                         temp |= 0x80;  //temp=temp|0x80         
  187.                         }
  188.                 else {
  189.                         temp &= 0x7F;         //temp=temp&0x80        
  190.                         }
  191.                 SCK=1;         //產生時鐘
  192.                 SCK=0;
  193.                 }        
  194.         RST=0;                                        //停止DS1302總線
  195.         return temp;
  196. }
  197. //向DS1302寫入時鐘數據
  198. void ds1302_write_time()
  199. {
  200.         ds1302_write_byte(ds1302_control_add,0x00);                        //關閉寫保護
  201.         ds1302_write_byte(ds1302_sec_add,0x80);                                //暫停時鐘  
  202.         ds1302_write_byte(ds1302_year_add,time_buf[1]);                //年
  203.         ds1302_write_byte(ds1302_month_add,time_buf[2]);        //月
  204.         ds1302_write_byte(ds1302_date_add,time_buf[3]);                //日
  205.         ds1302_write_byte(ds1302_hr_add,time_buf[4]);     //時
  206.         ds1302_write_byte(ds1302_min_add,time_buf[5]);                //分
  207.         ds1302_write_byte(ds1302_sec_add,time_buf[6]);                //秒
  208.         ds1302_write_byte(ds1302_day_add,time_buf[7]);                //周
  209.         ds1302_write_byte(ds1302_control_add,0x80);                        //打開寫保護     
  210. }
  211. //從DS1302讀出時鐘數據
  212. void ds1302_read_time()  
  213. {
  214.         time_buf[1]=ds1302_read_byte(ds1302_year_add);                //年
  215.         time_buf[2]=ds1302_read_byte(ds1302_month_add);                //月
  216.         time_buf[3]=ds1302_read_byte(ds1302_date_add);                //日
  217.         time_buf[4]=ds1302_read_byte(ds1302_hr_add);                //時
  218.         time_buf[5]=(ds1302_read_byte(ds1302_min_add))&0x7f;//分
  219.         time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59
  220.         time_buf[7]=ds1302_read_byte(ds1302_day_add);                //周         
  221. }

  222. //////設置數據位置////////
  223. //用于將DS1302讀回的數據,進行折分,折分后放入全局變量數組dis_time_buf[]中,以便顯示調用
  224. void time_read_address (uchar *TUMP)
  225. {
  226.         uchar i,a;
  227.   ds1302_read_time();//讀回的數據放在全局變量  dis_time_buf[]數組中
  228.         for(a=0,i=0;i<14;i=i+2,a++)/////做循環,讓數據不斷追加在數組里
  229.         {
  230.                 dis_time_buf[i]=(time_buf[a]>>4);     //取高四位
  231.                 dis_time_buf[i+1]=(time_buf[a]&0x0f);  //取低四位
  232.         }
  233.         if(i==14)
  234.         {
  235.      dis_time_buf[i]=(time_buf[7]&0x07);  ///星期單字節
  236.         }

  237. ////////顯示位置////////////
  238.         LCD_set_xy(1,0);
  239.         LCD_Write_number(TUMP[0]);
  240.         LCD_Write_number(TUMP[1]);
  241.         LCD_set_xy(1,1);
  242.         LCD_Write_number(TUMP[2]);
  243.         LCD_Write_number(TUMP[3]);
  244.         LCD_set_xy(1,3);
  245.         LCD_Write_number(TUMP[4]);
  246.         LCD_Write_number(TUMP[5]);
  247.         LCD_set_xy(1,5);
  248.         LCD_Write_number(TUMP[6]);
  249.         LCD_Write_number(TUMP[7]);
  250.         LCD_set_xy(3,0);
  251.         LCD_Write_number(TUMP[8]);
  252.         LCD_Write_number(TUMP[9]);
  253.         LCD_set_xy(3,2);
  254.         LCD_Write_number(TUMP[10]);
  255.         LCD_Write_number(TUMP[11]);
  256.         LCD_set_xy(3,4);
  257.         LCD_Write_number(TUMP[12]);
  258.         LCD_Write_number(TUMP[13]);
  259.         LCD_set_xy(2,2);
  260.         LCD_Write_number(TUMP[14]);        
  261. }
  262. ////時間顯示位置//////
  263. void  xianshi()
  264. {
  265.         LCD_Write_string(1,0,"    年  月  日");
  266.         LCD_Write_string(2,0,"星期");
  267.         LCD_Write_string(3,0,"  時  分  秒");
  268. }

  269. ////主程序///////
  270. void main()
  271. {
  272.         Lcd_init(); //第一步LCD12864初始化
  273.   Clr_Scr(); //清屏
  274.   Delaynms(200);//延時為了穩定
  275.         ds1302_init();     //DS1302初始化
  276.   Delaynms(1000);//為了穩定必需加延時///
  277.   ds1302_write_time();    //向DS1302寫入初始年月時間值
  278.         xianshi();
  279.         while(1)
  280.         {
  281.                 time_read_address(dis_time_buf);
  282.                 if(k1==0)
  283.                 {time_read_address(dis_time_buf);}
  284.                 Delaynms(600);
  285.         }
  286. }
復制代碼

T0_arm.pdf

155.1 KB, 下載次數: 0

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

使用道具 舉報

沙發
ID:1133081 發表于 2025-5-5 06:25 | 只看該作者
你這個程序不完整,K1形同虛設。給你一個示例參考。 4位數碼管DS1302單鍵調時時鐘 DS18B20程序 仿真.rar (153.84 KB, 下載次數: 0)

回復

使用道具 舉報

板凳
ID:584814 發表于 2025-5-5 08:30 | 只看該作者
本壇找個ds1302時鐘的工程文件,里面詳細。
回復

使用道具 舉報

地板
ID:469589 發表于 2025-5-5 09:34 | 只看該作者
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。
回復

使用道具 舉報

5#
ID:1109793 發表于 2025-5-5 11:22 | 只看該作者
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

還需要停止?不是直接寫入就行嗎?
回復

使用道具 舉報

6#
ID:69038 發表于 2025-5-5 11:49 | 只看該作者
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

不需要停止。
是你在修改之前,
要先取得RTC的時間做為基數,
然后對這個基數修改,
改完后把這個基數寫入RTC中相應的地址就OK了。
回復

使用道具 舉報

7#
ID:1149524 發表于 2025-5-5 13:35 | 只看該作者
WL0123 發表于 2025-5-5 06:25
你這個程序不完整,K1形同虛設。給你一個示例參考。

非常感謝。
回復

使用道具 舉報

8#
ID:1149524 發表于 2025-5-5 13:35 | 只看該作者
man1234567 發表于 2025-5-5 08:30
本壇找個ds1302時鐘的工程文件,里面詳細。

非常感謝。
回復

使用道具 舉報

9#
ID:1149524 發表于 2025-5-5 13:36 | 只看該作者
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

是的,我主要是想搞懂,就是如何通過按鍵來調它的時間。的確可以通過代碼來改變初始的時間。。
回復

使用道具 舉報

10#
ID:1109793 發表于 2025-5-5 14:09 | 只看該作者
單片機初學者336 發表于 2025-5-5 13:36
是的,我主要是想搞懂,就是如何通過按鍵來調它的時間。的確可以通過代碼來改變初始的時間。。

把新數據放到對應變量,然后調用寫入函數寫入就OK了吧
至于新數據怎么來的,按鍵還是其他的渠道,都行
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久综合 | 免费观看一级毛片 | 精品久| 可以免费看的毛片 | 久久精品亚洲国产奇米99 | 欧美色视频免费 | 亚洲精久久| 国产精品大全 | 久久九九网站 | www亚洲精品 | 色视频网站 | 亚洲国产精品99久久久久久久久 | 龙珠z在线观看 | 蜜桃免费一区二区三区 | 亚洲精品一区二区 | 国产日批| 国产偷录叫床高潮录音 | 成人在线视 | 国产精品久久久久久久久久久久冷 | 精品永久 | 国产精品 欧美精品 | 亚洲大片 | 天堂在线中文字幕 | 视频一区二区在线观看 | 国产精品高清在线 | 国产精品日韩欧美一区二区三区 | 伊人久久免费 | 成人精品一区亚洲午夜久久久 | 特级做a爰片毛片免费看108 | 久久久久久国产精品 | 精品动漫一区 | 久久新视频 | 久草成人网 | 免费中文字幕 | 久久精品国产亚洲一区二区 | 日韩在线小视频 | 亚洲成人免费电影 | 特黄特色大片免费视频观看 | 国产精品一区二区久久久久 | 欧美v在线观看 | 亚洲最大的黄色网址 |