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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

DS3231溫度讀取實驗 附單片機源程序

  [復制鏈接]
跳轉到指定樓層
樓主
本帖最后由 凌凈清河 于 2019-2-13 19:46 編輯

DS3231作為一個走時精準的RTC芯片,內部帶有溫度補償電路,此例將讀取其中11H和12H寄存器,提取測得的溫度值并傳送到串口輸出。

類似程序網上非常之多,不再贅述,在此重新提說幾處需要注意的地方。
1.根據DS3231的芯片手冊,其溫度傳感器的精度為±3℃,畢竟不是專用的溫度傳感器,在使用中可以作為一個參考,且僅此而已。
2.根據DS3231的芯片手冊,其溫度分辨率為±0.25℃,所以其小數部分讀出的值只能是.00、.25、.50、.75這四種,如果讀出的值不是這四種,則數據處理有誤。
3.本實驗使用一個float型數據直接接收了轉換的溫度值,沒有對補碼的符號位進行判斷等。

注明:本程序沒有使用CONV位進行強制轉換,但是實際上溫度值的刷新速度還是很令人滿意(用手按住芯片,溫度值更改速度很快,下面的測試圖片是恒溫下檢測的,故無變化)。
測試程序:
  1. #include<STC15.H>
  2. #include"stdio.h"
  3. #include<intrins.h>
  4. //位定義
  5. sbit DS3231_SDA=P3^3;
  6. sbit DS3231_SCL=P3^2;

  7. //運行數組
  8. unsigned char DS3231_Time_Buffer[7]={0x00,0x48,0x11,0x02,0x12,0x02,0x19};
  9. unsigned char temp[2]={0,0};
  10. char buf[20]={0};
  11. //運行標志位
  12. bit busy=0;
  13. //運行變量
  14. float v;

  15. /*##############################################################################
  16. 編寫/測試:凌凈清河
  17. 日期:2019年2月12日
  18. 測試平臺:IAP15W4K58S4

  19. 鳴謝:DS3231部分驅動函數借用了51黑論壇上某位的程序,但是時間太久忘記是誰的了。
  20. 并未修改原作者的寫法,如果原作者認出,鄙人在此表示感謝,或可聯系我提名。
  21. ##############################################################################*/

  22. /*###################以下為給DS3231定義的IIC通信函數################*/
  23. void DS3231_Delay()//使用空操作進行短暫的延時
  24. {
  25.         _nop_();
  26.         _nop_();
  27.         _nop_();
  28.         _nop_();
  29. }

  30. void DS3231_IIC_Start()//IIC總線的開始信號
  31. {
  32.         DS3231_SCL=1;
  33.         DS3231_SDA=1;
  34.         DS3231_Delay();
  35.         DS3231_SDA=0;
  36.         DS3231_Delay();
  37.         DS3231_SCL=0;
  38. }

  39. void DS3231_IIC_Stop()//IIC總線的停止信號
  40. {
  41.         DS3231_SCL=0;
  42.         DS3231_SDA=0;
  43.         DS3231_Delay();
  44.         DS3231_SCL=1;
  45.         DS3231_Delay();
  46.         DS3231_SDA=1;
  47.         DS3231_Delay();
  48. }

  49. bit DS3231_IIC_Send_Byte(unsigned char dat)//寫操作
  50. {
  51.         unsigned char mask;//定義一個掩碼用于進行按位發送數據的操作
  52.         bit ack;

  53.         for(mask=0x80;mask!=0;mask>>=1)
  54.         {
  55.                 if((mask&dat)==0)
  56.                         DS3231_SDA=0;
  57.                 else
  58.                         DS3231_SDA=1;
  59.                 DS3231_Delay();
  60.                 DS3231_SCL=1;
  61.                 DS3231_Delay();
  62.                 DS3231_SCL=0;
  63.         }
  64.         DS3231_SDA=1;
  65.         DS3231_Delay();
  66.         DS3231_SCL=1;
  67.         ack=DS3231_SDA;
  68.         DS3231_Delay();
  69.         DS3231_SCL=0;

  70.         return (~ack);
  71. }

  72. unsigned char DS3231_IIC_Read_Byte_NAK()//讀操作+非應答
  73. {
  74.         unsigned char mask;//定義一個用于累加的位存儲臨時變量
  75.         unsigned char dat;

  76.         DS3231_SDA=1;
  77.         for(mask=0x80;mask!=0;mask>>=1)
  78.         {
  79.                 DS3231_Delay();
  80.                 DS3231_SCL=1;
  81.                 if(DS3231_SDA==0)
  82.                         dat&=~mask;
  83.                 else
  84.                         dat|=mask;
  85.                 DS3231_Delay();
  86.                 DS3231_SCL=0;
  87.         }
  88.         DS3231_SDA=1;
  89.         DS3231_Delay();
  90.         DS3231_SCL=1;
  91.         DS3231_Delay();
  92.         DS3231_SCL=0;

  93.         return dat;
  94. }

  95. unsigned char DS3231_IIC_Read_Byte_ACK()//讀操作+應答
  96. {
  97.         unsigned char mask;//定義一個用于累加的位存儲臨時變量
  98.         unsigned char dat;

  99.         DS3231_SDA=1;
  100.         for(mask=0x80;mask!=0;mask>>=1)
  101.         {
  102.                 DS3231_Delay();
  103.                 DS3231_SCL=1;
  104.                 if(DS3231_SDA==0)
  105.                         dat&=~mask;
  106.                 else
  107.                         dat|=mask;
  108.                 DS3231_Delay();
  109.                 DS3231_SCL=0;
  110.         }
  111.         DS3231_SDA=0;
  112.         DS3231_Delay();
  113.         DS3231_SCL=1;
  114.         DS3231_Delay();
  115.         DS3231_SCL=0;

  116.         return dat;
  117. }
  118. /*#################以下為給DS3231封裝的寄存器通信函數###############*/

  119. void DS3231_Read_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//讀EEPROM中多個字節
  120. {
  121.         do{
  122.                 DS3231_IIC_Start();
  123.                 if(DS3231_IIC_Send_Byte(0xD0))
  124.                 {
  125.                         break;
  126.                 }
  127.                 DS3231_IIC_Stop();
  128.           }while(1);
  129.         DS3231_IIC_Send_Byte(addr);
  130.         DS3231_IIC_Start();
  131.         DS3231_IIC_Send_Byte((0xD0)|0x01);//尋址,讀操作
  132.         while(len>1)
  133.         {
  134.                 *buf++=DS3231_IIC_Read_Byte_ACK();
  135.                 len--;
  136.         }
  137.         *buf=DS3231_IIC_Read_Byte_NAK();//讀一個字節
  138.         DS3231_IIC_Stop();
  139. }

  140. void DS3231_Write_Registers(unsigned char *buf,unsigned char addr,unsigned char len)//寫寄存器,傳入待寫入數組
  141. {
  142.         while(len>0)
  143.         {        
  144.                 do{
  145.                         DS3231_IIC_Start();
  146.                         if(DS3231_IIC_Send_Byte(0xD0))
  147.                         {
  148.                                 break;
  149.                         }
  150.                         DS3231_IIC_Stop();
  151.                   }while(1);

  152.                 DS3231_IIC_Send_Byte(addr);
  153.                 while(len>0)
  154.                 {
  155.                         DS3231_IIC_Send_Byte(*buf++);
  156.                         len--;
  157.                         addr++;
  158.                         if((addr&0x07)==0)
  159.                         {
  160.                                 break;
  161.                         }
  162.                 }
  163.                 DS3231_IIC_Stop();
  164.         }
  165. }

  166. void SendData(unsigned char dat)//串口1發送一個字節數據
  167. {
  168.         while(busy);
  169.         busy=1;
  170.         SBUF=dat;
  171. }

  172. void SendString(char *p)//串口發送一個字符串
  173. {
  174.         while(*p!='\0')
  175.         {
  176.                 SendData(*p);
  177.                 p++;
  178.         }
  179. }

  180. void UartInit(void)                //9600bps@11.0592MHz
  181. {
  182.         SCON = 0x50;                //8位數據,可變波特率
  183.         AUXR |= 0x40;                //定時器1時鐘為Fosc,即1T
  184.         AUXR &= 0xFE;                //串口1選擇定時器1為波特率發生器
  185.         TMOD &= 0x0F;                //設定定時器1為16位自動重裝方式
  186.         TL1 = 0xE0;                //設定定時初值
  187.         TH1 = 0xFE;                //設定定時初值
  188.         ET1 = 0;                //禁止定時器1中斷
  189.         TR1 = 1;                //啟動定時器1
  190. }

  191. void delay(unsigned long int i)//延時函數
  192. {
  193.         while(i--);
  194. }

  195. void main()
  196. {
  197.         P3M1=0x00;
  198.         P3M0=0x00;//IO初始化,這個準雙向的初始化操作是為STC15W4K32S4系列單片機特別準備的
  199.         UartInit();//串口初始化
  200.         EA=1;//開總中斷
  201.         ES=1;//開串口中斷
  202.         DS3231_Write_Registers(DS3231_Time_Buffer,0x00,7);//向器件寫入有效的IIC地址,以保證驅動振蕩器起振,防止讀出初始值0℃
  203.         while(1)
  204.         {
  205.                 DS3231_Read_Registers(temp,0x11,2);
  206.                 v=temp[0]*1.0+(temp[1]>>6)*0.25;//按照數據格式,將寄存器中的值放入一個有符號的float型數據,就不必糾結于補碼的正負判別和轉換了
  207.                 sprintf(buf,"溫度值為:%6.2f",v);//字符串拼接輸出,用于串口觀察數據
  208.                 SendString(buf);//發送組合好的字符串
  209.                 delay(100000);//延時等待,以防止串口信息爆炸>v<
  210.         }
  211. }

  212. void UART() interrupt 4//串口中斷服務函數
  213. {
  214.         if(RI)//接收標志位(未使用)
  215.         {
  216.                 RI=0;
  217.         }
  218.         
  219.         if(TI)//發送標志位
  220.         {
  221.                 TI=0;
  222.                 busy=0;
  223.         }
  224. }
