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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

DS1302實時時鐘實驗程序 帶詳細注釋

[復制鏈接]
跳轉到指定樓層
樓主
ID:71259 發表于 2014-12-30 01:44 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include<reg52.h>        //包含單片機寄存器的頭文件
  2. #include<intrins.h>       //包含_nop_()的頭文件
  3. sbit RS=P2^0;            //LCD讀寫選擇位
  4. sbit RW=P2^1;    //LCD讀寫選擇位
  5. sbit E=P2^2;  //LCD使能端
  6. sbit BF=P0^7;        //忙信號
  7. sbit SCLK=P1^0;    //1302時鐘輸出端
  8. sbit DATA=P1^1;    //1302數據端
  9. sbit RST=P1^2;    //1302復位端
  10. unsigned char code digit[]="0123456789";
  11. /***************************
  12. 1ms基準延時
  13. ***************************/
  14. void delay1ms(unsigned int n)      
  15. {
  16. unsigned char i;
  17. while(n--)
  18.   for(i=0;i<115;i++);
  19. }
  20. /***************************
  21. 以下是DS1302模塊
  22. ***************************/

  23. /**************************
  24. 向1302寫一個字節
  25. **************************/
  26. void Write1302(unsigned char dat)
  27. {
  28. unsigned char i;

  29. SCLK=0;       //確保寫數據前SCLK為低電平
  30. _nop_();
  31. _nop_(); //給硬件反應時間
  32. for(i=0;i<8;i++){
  33.   DATA=dat&0x01; //取數據的最低位  低位在前,高位在后
  34.   _nop_();
  35.   _nop_();  //給硬件反應時間
  36.   SCLK=1;  //正跳變寫數據
  37.   _nop_();
  38.   _nop_();  //給硬件反應時間
  39.   SCLK=0;  //重新拉低SCLK,形成脈沖
  40.   dat>>=1;   //dat右移,為寫入下位數據做準備
  41. }
  42. }
  43. /**************************
  44. 根據命令字,向1302寫一個字節
  45. **************************/

  46. void WriteSet1302(unsigned char cmd, unsigned char dat)
  47. {
  48.   RST=0;          //禁止數據傳輸   .!!!這條很重要
  49.   SCLK=0;      //確保寫數據前SCLK為低電平
  50.   RST=1;  //開啟數據傳輸        
  51.   _nop_();
  52.   _nop_();
  53.   Write1302(cmd);
  54.   Write1302(dat);
  55.   SCLK=1;   // 將時鐘電平置于高電平狀態 ,處于已知狀態
  56.   RST=0;
  57. }
  58. /**************************
  59. 向1302讀一個字節
  60. **************************/

  61. unsigned char Read1302()
  62. {
  63. unsigned char i,dat=0;
  64. for(i=0;i<8;i++){
  65.   dat>>=1;
  66.   if(DATA==1)  //如果讀出的數據是1
  67.    dat|=0x80;   //將1取出,寫在dat的最高位
  68.   SCLK=1;      //將SCLK置于高電平,為下降沿讀出
  69.   _nop_();
  70.   _nop_();
  71.   SCLK=0;   //拉低SCLK,形成脈沖下降沿
  72. }
  73. return dat;
  74. }

  75. /**************************
  76. 根據命令字.向1302讀一個字節
  77. **************************/

  78. unsigned char ReadSet1302(unsigned char cmd)
  79. {
  80. unsigned char dat;
  81.     RST=0;    //這條很重要
  82. SCLK=0;   //確保寫數居前SCLK被拉低
  83. RST=1;    //啟動數據傳輸
  84. _nop_();
  85. _nop_();
  86. Write1302(cmd);  //寫入命令字
  87. dat=Read1302();   //讀出數據
  88. SCLK=1;     //將時鐘電平置于已知狀態
  89. RST=0;      //禁止數據傳遞
  90. return dat;    //將讀出的數據返回
  91. }
  92. /**************************
  93. 初始化1302
  94. **************************/

  95. void DS1302_Int()
  96. {

  97. WriteSet1302(0x8E,0x00);                 //根據寫狀態寄存器命令字,寫入不保護指令
  98.     WriteSet1302(0x80,((55/10)<<4|(55%10)));   //根據寫秒寄存器命令字,寫入秒的初始值
  99. WriteSet1302(0x82,((59/10)<<4|(59%10)));   //根據寫分寄存器命令字,寫入分的初始值
  100. WriteSet1302(0x84,((23/10)<<4|(23%10))); //根據寫小時寄存器命令字,寫入小時的初始值
  101. WriteSet1302(0x86,((18/10)<<4|(18%10))); //根據寫日寄存器命令字,寫入日的初始值
  102. WriteSet1302(0x88,((6/10)<<4|(6%10))); //根據寫月寄存器命令字,寫入月的初始值
  103. WriteSet1302(0x8c,((9/10)<<4|(9%10)));   //根據寫年寄存器命令字,寫入年的初始值
  104. WriteSet1302(0x90,0xa5);                //打開充電功能 選擇2K電阻充電方式
  105. WriteSet1302(0x8E,0x80);              //根據寫狀態寄存器命令字,寫入保護指令
  106. }




  107. /***************************
  108. 以下是液晶模塊
  109. ***************************/

  110. /***************************
  111. 忙信號檢測
  112. ***************************/

  113. bit BusyTest()
  114. {
  115. bit result;
  116. RS=0;   //根據規定,RS為低電平,RW為高電平時,可以讀狀態
  117. RW=1;
  118. E=1;
  119. _nop_();
  120. _nop_();
  121. result=BF;     //將忙碌標志電平賦給result
  122. E=0;     //將E恢復低電平
  123. _nop_();
  124. _nop_();
  125. return result;

  126. }

  127. /***************************
  128. 將模式設置指令或顯示地址送入LCD
  129. ***************************/

  130. void WriteInstruction(unsigned char dictate)
  131. {
  132. while(BusyTest()==1);     //如果忙就等待
  133. RS=0;      //根據規定,RS和R/W同時為低電平時,可以寫入指令
  134. RW=0;
  135. E=0;       //E置低電平(寫指令時,E為高脈沖,
  136.                            // 就是讓E從0到1發生正跳變,所以應先置"0"
  137. _nop_();
  138. _nop_();
  139. P0=dictate;
  140. _nop_();
  141. _nop_();
  142. _nop_();
  143. _nop_();
  144. E=1;     //E置高電平
  145. _nop_();
  146. _nop_();
  147. _nop_();
  148. _nop_();
  149. E=0;       //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  150. }


  151. /***************************
  152. 設定字符顯示位置
  153. ***************************/

  154. void WriteAddress(unsigned char x)
  155. {
  156.      WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
  157. }
  158. /***************************
  159. 向LCD寫數據
  160. ***************************/

  161. void WriteData(unsigned char dat)
  162. {
  163. while(BusyTest()==1);    //如果忙就等待
  164. RS=1;        //RS為高電平,RW為低電平時,可以寫入數據
  165. RW=0;
  166. E=0;        //E置低電平(寫指令時,E為高脈沖,
  167.                      // 就是讓E從0到1發生正跳變,所以應先置"0"
  168. _nop_();
  169. _nop_();
  170. P0=dat;     //將數據送入P0口,即將數據寫入液晶模塊
  171. _nop_();
  172. _nop_();
  173. _nop_();
  174. _nop_();
  175. E=1;       //E置高電平
  176. _nop_();
  177. _nop_();
  178. _nop_();
  179. _nop_();
  180. E=0;   //當E由高電平跳變成低電平時,液晶模塊開始執行命令
  181. }


  182. /***************************
  183. 初始化LCD
  184. ***************************/

  185. void LCD_Int()
  186. {
  187. delay1ms(15);      //延時15ms,首次寫指令時應給LCD一段較長的反應時間
  188. WriteInstruction(0x38);     //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
  189. delay1ms(5);
  190. WriteInstruction(0x38);
  191. delay1ms(5);
  192. WriteInstruction(0x38);
  193. delay1ms(5);     //連續三次,確保初始化成功
  194. WriteInstruction(0x0c);  //顯示模式設置:顯示開,無光標,光標不閃爍
  195. delay1ms(5);
  196. WriteInstruction(0x06);    //顯示模式設置:光標右移,字符不移
  197. delay1ms(5);
  198. WriteInstruction(0x01);     //清屏幕指令,將以前的顯示內容清除
  199. delay1ms(5);
  200. }


  201. /***************************
  202. 以下是1302的顯示程序
  203. ***************************/

  204. void DisplaySecond(unsigned char x)
  205. {
  206. unsigned char i,j;   //i,j分別儲存十位和個位
  207.     i=x/10;
  208. j=x%10;
  209. WriteAddress(0x49);
  210. WriteData(digit[i]);
  211. WriteData(digit[j]);
  212. delay1ms(15);
  213. }

  214. void DisplayMinute(unsigned char x)
  215. {
  216. unsigned char i,j;
  217.     i=x/10;
  218. j=x%10;
  219. WriteAddress(0x46);
  220. WriteData(digit[i]);
  221. WriteData(digit[j]);
  222. delay1ms(15);
  223. }

  224. void DisplayHour(unsigned char x)
  225. {
  226. unsigned char i,j;
  227.     i=x/10;
  228. j=x%10;
  229. WriteAddress(0x43);
  230. WriteData(digit[i]);
  231. WriteData(digit[j]);
  232. delay1ms(15);
  233. }

  234. void DisplayDay(unsigned char x)
  235. {
  236. unsigned char i,j;
  237.     i=x/10;
  238. j=x%10;
  239. WriteAddress(0x0c);
  240. WriteData(digit[i]);
  241. WriteData(digit[j]);
  242. delay1ms(15);
  243. }

  244. void DisplayMonth(unsigned char x)
  245. {
  246. unsigned char i,j;
  247.     i=x/10;
  248. j=x%10;
  249. WriteAddress(0x09);
  250. WriteData(digit[i]);
  251. WriteData(digit[j]);
  252. delay1ms(15);
  253. }

  254. void DisplayYear(unsigned char x)
  255. {
  256. unsigned char i,j;
  257.     i=x/10;
  258. j=x%10;
  259. WriteAddress(0x06);
  260. WriteData(digit[i]);
  261. WriteData(digit[j]);
  262. delay1ms(15);
  263. }

  264. /*******************************
  265. 主函數
  266. *******************************/

  267. void main()
  268. {
  269. unsigned char second,minute,hour,day,month,year;     //分別儲存苗、分、小時,日,月,年
  270. unsigned char ReadValue;        //儲存從1302讀取的數據
  271. LCD_Int();     //將液晶初始化
  272. WriteAddress(0x01);   //寫Date的顯示地址,將在第1行第2列開始顯示
  273. WriteData('D');
  274. WriteData('a');
  275. WriteData('t');
  276. WriteData('e');
  277. WriteData(':');
  278. WriteAddress(0x08);
  279. WriteData('-');
  280. WriteAddress(0x0b);
  281. WriteData('-');
  282. WriteAddress(0x45);
  283. WriteData(':');
  284. WriteAddress(0x48);
  285. WriteData(':');
  286. DS1302_Int();            //將1302初始化
  287. while(1){
  288.   ReadValue = ReadSet1302(0x81);   //從秒寄存器讀數據
  289.         second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//將讀出數據轉化
  290.      DisplaySecond(second);          //顯示秒
  291.      ReadValue = ReadSet1302(0x83);  //從分寄存器讀
  292.         minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數據轉化
  293.      DisplayMinute(minute);        //顯示分
  294.         ReadValue = ReadSet1302(0x85);  //從分寄存器讀
  295.         hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數據轉化
  296.      DisplayHour(hour);              //顯示小時
  297.         ReadValue = ReadSet1302(0x87);  //從分寄存器讀
  298.         day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數據轉化
  299.      DisplayDay(day);                //顯示日
  300.      ReadValue = ReadSet1302(0x89);  //從分寄存器讀
  301.         month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數據轉化
  302.      DisplayMonth(month);            //顯示月
  303.      ReadValue = ReadSet1302(0x8d);  //從分寄存器讀
  304.         year=((ReadValue&0xf0)>>4)*10 + (ReadValue&0x0F); //將讀出數據轉化
  305.      DisplayYear(year);              //顯示年
  306. }
  307. }

復制代碼


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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日一区二区 | 一区二区在线免费观看 | 国产丝袜av | 精品国产91久久久久久 | 国产精品久久一区二区三区 | 国产一级电影在线观看 | 国产精品高潮呻吟久久av黑人 | 爱操av | 日韩一区av | 国产成人福利在线 | 国产一级片 | 午夜精品在线 | 久草在线影 | 中文字幕一区二区三区在线观看 | 日韩三级免费观看 | 国产高清精品在线 | 在线视频一区二区三区 | 婷婷开心激情综合五月天 | 亚洲精品日韩精品 | 国产免费一区二区 | 日韩视频一区 | 精品日本久久久久久久久久 | 蜜月aⅴ免费一区二区三区 99re在线视频 | 欧美日韩国产在线观看 | 91一区二区三区在线观看 | 久久久久久精 | 成人黄色在线观看 | 91精品国产91久久久久久三级 | 做a网站| 九色网址| 亚洲精品av在线 | 97在线观视频免费观看 | 国产精品久久久久久久久久久久冷 | 日韩精品一区二区三区视频播放 | 国产精品日本一区二区不卡视频 | 不卡av电影在线播放 | 91久久精品国产 | 久草在线在线精品观看 | 日韩一区二区在线播放 | 亚洲天堂一区二区 | 中文字幕国产第一页 |