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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4044|回復(fù): 0
收起左側(cè)

基于STM32自碼 DS18B20驅(qū)動程序

[復(fù)制鏈接]
ID:267624 發(fā)表于 2017-12-27 12:23 | 顯示全部樓層 |閱讀模式
為了加深對于底層驅(qū)動開發(fā)的認(rèn)識和理解,樓主決定自擼常見模塊,傳感器的驅(qū)動程序。-------立貼為證。
DS18B20是一款單總線可編程分辨率的數(shù)字溫度計(jì),詳細(xì)內(nèi)容可見中英文datasheet,筆者不在贅述。
很早就接觸到的溫度傳感器,也相信每一個(gè)曾學(xué)習(xí)過嵌入式開發(fā)的人都用過,筆者在STM32F4上自碼DS18B20驅(qū)動,有些小小心得:
1.初始化時(shí)序要注意,筆者親測,在MCU控制單總線為低電平240us即可(數(shù)據(jù)手冊上要求至少480us)釋放總線,等待60us后即可檢測到到DS18B20返回的拉低單總線信號,此處,需注意至少應(yīng)在此等待120us,否則可能會導(dǎo)致溫度傳感器無法正常工作。

2.初學(xué)者需注意時(shí)序,對于DS18B20的操作都必需經(jīng)過三步:初始化,ROM命令(多為跳過指令0xCC),DS18B20功能命令。再次強(qiáng)調(diào)對其的每一個(gè)操作必須經(jīng)過這三步,可閱讀code加深理解。
3.在讀取DS18B20時(shí),注意順序,DS18B20先發(fā)送低位,在字節(jié)讀取時(shí)應(yīng)當(dāng)注意。
4.初學(xué)者應(yīng)嘗試實(shí)現(xiàn)對于DS18B20內(nèi)部ROM的8位系列號(28H),和48位唯一序列號進(jìn)行讀取,以及修改溫度傳感器內(nèi)部EEPROM的過溫、低溫報(bào)警值。(可參考筆者code)

