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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2685|回復: 3
收起左側

51單片機+DS1302+DS18B20制作(程序開源)

  [復制鏈接]
ID:61140 發表于 2022-5-8 14:01 | 顯示全部樓層 |閱讀模式
由于本程序使用了STC12C5A60S2單片機,最好不要使用太高的晶振,不然DS18B20延時部分太難調試(搞不好會顯示00.0度),一般12M以下相對好些.

制作出來的實物圖如下:
51hei圖片_20220508140028.jpg

單片機源程序如下:
  1. //******************************************************************************
  2. //LCD12864行地址地址定義                                          *
  3. //第一行地址:80H 81H 82H 83H 84H 85H 86H 87H          *
  4. //第二行地址:90H 91H 92H 93H 94H 95H 96H 97H          *
  5. //第三行地址:88H 89H 8AH 8BH 8CH 8DH 8EH 8FH          *
  6. //第四行地址:98H 99H 9AH 9BH 9CH 9DH 9EH 9FH          *
  7. //程序說明:本程序為帶有字庫漢字顯示的12864液晶顯示器源程序
  8. //****************************************************************
  9. //#include<stc12c5a60s2.h>表示頭文件在keil5軟件安裝目錄(根目錄)下,編譯時軟件到安裝目錄找頭文件。
  10. //#include"stc12c5a60s2.h"表示頭文件在當前的工程目錄下,如果找不到頭文件再到安裝目錄的根目錄找。
  11. //****************************************************************
  12. #include<stc12c5a60s2.h>           //載入STC12C5A60S2頭文件
  13. #include<intrins.h>                               //用到這個頭文件表示你可以在程序中調用單片機中庫文件中的函數
  14. #define uchar unsigned char            //用Uchar代替unsigned char
  15. #define uint  unsigned int         //用uint代替unsigned int  
  16. //****************************************************************
  17. //定義LCD12864的數據線和相關函數
  18. //****************************************************************  
  19. sbit   LCD_RS=P2^7;                  //模式位,低電平輸入指令,高電平輸入數據
  20. sbit   LCD_RW=P2^6;                  //讀寫位,低電平讀,高電平寫
  21. sbit   LCD_E =P2^5;                  //LCD12864使能位,低電平無效,高電平使能
  22. #define Busy 0x80
  23. #define LCD_Data P0                //LCD12864的8位數據總線,單片機的P0端口
  24. void   WriteDataLCD(unsigned char WDLCD);          //給LCD12864寫數據
  25. void   WriteCommandLCD(unsigned char WCLCD);       //給LCD12864寫指令
  26. void   LCDInit(void);                              //LCD12864初始化
  27. void   LCDClear(void);                             //LCD12864清屏
  28. void   CheckBusy(void);                            //忙檢測
  29. void   LCDSendWord(unsigned char *p);              //向LCD發送一個字符串
  30. void   LCDTestWord(bit i,unsigned char word);
  31. //****************************************************************
  32. //定義時間芯片DS1302的數據線及相關函數
  33. //****************************************************************
  34. void   DisplaySec(void);                           //在LCD上顯示秒鐘
  35. void   DisplayMin(void);                           //在LCD上顯示分鐘
  36. void   DisplayHour(void);                          //在LCD上顯示小時
  37. unsigned char sec,min,hour;                      //秒,分,小時
  38. sbit   DS1302_CLK=P2^0;                            //DS1302的時鐘信號線   
  39. sbit   DS1302_IO =P2^1;                            //DS1302的數據端口線
  40. sbit   DS1302_RST=P2^2;                            //DS1302的片選信號線
  41. void   WriteDs1302byte(unsigned char temp);                    //給DS1302寫一個字節
  42. void   WriteDs1302(unsigned char address,unsigned char dat);  //給DS1302寫入時間,先確定地址,再確定要寫入的數據
  43. unsigned char ReadDs1302(unsigned char address);           //讀取DS1302的數據
  44. void   InitDS1302();
  45. //****************************************************************
  46. //定義溫度傳感器DS18B20的數據線和相關函數
  47. //****************************************************************
  48. sbit   DS18B20=P1^2;                        //DS18B20的數據線
  49. int    temp;
  50. void   DS18B20Init(void);                   //DS18B20初始化函數
  51. int    GetTemp(void);
  52. void   TempWriteByte(unsigned char dat);
  53. unsigned char TempRead(void);
  54. bit    TempReadBit(void);   
  55. void   TempChange(void);
  56. //****************************************************************
  57. //定義延時部分相關函數
  58. //****************************************************************
  59. void   delayb(unsigned int count);
  60. void   DelayMs(unsigned int a);
  61. void   Delay(unsigned char num);
  62. //****************************************************************
  63. //定義開關按鍵的端口
  64. //****************************************************************
  65. sbit   Key1    =P1^4;       //按鍵功能:設置(本程序未使用按鍵)
  66. sbit   Key2    =P1^5;       //按鍵功能:確認(本程序未使用按鍵)
  67. sbit   Key3    =P1^6;       //按鍵功能:加        (本程序未使用按鍵)
  68. sbit   Key4    =P1^7;       //按鍵功能:左移(本程序未使用按鍵)
  69. void   Key(void);
  70. //****************************************************************
  71. //定義提示音樂部分相關函數
  72. //****************************************************************
  73. #define Fosc 6000000      //定義晶振頻率24000000HZ
  74. sbit    Speaker=P3^7;         //定義輸出管腳

  75. void SpeakerDiDi(void)
  76. {
  77. unsigned char i;  //整點報時延時
  78. for(i=0;i<3;i++)
  79. {
  80.   Speaker=0;
  81.   DelayMs(800);
  82.   Speaker=1;
  83.   DelayMs(800);
  84. }
  85. DelayMs(4000);
  86. for(i=0;i<3;i++)
  87. {
  88.   Speaker=0;
  89.   DelayMs(800);
  90.   Speaker=1;
  91.   DelayMs(800);
  92. }
  93. DelayMs(4000);
  94. for(i=0;i<2;i++)
  95. {
  96.   Speaker=0;
  97.   DelayMs(4000);
  98.   Speaker=1;
  99.   DelayMs(1000);
  100. }
  101. }


  102. /******************忙檢測函數***************/
  103. void CheckBusy(void)
  104. {
  105. LCD_RS=0;
  106. LCD_RW=1;
  107. LCD_E=1;
  108. LCD_Data=0xff;
  109. while((LCD_Data&0x80)==0x80);
  110. LCD_E=0;
  111. }

  112. /**********************給LCD寫入數據*****************/
  113. void WriteDataLCD(unsigned char WDLCD)
  114. {
  115.   CheckBusy();               //檢測忙
  116.   LCD_RS = 1;                //RS為高電平,DB7----DB0為數據      
  117.   LCD_RW = 0;                //RW為低電平,E從高電平到低電平,則是把DB7----DB0的數據寫到DR或者IR
  118.   LCD_E = 1;
  119.   LCD_Data = WDLCD;          //傳送數據WDLCD
  120.   Delay(40);
  121.   LCD_E = 0;                 //E從 高電平 到 低電平
  122.   Delay(40);
  123. }

  124. /******************給LCD寫入指令**********************/
  125. void WriteCommandLCD(unsigned char WCLCD) //BuysC為0時忽略忙檢測
  126. {
  127.   CheckBusy();                //檢測忙
  128.   LCD_RS = 0;                 //RS為低,DB7----DB0為指令
  129.   LCD_RW = 0;                 //RW為低,E從高電平到低電平,則是把DB7----DB0的數據寫到DR或者IR
  130.   LCD_E = 1;
  131.   LCD_Data = WCLCD;           //傳送數據
  132.   Delay(40);
  133.   LCD_E = 0;                  //E從 高電平到低電平
  134.   Delay(40);
  135. }

  136. /***************LCD初始化******************/

  137. void LCDInit(void)
  138. {
  139.   WriteCommandLCD(0x30);     //顯示模式設置,開始要求每次檢測忙信號
  140.   WriteCommandLCD(0x01);     //顯示清屏
  141.   WriteCommandLCD(0x06);     // 顯示光標移動設置
  142.   WriteCommandLCD(0x0C);     // 顯示開,無游標,不反白
  143. }

  144. /********************清屏***************************/
  145. void LCDClear(void)
  146. {
  147.   WriteCommandLCD(0x01);     //顯示清屏
  148.   WriteCommandLCD(0x34);     // 顯示光標移動設置
  149.   WriteCommandLCD(0x30);     // 顯示開及光標設置
  150. }

  151. void LCDSendWord(unsigned char *p)         //向LCD發送一個字符串,
  152. {
  153. while(*p>0)                            //比如void LCDSendWord('你好');就是讓LCD顯示"你好"
  154. {
  155.   WriteDataLCD(*p);
  156.   p++;
  157. }
  158. }
  159.   
  160. /************寫數據或者指令***************/
  161. void LCDTestWord(bit i,unsigned char word)
  162. {
  163. if(i==0)
  164. {
  165.   WriteCommandLCD(word);             //i=0;則寫入指令
  166. }
  167. else
  168. {
  169.   WriteDataLCD(word);                //i=1;則寫入數據  
  170. }
  171. }

  172. void Displayqt(void)
  173. {
  174. LCDTestWord(0,0x80);
  175. LCDSendWord("如果你還在!");
  176. }

  177. void DisplayHour(void)                 //往LCD上填寫小時數據
  178. {
  179. hour=ReadDs1302(0x85);
  180. LCDTestWord(0,0x98);
  181. LCDTestWord(1,(hour/16)+0x30);
  182. LCDTestWord(1,hour%16+0x30);
  183. }

  184. void DisplayMin(void)                  //往LCD上填寫分鐘數據   
  185. {
  186. min=ReadDs1302(0x83);
  187. LCDTestWord(0,0x99);
  188. LCDTestWord(1,0x3a);
  189. LCDTestWord(1,(min/16)+0x30);
  190. LCDTestWord(1,min%16+0x30);
  191. LCDTestWord(1,0x3a);
  192. }

  193. void DisplaySec(void)                  //往LCD上填寫秒鐘數據
  194. {
  195. unsigned char i=0;
  196. unsigned int a=0,b=0,c=0;
  197. sec=ReadDs1302(0x81);
  198. LCDTestWord(0,0x9b);
  199. LCDTestWord(1,(sec/16)+0x30);
  200. LCDTestWord(1,sec%16+0x30);
  201. }

  202. void DisplayTemp(void)
  203. {
  204. unsigned int i;
  205. unsigned char a,b,c;
  206. WriteCommandLCD(0x9c);
  207. LCDTestWord(0,0x9d);
  208. TempChange();
  209. i=GetTemp();
  210. a=i/100;
  211. LCDTestWord(1,a+0x30);
  212. b=i/10-a*10;
  213. LCDTestWord(1,b+0x30);
  214. LCDTestWord(1,0x2e);
  215. c=i-a*100-b*10;
  216. LCDTestWord(1,c+0x30);
  217. LCDSendWord("度");
  218. }

  219. //****************************************************************
  220. //DS1302部分子程序
  221. //****************************************************************
  222. /*********************寫入操作*********************/
  223. void WriteDs1302Byte(unsigned  char temp)        
  224. {
  225.     unsigned char i;
  226.     for (i=0;i<8;i++)               //循環8次 寫入數據
  227.     {
  228.         DS1302_CLK=0;
  229.         DS1302_IO=temp&0x01;      //每次傳輸低字節
  230.         temp>>=1;                //右移一位
  231.         DS1302_CLK=1;
  232.    }
  233. }

  234. /*********************寫入數據*******************/
  235. void WriteDs1302( unsigned char address,unsigned char dat )     //先寫地址,再寫數據
  236. {
  237.   DS1302_RST=0;
  238. _nop_();
  239.   DS1302_CLK=0;
  240. _nop_();
  241.   DS1302_RST=1;
  242.     _nop_();                             //啟動
  243.   WriteDs1302Byte(address);              //發送地址
  244.   WriteDs1302Byte(dat);                  //發送數據
  245.   DS1302_RST=0;                          //恢復
  246. }

  247. /************************************************/
  248. unsigned char ReadDs1302(unsigned char address)        //先送地址,再讀數據
  249. {
  250.   unsigned char i,temp=0x00;
  251.   DS1302_RST=0;
  252. _nop_();
  253.   DS1302_CLK=0;
  254. _nop_();
  255.   DS1302_RST=1;
  256. _nop_();
  257.   WriteDs1302Byte(address);         //送地址函數
  258.   for (i=0;i<8;i++)               //循環8次 讀取數據
  259.   {
  260.   DS1302_CLK=1;
  261.   _nop_();
  262.    if(DS1302_IO)
  263.    temp|=0x80;               //每次傳輸低字節
  264.   DS1302_CLK=0;
  265.   temp>>=1;               //右移一位
  266. }
  267.   DS1302_RST=0;
  268. _nop_();  
  269. DS1302_CLK=1;
  270. DS1302_IO=0;
  271. return (temp);              //返回
  272. }
  273. /*****************DS1302初始化********************/
  274. void InitDS1302()                        //DS1302中秒,分,時,日期,月份,星期,年的地址分別是0x80,0x82,0x84,0x86,0x88,0x8a,0x8c
  275. {                                        //初始化寫入的時間是2010年4月1日15點整,星期六
  276. WriteDs1302(0x8e,0x00);                 //控制命令,WP位為0,允許寫操作  控制位地址是0x8e
  277. DelayMs(5);                           
  278. WriteDs1302(0x84,0x00);                 //寫入小時 20點
  279. DelayMs(5);
  280. WriteDs1302(0x82,0x00);                 //寫入分鐘 03分
  281. DelayMs(5);
  282. WriteDs1302(0x80,0x00);                 //寫入秒鐘 00秒
  283. DelayMs(5);                                 
  284. WriteDs1302(0x8e,0x80);                 //控制命令,WP為1,禁止寫操作
  285. }
  286. //****************************************************************
  287. //DS18B20部分子程序
  288. //****************************************************************
  289. void DS18B20Init(void)          //DS18B20初始化
  290. {
  291. unsigned int i;               
  292. DS18B20=0;
  293. i=103*8;
  294. while(i>0)i--;
  295. DS18B20=1;
  296. i=103;
  297. while(i>0)i--;
  298. }

  299. bit TempReadBit(void)          // 讀一位
  300. {
  301. unsigned int i;
  302.     bit dat;
  303.     DS18B20=0;i++;             //小延時一下
  304.     DS18B20=1;i++;i++;
  305.     dat=DS18B20;
  306.     i=32;while(i>0)i--;
  307.     return (dat);
  308. }

  309. unsigned char TempRead(void)   //讀一個字節
  310. {
  311. unsigned char i,j,dat;
  312.     dat=0;
  313.     for(i=1;i<=8;i++)
  314.     {
  315.      j=TempReadBit();
  316.      dat=(j<<7)|(dat>>1); //讀出的數據最低位在最前面,這樣剛好一個字節在DAT里
  317.     }
  318.     return(dat);             //將一個字節數據返回
  319. }

  320. void TempWriteByte(unsigned char dat)  
  321. {                           //寫一個字節到DS18B20里
  322. unsigned int i;
  323.     unsigned char j;
  324.     bit testb;
  325.     for(j=1;j<=8;j++)
  326.     {
  327.      testb=dat&0x01;
  328.      dat=dat>>1;
  329.      if(testb)          // 寫1部分
  330.      {
  331.          DS18B20=0;
  332.          i++;i++;
  333.          DS18B20=1;
  334.          i=32;while(i>0)i--;
  335.         }
  336.      else
  337.      {
  338.          DS18B20=0;       //寫0部分
  339.          i=32;while(i>0)i--;
  340.          DS18B20=1;
  341.          i++;i++;
  342.         }
  343.     }
  344. }

  345. void TempChange(void)  //發送溫度轉換命令
  346. {
  347. DS18B20Init();             //初始化DS18B20
  348.     delayb(8);             //延時
  349.     TempWriteByte(0xcc);  // 跳過序列號命令
  350.     TempWriteByte(0x44);  //發送溫度轉換命令
  351. }

  352. int GetTemp()               //獲得溫度
  353. {
  354. float tt;
  355.     unsigned char a,b;
  356.     DS18B20Init();
  357.     delayb(1);
  358.     TempWriteByte(0xcc);
  359.     TempWriteByte(0xbe);    //發送讀取數據命令
  360.     a=TempRead();           //連續讀兩個字節數據
  361.     b=TempRead();
  362.     temp=b;
  363.     temp<<=8;            
  364.     temp=temp|a;            //兩字節合成一個整型變量。
  365.     tt=temp*0.0625;         //得到真實十進制溫度值,因為DS18B20 可以精確到0.0625度,所以讀回數據的最低位代表的是0.0625度。                     
  366.     temp=tt*10+0.5;         //放大十倍,這樣做的目的將小數點后第一位 也轉換為可顯示數字,同時進行一個四舍五入操作。                          
  367.     return temp;            //返回溫度值
  368. }
  369. /****************************************************************************/
  370. void UpDate(void)
  371. {
  372. DS18B20=1;
  373. DisplayHour();             //顯示時
  374. DisplayMin();              //顯示分
  375. DisplaySec();              //顯示秒
  376. DisplayTemp();                         //顯示溫度
  377. }

  378. //****************************************************************
  379. //延時部分子程序
  380. //****************************************************************
  381. void delayb(unsigned int count)   //delay
  382. {
  383.     unsigned char i;
  384.     while(count)
  385.     {
  386.        i=200;
  387.        while(i>0)
  388.        i--;
  389.        count--;
  390.     }
  391. }

  392. void DelayMs(unsigned int a)        //延時 1MS/次
  393. {
  394. unsigned char i;
  395. while(--a!=0)
  396. {
  397.   for(i=0;i<125;i++)
  398.   ;
  399. }
  400. }

  401. void Delay(unsigned char num)               
  402. {
  403. while(num--)
  404. ;
  405. }                                          


  406. void main()
  407. {
  408. LCDInit();
  409. LCDClear();
  410. InitDS1302();
  411. while(1)                        
  412. {
  413.   Displayqt();
  414.   UpDate();
  415.   }
  416. }