復制代碼


測試時的截圖:

測試中,對比室內的酒精溫度計,該轉換值偏大了約1.75℃

相關文件如下:
【測試工程】:工程中的延時函數形參編寫時出了一個小紕漏,應該改成ulong型,并更改相應實參值
DS3231溫度讀取 凌凈清河.zip (99.37 KB, 下載次數: 116)
【DS3231英文手冊】:英文手冊比中文的在某些細節描述更詳盡
DS3231.pdf (361.01 KB, 下載次數: 36)
【DS3231中文手冊】
DS3231中文手冊.pdf (449.27 KB, 下載次數: 85)

下載注明:可以回復本帖得到黑幣補貼(評分),本人現在最高能給15黑幣/帖,多次回復亦有補貼。


評分

參與人數 3黑幣 +70 收起 理由
NPC-1024 + 5 凌:由于站點對評分機制的修改,帖子不再給.
tieq1952 + 15 贊一個!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:253767 發表于 2019-2-13 08:00 | 只看該作者
謝謝分享!!!

評分

參與人數 1黑幣 +15 收起 理由
凌凈清河 + 15 黑幣補貼

查看全部評分

回復

使用道具 舉報

板凳
ID:448212 發表于 2019-5-19 14:12 | 只看該作者
感謝!!學習了!
回復