廢話不多說,上碼:
  1. #include <ds18b20.h>  
  2. #include "delay.h"  
  3. #include "usart.h"   
  4.   
  5. //ds18b20初始化  
  6. void  init_ds18b20( void )  
  7. {  
  8.     init_onewire_out();  
  9.     GPIO_ResetBits(GPIOG,GPIO_Pin_9);  
  10.     delay_us(480);  
  11.     init_onewire_in();  
  12.     delay_us(60);  
  13.     if( !DQ_In)  
  14.     {  
  15.         delay_us(120);  
  16.                   
  17.     }  
  18. }  
  19. //ds18b20 檢測  
  20. void  chack_ds18b20( void )  
  21. {  
  22.     init_onewire_out();  
  23.     GPIO_ResetBits(GPIOG,GPIO_Pin_9);  
  24.     delay_us(240);  
  25.     init_onewire_in();  
  26.     delay_us(60);  
  27.     if( !DQ_In)  
  28.     {  
  29.         delay_us(80);  
  30.         if( !DQ_In )  
  31.             printf("檢測到DS18B20!\r\n");  
  32.                   
  33.     }  
  34.   
  35. }  
  36. //設(shè)置為主設(shè)備寫總線,從設(shè)備讀總線  
  37. void init_onewire_out( void )  
  38. {  
  39.     GPIO_InitTypeDef  GPIO_InitStructure;  
  40.   
  41.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時(shí)鐘  
  42.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  43.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式  
  44.     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出  
  45.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz  
  46.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉  
  47.     GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化  
  48. }  
  49. //設(shè)置為主設(shè)備讀取總線,從設(shè)備寫總線  
  50. void init_onewire_in( void )  
  51. {  
  52.       
  53.     GPIO_InitTypeDef  GPIO_InitStructure;  
  54.   
  55.     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIOG時(shí)鐘  
  56.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  
  57.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通輸入模式  
  58. //  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出  
  59.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz  
  60.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉  
  61.     GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化  
  62. }  
  63.   
  64. void ds18b20_write_byte( u8 data )  
  65. {  
  66.     u8 i;  
  67.     u8 j=0;  
  68.     init_onewire_out();  
  69.     for(i=0;i<8;i++)  
  70.         {  
  71.             j=data & 0x01;  
  72.             if(j)  
  73.             {  
  74.                 DQ_Out=0;       //寫1  
  75.                 delay_us(15);  
  76.                 DQ_Out=1;  
  77.                 delay_us(60);  
  78.                   
  79.             }  
  80.             else  
  81.             {  
  82.                 DQ_Out=0;       //寫0  
  83.                 delay_us(60);  
  84.                 DQ_Out=1;  
  85.                 delay_us(1);  
  86.             }  
  87.             data = data>>1;  
  88.         }     
  89. }  
  90. //讀取DS18B20 的一位  
  91. u8 ds18b20_read_bit( void )  
  92. {     
  93.     u8 bit;  
  94.     init_onewire_out();  
  95.     DQ_Out=0;  
  96.     delay_us(2);  
  97.     DQ_Out=1;  
  98.     init_onewire_in();  
  99.     delay_us(12);  
  100.     if(DQ_In)  
  101.         bit=1;  
  102.     else  
  103.         bit=0;  
  104.     delay_us(50);  
  105.     return bit;  
  106. }  
  107. //讀ds18b20的字節(jié)  
  108. u8 ds18b20_read_byte ( void )  
  109. {  
  110.     u8 data=0;  
  111.     u8 i;  
  112.     u8 j=0;  
  113.     for(i=0;i<8;i++)  
  114.     {  
  115.         j=ds18b20_read_bit();  
  116.         if(j)           //注意順序即可,ds18b20先發(fā)送地位到總線上  
  117.             j=j<<i;  
  118.         data |=j;  
  119.   
  120.     }  
  121.     return data;  
  122. }  
  123. //獲取ds18b20的系列碼和48位唯一序列號  
  124. void ds18b20_read_rom_number()  
  125. {  
  126.     u32 number=0;  
  127.     u8 data,i,serial_num,ds18b20_crc;  
  128.     init_ds18b20();  
  129.     ds18b20_write_byte(0x33);  
  130.     serial_num = ds18b20_read_byte();  
  131.     for(i=0;i<6;i++)  
  132.     {  
  133.         data = ds18b20_read_byte();  
  134.         number |= data;  
  135.         number = number<<8;  
  136.     }  
  137.     ds18b20_crc = ds18b20_read_byte();  
  138.       
  139.     printf("系列號是:%d\r\n",serial_num);  
  140.     printf("序列號是:%d\r\n",number);  
  141.     printf("CRC校驗(yàn)為:%d\r\n",ds18b20_crc);  
  142.       
  143. }  
  144. //開啟ds18b20溫度轉(zhuǎn)換  
  145. void tem_chage( void )  
  146. {  
  147.     init_ds18b20();  
  148.     ds18b20_write_byte(0xcc);       //忽略rom指令  
  149.     ds18b20_write_byte(0x44);   //開啟轉(zhuǎn)換  
  150. }  
  151.   
  152. short  get_temp( void )  
  153. {  
  154.     int temp=0;  
  155.     u8 i,TH,TL;  
  156.     short tem;  
  157.   
  158.     tem_chage();  
  159.     delay_us(10);  
  160.     init_ds18b20();  
  161.     ds18b20_write_byte(0xcc);       //忽略rom指令  
  162.     ds18b20_write_byte(0xbe);   //讀取溫度轉(zhuǎn)換值  
  163.     TL=ds18b20_read_byte();  
  164.     TH=ds18b20_read_byte();  
  165.       
  166.     if(TH > 7)       //通過判讀存儲器的高五位的0,1來判斷溫度的正負(fù),  
  167.     {  
  168.         temp = 0;   //為負(fù)  
  169.         TH =~TH;  
  170.         TL =~TL;   
  171.     }  
  172.     else   
  173.         temp = 1;   //為正  
  174.     tem = TH;  
  175.     tem =tem<<8;  
  176.     tem =tem+TL;  
  177.     tem = (double)tem * 0.625;  
  178.     if(temp)  
  179.         return tem;  
  180.     else  
  181.         return -tem;  
  182.       
  183. }  
  184. void ds18b20_return_TH_TL_CONF( void )  
  185. {  
  186.     char data,data_TH,data_TL,CONF;  
  187.     init_ds18b20();  
  188.     ds18b20_write_byte(0xcc);       //忽略rom指令  
  189.     ds18b20_write_byte(0xbe);   //讀取溫度轉(zhuǎn)換值  
  190.     data = ds18b20_read_byte();  
  191.     data = ds18b20_read_byte();  
  192.     data_TH = ds18b20_read_byte();  
  193.     data_TL = ds18b20_read_byte();  
  194.     CONF =ds18b20_read_byte();  
  195.     printf("過溫報(bào)警的溫度為:%d℃\r\n",data_TH);  
  196.     printf("低溫報(bào)警的溫度為:%d℃\r\n",-(data_TL-128));  
  197.     CONF &=0x60 ;  
  198.     CONF =CONF>>5;  
  199.     switch (CONF) {  
  200.         case 0:  
  201.             printf("ds18b20的測量精度為9位,精度為0.5℃\r\n");  
  202.             break;  
  203.         case 1:  
  204.             printf("ds18b20的測量精度為10位,精度為0.25℃\r\n");  
  205.             break;  
  206.         case 2:  
  207.             printf("ds18b20的測量精度為11位,精度為0.125℃\r\n");  
  208.             break;  
  209.         case 3:  
  210.             printf("ds18b20的測量精度為12位,精度為0.0625℃\r\n");  
  211.             break;  
  212.         default:  
  213.             printf("error!!\r\n");  
  214.             break;  
  215.     }  
  216. }  
  217. //設(shè)置溫度報(bào)警值和配置精度,TH過溫報(bào)警值(TH>0),TL低溫報(bào)警值(TL為負(fù)數(shù) ),mode配置模式0,1,2,3  
  218. //mode=0 精度為9位  00011111 dat=31  
  219. //mode=1 精度為10位  00111111   dat=63  
  220. //mode=2 精度為11位 01011111    dat=95  
  221. //mode=3 精度為12位  01111111   dat =127  
  222. void ds18b20_write_TH_TL_CONF(u8 TH,u8 TL,u8 mode)  
  223. {  
  224.     u8 dat;  
  225.     switch (mode){  
  226.         case 0:  
  227.             dat=31;  
  228.             break;  
  229.         case 1:  
  230.             dat=63;  
  231.             break;  
  232.         case 2:  
  233.             dat=95;  
  234.             break;  
  235.         case 3:  
  236.             dat=127;  
  237.             break;  
  238.         default:  
  239.             printf("mode error!!\r\n");  
  240.             dat=127;  
  241.             break;  
  242.     }  
  243.     TL=TL+128;  
  244.     init_ds18b20();  
  245.     ds18b20_write_byte(0xcc);       //忽略rom指令  
  246.     ds18b20_write_byte(0x4e);   //寫入暫存寄存器 ,過溫和低溫報(bào)警值  
  247.     ds18b20_write_byte(TH); //寫入20°為過溫報(bào)警值  
  248.     ds18b20_write_byte(TL); //寫入-20°為低溫報(bào)警值  
  249.     ds18b20_write_byte(dat);    //寫入精度  
  250.     init_ds18b20();  
  251.     ds18b20_write_byte(0xcc);       //忽略rom指令  
  252.     ds18b20_write_byte(0x48);   //將寫入的暫存寄存器拷入EEPROM  
  253. }  
  254. void ds18b20_chack_self( void )  
  255. {  
  256.     chack_ds18b20();  
  257.     ds18b20_read_rom_number();  
  258.     ds18b20_return_TH_TL_CONF();  
  259. }  
