加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 一、前言
    • 二、芯片介紹
    • 三、編程講解
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

stm32+DS18B20編程教學

03/24 09:25
5846
閱讀需 15 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

一、前言

繼上次發(fā)布的光照傳感器講解,這次繼續(xù)講一些簡單的適合大學生學習使用的傳感器。這次要講的是一款溫度傳感器,想要完整代碼工程的,可以在文章末尾的鏈接下載。

二、芯片介紹

1、簡介

DS18B20是一款數(shù)字型溫度傳感器,這款傳感器已經(jīng)有長的歷史了,驅(qū)動方式簡單,很適合初學者使用,具體的我就不多說了,很多人應(yīng)該都是知道這個傳感器的。

2、引腳定義

引腳 名稱 說明
1 GND 供電電源負極
2 DQ 數(shù)據(jù)輸入輸出引腳(和單片機IO口相連的時候一定要接上拉電阻
3 VCC 供電電源正極

3、通訊方式

DS18B20用的是單總線方式,單片機給DQ引腳輸出一定規(guī)則的時序信號即可配置和驅(qū)動DS18B20,同樣的,單片機按照時序接收DS18B20發(fā)送的數(shù)據(jù)即可得到溫度數(shù)據(jù)。

4、工作原理

DS18B20通過傳感電路把溫度轉(zhuǎn)換成對應(yīng)的電壓信息,然后轉(zhuǎn)換成數(shù)字信號,再把溫度相關(guān)的數(shù)據(jù)存到自身的寄存器里面,單片機去讀取這些數(shù)據(jù),就可以知道當前的溫度了。簡單的說就是把模擬信號轉(zhuǎn)換成數(shù)字信號,然后把這些數(shù)據(jù)存起來交給單片機,大概的原理是這樣,如果你想繼續(xù)深入了解,可以去找一下相關(guān)的文章,關(guān)于這方面的介紹有很多。

三、編程講解

1、DS18B20驅(qū)動程序

//單片機只需要用一個普通的IO口和DS18B20的DQ引腳相連,然后控制這個IO口輸出高低電平即可

//復(fù)位DS18B20
//作用:復(fù)位
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT(); //把單片機的IO口配置為輸出
    DS18B20_DQ_OUT=0; //拉低DQ
    delay_us(750);    //拉低750us,這個時間是根據(jù)DS18B20本身的規(guī)則定的,可以在數(shù)據(jù)手冊找到相關(guān)介紹
    DS18B20_DQ_OUT=1; //拉高DQ
	delay_us(15);     //15US
}

//等待DS18B20的回應(yīng)
//作用:檢查單片機和DS18B20的通訊是否正常
//返回1:未檢測到DS18B20的存在(可能是DQ引腳沒有上拉電阻,通訊的時序不對,芯片損壞等原因)
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();//把IO口配置為輸入,目的是為了接收DS18B20發(fā)過來的數(shù)據(jù)	 
    while (DS18B20_DQ_IN&&retry<200)//如果IO口是低電平,則是正常的,否則一直進while循環(huán)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)
	{//通訊有誤,返回1
		return 1;
	}
	else 
	{//正常
		retry=0;
	}
    while (!DS18B20_DQ_IN&&retry<240)//繼續(xù)讀取電平,如果IO口是高電平,則是正常的
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)
	{//通訊有誤,返回1
		return 1;
	}	    
	return 0;//通訊正常,返回0
}

//從DS18B20讀取一個位
//作用:讀取一個位數(shù)據(jù),重復(fù)調(diào)用該函數(shù)可以把溫濕度數(shù)據(jù)讀出來
//返回值:1/0
u8 DS18B20_Read_Bit(void) 			 // read one bit
{
  	u8 data;
	DS18B20_IO_OUT();//單片機輸出一個由低到高的上升沿脈沖給DS18B20
 	DS18B20_DQ_OUT=0; 
	delay_us(2);
 	DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();//把IO口配置為輸入,讀取電平
	delay_us(12);
	if(DS18B20_DQ_IN)//如果是高電平,則DS18B20輸出的數(shù)據(jù)是'1',否則為'0'
		data=1;
  	else 
  		data=0;	 
 	delay_us(50);           
  	return data;
}

//從DS18B20讀取一個字節(jié)
//作用:連續(xù)讀8個位,并合成一個字節(jié)數(shù)據(jù)
//返回值:讀到的數(shù)據(jù)
u8 DS18B20_Read_Byte(void)    // read one byte
{        
    u8 i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();//連續(xù)調(diào)用8次
        dat=(j<<7)|(dat>>1);//每次讀取到1個位的數(shù)據(jù)后左移1位,讀取完8個位的數(shù)據(jù)之后就可以合成1個字節(jié)了
    }						    
    return dat;//返回合成的1字節(jié)數(shù)據(jù)
}

//寫一個字節(jié)到DS18B20
//作用:寫數(shù)據(jù)到DS18B20,調(diào)用這個函數(shù)可以發(fā)送指令控制DS18B20
//dat:要寫入的字節(jié)
void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
	DS18B20_IO_OUT();//SET PA0 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;//把傳進來的這個數(shù)據(jù)的最高位提取出來
        dat=dat>>1;//dat的數(shù)據(jù)左移1位,作用是把次高位移到最高位
        if (testb) //如果最高位數(shù)據(jù)為'1'
        {
            DS18B20_DQ_OUT=0;// Write 1
            delay_us(2);                            
            DS18B20_DQ_OUT=1;//輸出60us高電平,相當于告訴DS18B20要傳的數(shù)據(jù)是'1'
            delay_us(60);             
        }
        else //如果最高位數(shù)據(jù)為'0'
        {
            DS18B20_DQ_OUT=0;//輸出60us低電平,相當于告訴DS18B20要傳的數(shù)據(jù)是'0'
            delay_us(60);             
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}