使用道具 舉報

地板
ID:184096 發表于 2019-5-20 12:12 | 只看該作者
感謝了樓主 學到了
回復

使用道具 舉報

5#
ID:581125 發表于 2019-7-9 18:40 | 只看該作者
很強很強很強學到了感謝樓主
回復

使用道具 舉報

6#
ID:483407 發表于 2019-7-9 21:45 | 只看該作者
串口助手用得不錯,學習了。
回復

使用道具 舉報

7#
ID:585103 發表于 2019-7-16 14:42 | 只看該作者
謝謝分享。
回復

使用道具 舉報

8#
ID:585374 發表于 2019-7-16 20:55 | 只看該作者
謝謝分享
回復

使用道具 舉報

9#
ID:371527 發表于 2019-7-19 09:25 | 只看該作者
多字節操作子程序清晰,讀取溫度運算的方式比其它判符號程序簡潔
回復

使用道具 舉報

10#
ID:111376 發表于 2019-8-13 11:02 | 只看該作者
感謝樓主的無私奉獻精神
回復

使用道具 舉報

11#
ID:91162 發表于 2019-12-22 16:01 | 只看該作者
正想做一個精準時鐘,謝謝樓主分享
回復

使用道具 舉報

12#
ID:4306 發表于 2020-1-18 20:47 | 只看該作者
正在學習中,謝謝
回復