復(fù)制代碼


筆者用串口助手得到結(jié)果如下:

回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产成人精品综合 | 日韩欧美在线播放 | 日韩不卡一区二区 | 91精品国产91久久久久久最新 | 亚洲欧美中文日韩在线v日本 | 99热精品在线| 性福视频在线观看 | 精品国产乱码久久久久久88av | 久久免费大片 | 日韩视频1 | 国产片一区二区三区 | 91精品在线观看入口 | 性高湖久久久久久久久3小时 | 国产精品日韩在线观看 | 国产探花在线精品一区二区 | 亚洲第一色av | 欧美舔穴 | 欧亚av在线 | 亚洲国产成人在线视频 | 成人国产精品久久 | 午夜激情视频 | www日本高清| 亚洲一区二区三区在线播放 | 自拍第1页 | 成人久久久 | av中文在线观看 | 亚洲第一区国产精品 | 亚洲欧美国产精品久久 | 黄色成人在线观看 | 桃色五月 | 亚洲人成在线播放 | 色一级片| 高清成人av | 99久久精品国产一区二区三区 | 91性高湖久久久久久久久_久久99 | 91久久精品国产免费一区 | 久久精品国产亚洲一区二区三区 | 日韩在线免费 | 日韩视频 中文字幕 | 精品自拍视频 | 日韩久久成人 |