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

標題: ds1302是如何實現按鍵改時間的,能麻煩大佬看一下嗎? [打印本頁]

作者: 單片機初學者336    時間: 2025-5-4 15:20
標題: ds1302是如何實現按鍵改時間的,能麻煩大佬看一下嗎?
  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


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


作者: man1234567    時間: 2025-5-5 08:30
本壇找個ds1302時鐘的工程文件,里面詳細。
作者: GlenXu    時間: 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。
作者: xiaobendan001    時間: 2025-5-5 11:22
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

還需要停止?不是直接寫入就行嗎?
作者: zhuls    時間: 2025-5-5 11:49
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

不需要停止。
是你在修改之前,
要先取得RTC的時間做為基數,
然后對這個基數修改,
改完后把這個基數寫入RTC中相應的地址就OK了。
作者: 單片機初學者336    時間: 2025-5-5 13:35
WL0123 發表于 2025-5-5 06:25
你這個程序不完整,K1形同虛設。給你一個示例參考。

非常感謝。
作者: 單片機初學者336    時間: 2025-5-5 13:35
man1234567 發表于 2025-5-5 08:30
本壇找個ds1302時鐘的工程文件,里面詳細。

非常感謝。
作者: 單片機初學者336    時間: 2025-5-5 13:36
GlenXu 發表于 2025-5-5 09:34
你能啟動ds1302,就能知道怎么停止,好像修改前需要停止,然后修改、再啟動即可。

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

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




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 亚洲v区| 亚洲精品久久久久中文字幕欢迎你 | 成人免费三级电影 | 色婷婷国产精品综合在线观看 | 99久久电影 | 国产精品片 | 国产综合欧美 | 午夜久久久久久久久久一区二区 | 午夜精品久久久久久久久久久久 | 黑人巨大精品欧美黑白配亚洲 | 欧美一区二区三区在线 | 一级毛片大全免费播放 | 天天爽夜夜操 | 999久久精品 | 台湾佬久久 | 国产日韩一区二区 | 99热都是精品 | 日韩精品免费一区 | 这里精品 | 三级视频网站 | 美美女高清毛片视频免费观看 | 成人免费视频网站在线观看 | 91精品国产综合久久久久久丝袜 | www.色午夜.com | www.se91| 成人福利在线观看 | 国产在线视频三区 | 91玖玖 | 超碰97在线免费 | 亚洲精品一区在线观看 | 日本三级在线 | 国产精品久久久乱弄 | 伊人一区 | 中文一区 | 欧美激情第一区 | 久久精品欧美一区二区三区不卡 | 国产成人小视频 | 伊人久久精品一区二区三区 | 欧美成人精品一区二区三区 | 黄色大片免费播放 | 亚洲国产精品99久久久久久久久 |