項目四:基於藍牙的無線數據採集系統
總簡介
本系統本兩個部分,一個部分是採集端,一個是接收端。採集端由溫度傳感器DS18B20、主藍牙ATK-HC05(藍牙2.0)、光敏電阻及一個51單片機小系統組成。接收端由一個從藍牙模塊、報警模塊、溫度設定與顯示模塊組成。
系統工作原理
單片機串口通訊的工作原理及藍牙通訊協議。
單片機串口通信原理
DS18B20單總線協議
典型的單總線命令序列如下 :
第一步:初始化
第二步:ROM命令(跟隨需要交換的數據 )
第三步:功能命令(跟隨需要交換的數據)**
讀或者寫命令
DS18B20溫度傳感器只有三個引腳,只需要分別接電源、地及中間的引腳接到單片機的普通I/O口既可以與單片機進行通信。DS18B20是單總線通信方式,只需要一條總線就可以與單片機實現雙向通信,可讀可寫,而且支持多點組網方式,可以實現多點測溫,接線簡單,使用方便。DS18B20引腳圖如下圖3-5所示。
DS18B20單總線協議雖然接線簡單,但是對於程序部分的時隙要求非常高,DS18B20有嚴格的時序通訊協議,下圖3-6是DS18B20的初始化時序圖。
在主機初始化過程,主機(即通過單片機操作)拉低單總線至少 480us, 以產生(Tx) 復位脈衝。接着,主機釋放總線,並進入接收模式(Rx)。 當總線被釋放後,5k上拉電阻將單總線拉高。在單總線器件檢測到上升沿後,延時 15-60us,接着從機(也就是傳感器自己)通過拉低總線 60-240 us, 以產生應答脈衝 ,所以在初始化過程中我們需要做的就是拉低總線480us以上。
*******************************************************************************
* 函數名 : Ds18b20Init
* 函數功能 : 初始化
* 輸入 :無
* 輸出 :初始化成功返回1,不成返回0
*******************************************************************************/
unsigned char Ds18b20Init()
{
unsigned int i;
DSPORT=0; //將總線拉低480-960us
i=70;
while(i--);//延時±642us
DSPORT=1; //然後拉高總線·如果DS18B20做出反應會在15US-60Us後將總線拉低。
i=0;
while(DSPORT) //等待拉低總線,總線拉低了這個條件就不符合即跳出了
{
i++;
if(i>5000)//等待>5MS
return 0;//初始化失敗
return 1;//初始化成功
轉換命令
*******************************************************************************
* 函數名 : Ds18b20ChangTemp
* 功能 : 開始轉換溫度
* 輸入 : com
* 輸出 :無
*******************************************************************************/
void Ds18b20ChangTemp()
{
Ds18b20Init();
Delay1ms(1);
Ds18b20WriteByte(0xcc); //跳過ROM命令 //只有一個期間在線上的時候才能用,不然出錯亂
Ds18b20WriteByte(0x44); //溫度轉換命令
}
/*******************************************************************************
* 函數名 : Ds18b20WriteByte
* 功能 : 寫入一個字節
* 輸入 : dat:一些命令入0xcc跳過ROM命令,0x44溫度轉換命令,0Xbe發送讀取溫度命令
* 輸出 :無
*******************************************************************************/
void Ds18b20WriteByte(unsigned char dat)
{
unsigned int i,j;
for(j=0;j<8;j++)
{
DSPORT=0; //每寫入一位數據之前都要把總線拉低1us
i++;
DSPORT=dat&0x01; //從最低位開始一爲一位寫入數據
i=6;
while(i--); //延遲至少60us
DSPORT=1; //釋放總線接着寫入第二位數
dat>>=1;
}
}
讀取溫度
/*******************************************************************************
* 函數名 : Ds18b20ReadTemp
* 功能 : 讀取溫度
* 輸入 :無
* 輸出 :返回16位的溫度值
*******************************************************************************/
int Ds18b20ReadTemp()
{
int temp=0;
unsigned char tmh,tml;
Ds18b20ChangTemp(); //溫度轉換命令
Ds18b20ReadTempCom(); //溫度讀取命令
tml=Ds18b20ReadByte(); //開始讀,一共16位,先讀低字節。
tmh=Ds18b20ReadByte(); //再讀高字節
temp=tmh;
temp<<=8;
temp|=tml;//把兩個字節連接起來,一共16位
return temp;//返回這16位的溫度數值
}
至於爲什麼是16位呢?前5位是符號位,後11位纔是數值,其中前7位是整數位,後4位是小數位。
**所以DS18B20的溫度讀取到此結束:總結如下,初始化–ROM命令–功能命令。
因爲是單總線通信所以時序很重要,首先是要初始化,拉低總線DSPORT=0 480us以上,再釋放15us左右DS18B20做出反應自動拉低總線60-240us這時候就判斷是不是變低了即可,變低即成功初始化。然後ROM命令單點總線選跳過的命令,下達溫度轉換命令,然後就開始讀溫度的命令,先讀低字節再讀高字節,總共兩個字節16位。**這16位是二進制溫度數,需要編程10進制的實際溫度值乘以0.0625即可變成實際溫度值+0.5四捨五入。這樣子再顯示出來就可以了。