復制代碼




評分

參與人數 2黑幣 +61 收起 理由
gqzjl + 11 共享資料的黑幣獎勵!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:61140 發表于 2022-5-8 15:44 | 顯示全部樓層
本程序已實測無BUG,若溫度不顯示,要按你的晶振來調DS18B20讀寫部分的延時,本程序使用STC12C5A60S2單片機和6M晶振實測
回復

使用道具 舉報

ID:61140 發表于 2022-6-3 04:06 | 顯示全部樓層
無事再來頂一下
回復

使用道具 舉報

ID:1027942 發表于 2022-9-19 21:31 | 顯示全部樓層
我用串口顯示秒,部分出現了亂碼,是什么原因,開始時間為0秒
unsigned int ReadTime()      //接收并且轉換為十進制
{
        dat = ReadDs1302(0x81) ;
       
        damp = (int)dat / 16*10 + (int)dat %16;
       
        return damp;
}
void main()
{
                uart_init();       
                SetTime();       //設置開始時間

        while(1)
        {               
                sec = ReadTime();
               
                printf("%d        ",sec);
                Delay100ms(10);
        }       
}
例如: 1        0        3        0        1        2        7        0        1        0        1        0        3        0        1        2        7        8        9        0        1        0        3        0        1        2        7        0        1        10        11        8        13        8        9        10        17        18        19        0        1        0       
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91.com视频 | 午夜视频在线视频 | 亚洲欧洲色视频 | 久久av一区二区三区 | www.天天操 | 亚洲免费人成在线视频观看 | 久久黄网 | 91在线综合 | 久久久精品一区 | 91在线影院| 毛片免费视频 | 午夜精品导航 | 91在线观看 | 91久久久久久久久久久久久 | 麻豆精品国产91久久久久久 | 亚洲一二三区精品 | 天天做日日做 | 91精品国产色综合久久不卡98口 | 国产91黄色 | 在线播放一区 | 国产高清免费视频 | 神马影院一区二区三区 | 久久成人免费 | 国产a区 | 91久久夜色 | 97色伦网 | www日韩 | 成人h动漫精品一区二区器材 | a黄视频 | 国产麻豆乱码精品一区二区三区 | 日韩国产中文字幕 | aaaaaaa片毛片免费观看 | 久久这里只有精品首页 | 少妇无套高潮一二三区 | 日韩一级免费电影 | 美国黄色毛片 | 久久福利 | 国产成人精品在线播放 | 久草资源在线视频 | 国产精品久久久久aaaa樱花 | 一级女毛片|