使用道具 舉報

13#
ID:138937 發表于 2020-6-19 14:45 | 只看該作者

謝謝分享。
回復

使用道具 舉報

14#
ID:702127 發表于 2020-8-4 07:36 | 只看該作者
剛弄好DS3231的時間,最近在弄溫度,總是出錯,看了你的貼子,嗯,找到錯誤原因了,感謝
回復

使用道具 舉報

15#
ID:491923 發表于 2021-1-3 11:37 | 只看該作者
剛剛買了1個模塊,正在學習使用中,這個資料太有用了 謝謝樓主分享
回復

使用道具 舉報

16#
ID:90970 發表于 2021-4-15 13:26 | 只看該作者
看看這個溫度是不是能用
回復

使用道具 舉報

17#
ID:884042 發表于 2021-7-16 14:24 | 只看該作者
樓主,我是直接讀取11H和12H這兩個寄存器的值然后顯示到屏幕上,在顯示小數點的,照樣用,應該不要建變量吧?
回復

使用道具 舉報

18#
ID:884042 發表于 2021-7-16 14:26 | 只看該作者
我是這樣寫的:
OLED_P8x16(0,6,DS3231Time[7]/10);
          OLED_P8x16(8,6,DS3231Time[7]%10);
我通過溫度讀取函數直接將溫度值顯示在OLED屏幕上的
回復

使用道具 舉報

19#
ID:972563 發表于 2021-11-19 11:18 | 只看該作者
ds3231的溫度可是有點不靠譜,畢竟手冊上也是正負3度的誤差,3度的誤差不小了,沒辦法只能改用DS18B20
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩视频精品 | 97久久精品午夜一区二区 | 久久国产精品-国产精品 | caoporn国产精品免费公开 | 国产精彩视频 | 天天操网 | 不卡一区二区在线观看 | 亚洲一区 中文字幕 | 一区二区三区亚洲精品国 | 久久久久久久久久久蜜桃 | 欧美另类视频 | 日本字幕在线观看 | 久久r免费视频 | 欧州一区二区三区 | 91在线视频观看 | 99久久久无码国产精品 | 久久久视频在线 | 国内精品视频在线观看 | av在线免费播放 | 懂色中文一区二区在线播放 | 久久爆操 | 亚洲精品免费视频 | 欧美久久一级特黄毛片 | 成人国产在线观看 | 欧美激情久久久 | 国产美女在线观看 | 国产精品免费av | 夜夜艹 | 电影在线 | 久久久久久国产精品免费免费 | 精品毛片 | 综合亚洲视频 | 欧美日韩国产一区二区 | 91精品国产综合久久婷婷香蕉 | 国产1区 | 亚洲精品一区二区 | 精品美女在线观看视频在线观看 | 91在线精品秘密一区二区 | 欧美在线一级 | 一区二区三区四区视频 | 亚洲色图图片 |