//開始溫度轉(zhuǎn)換
//作用:從DS18B20中讀取溫度數(shù)據(jù)
void DS18B20_Start(void)// ds1820 start convert
{   						               
  DS18B20_Rst();//復(fù)位   
  DS18B20_Check();//檢查單片機和DS18B20的通訊是否正常	 
  DS18B20_Write_Byte(0xcc);//尋址總線上的所有從設(shè)備,詳細說明可以參考數(shù)據(jù)手冊ROM COMMANDS
  DS18B20_Write_Byte(0x44);//0x44命令為啟動溫度轉(zhuǎn)換命令,詳細說明可以參考數(shù)據(jù)手冊ROM COMMANDS
} 
//初始化DS18B20的IO口DQ 同時檢測DS18B20的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
 	GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PORTA口時鐘 
 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//PORTA0 推挽輸出
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);

 	GPIO_SetBits(GPIOA,GPIO_Pin_0);    //輸出1

	DS18B20_Rst();//復(fù)位

	return DS18B20_Check();
}  
//從ds18b20得到溫度值
//精度:0.1C
//返回值:溫度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
	short tem;
    //DS18B20_Start (); //開始采集溫度
    DS18B20_Rst();//復(fù)位
    DS18B20_Check();//檢查單片機和DS18B20通訊是否正常	 
    DS18B20_Write_Byte(0xcc);//尋址總線上的所有從設(shè)備,詳細說明可以參考數(shù)據(jù)手冊ROM COMMANDS
    DS18B20_Write_Byte(0xbe);//0x44命令為啟動溫度轉(zhuǎn)換命令,詳細說明可以參考數(shù)據(jù)手冊ROM COMMANDS    
    TL=DS18B20_Read_Byte(); //讀取數(shù)據(jù)低字節(jié)  
    TH=DS18B20_Read_Byte(); //讀取數(shù)據(jù)高字節(jié) 
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//溫度為負  
    }
    else 
    {
    	temp=1;//溫度為正	
    }  	  
    tem=TH;//獲得高字節(jié)數(shù)據(jù)
    tem<<=8;//高字節(jié)位左移8位    
    tem+=TL;//左移的高8位加上低8位合成一個16位數(shù)據(jù)
    tem=(float)tem*0.625;//從DS18B20讀取到的2個字節(jié)的數(shù)據(jù)還不是溫度值,需要轉(zhuǎn)換,轉(zhuǎn)換公式參考數(shù)據(jù)手冊     
	if(temp)
	{
		return tem; //返回溫度值
	}
	else 
	{
		return -tem;   
	} 
} 

2、main函數(shù)

int main()
{  
	short temperature;    
	uart_init(115200);	 	//串口初始化為115200
	LED_Init();		  		//初始化與LED連接的硬件接口
	OLED_Init();            //OLED初始化
	OLED_Clear();           //OLED清屏
	while(DS18B20_Init())	//DS18B20初始化	
	{
    	OLED_ShowString(50,2,"error",12);//DS18B20通訊有問題
	}
	while(1)
	{	
	    //讀取溫度		
		temperature=DS18B20_Get_Temp();	
		if(temperature<0)//溫度低于0
		{		
			OLED_ShowString(50,4,"-",16);   //顯示負號
			temperature=-temperature;	    //轉(zhuǎn)為正數(shù)
		}
		else //溫度大于0
		{
			OLED_ShowString(50,4," ",16);	//不顯示負號,也不顯示正號
		}	 
		OLED_ShowCHinese(0,4,0);//顯示中文字體“溫”
		OLED_ShowCHinese(16,4,1);//顯示中文字體“度”
		OLED_ShowString(32,4,":",16);
		OLED_ShowNum(60,4,temperature/10,2,16); //顯示整數(shù)部分
		OLED_ShowString(80,4,".",16);
   		OLED_ShowNum(88,4,temperature%10,1,16);	//顯示小數(shù)部分 
		OLED_ShowCHinese(100,4,9);//顯示“℃”
	}

好了,關(guān)于這個傳感器的介紹就到這里吧。

鏈接:https://pan.baidu.com/s/1pIcwctU0q1EWM7975JWrnQ ,提取碼:bbhc

創(chuàng)作不易,希望你們尊重別人的勞動,點贊+關(guān)注支持一下吧,謝謝大家了,博主也會繼續(xù)寫更多的大學生專欄,如果你們還有什么問題,可以評論留言或者私信給我

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
AD73311ARSZ 1 Analog Devices Inc Single-Channel, 3 V and 5 V Front-End Processor for General Purpose Applications Including Speech and Telephony

ECAD模型

下載ECAD模型
$10.72 查看
AT27C256R-70JU-306 1 Microchip Technology Inc IC OTP 256KBIT 70NS 32PLCC
暫無數(shù)據(jù) 查看
511FBA125M000BAG 1 Silicon Laboratories Inc LVDS Output Clock Oscillator,

ECAD模型

下載ECAD模型
$3.39 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