单总线协议
一、單總線協(xié)議(1-wire)
1.定義:主機和從機用一根總線進行通信,是一種半雙工的通信方式,單線=時鐘線+數(shù)據(jù)線+控制線( +電源線)。理想狀況下一條總線上的從器件數(shù)量幾乎不受數(shù)量限制。
2.特點:這是由達拉斯半導(dǎo)體公司推出的一項通信技術(shù)。它采用單根信號線,既可傳輸時鐘,又能傳輸數(shù)據(jù),而且數(shù)據(jù)傳輸是雙向的。
3.優(yōu)點:單總線技術(shù)具有線路簡單,硬件開銷少,成本低廉,便于總線擴展和維護等。
二、單總線通信過程
所有的單總線器件要求采用嚴(yán)格的通信協(xié)議, 以保證數(shù)據(jù)的完整性。該協(xié)議定義了幾種信號類型:復(fù)位脈沖、 應(yīng)答脈沖、 寫0、寫1、 讀0和讀1。所有這些信號,除了應(yīng)答脈沖以外,都由主機發(fā)出同步信號。并且發(fā)送所有的命令和數(shù)據(jù)都是字節(jié)的低位在前,這一點與多數(shù)串行通信格式不同(多數(shù)為字節(jié)的高位在前)。
(1)初始化序列:復(fù)位和應(yīng)答脈沖
初始化過程 = 復(fù)位脈沖 + 從機應(yīng)答脈沖。
主機通過拉低單總線480 ~ 960 us產(chǎn)生復(fù)位脈沖,然后釋放總線,進入接收模式。主機釋放總線時,會產(chǎn)生低電平跳變?yōu)楦唠娖降纳仙?#xff0c;單總線器件檢測到上升沿之后,延時15 ~ 60 us,單總線器件拉低總線60 ~ 240 us來產(chǎn)生應(yīng)答脈沖。主機接收到從機的應(yīng)答脈沖說明單總線器件就緒,初始化過程完成。
初始化時序圖如下所示:
(2)寫間隙
寫間隙有兩種,包括寫0的時間隙和寫1的時間隙。
當(dāng)數(shù)據(jù)線拉低后,在15 ~ 60 us的時間窗口內(nèi)對數(shù)據(jù)線進行采樣。如果數(shù)據(jù)線為低電平,就是寫0,如果數(shù)據(jù)線為高電平,就是寫1。主機要產(chǎn)生一個寫1時間隙,就必須把數(shù)據(jù)線拉低,在寫時間隙開始后的15 us內(nèi)允許數(shù)據(jù)線拉高。主機要產(chǎn)生一個寫0時間隙,就必須把數(shù)據(jù)線拉低并保持60 us。
寫時間隙時序圖如下所示:
(3)讀時間隙
當(dāng)主機把總線拉低是,并保持至少1 us后釋放總線,必須在15 us內(nèi)讀取數(shù)據(jù)。
單總線器件僅在主機發(fā)出讀時隙時,才向主機傳輸數(shù), 所以, 在主機發(fā)出讀數(shù)據(jù)命令后,必須馬上產(chǎn)生讀時隙,以便從機能夠傳輸數(shù)據(jù)。所有讀時隙至少需要 60us, 且在兩次獨立的讀時隙之間至少需要 1us的恢復(fù)時間,每個讀時隙都由主機發(fā)起, 至少拉低總線 1us (圖5 所示)。在主機發(fā)起讀時隙之后,單總線器件才開始在總線上發(fā)送 0 或1。 若從機發(fā)送1,則保持總線為高電平;若發(fā)送 0, 則拉低總線 。當(dāng)發(fā)送 0 時,從機在該時隙結(jié)束后釋放總線 。由上拉電阻將總線拉回至空閑高電平狀態(tài)。從機發(fā)出的數(shù)據(jù)在起始時隙之后,保持有效時間 15us ,因而,主機在讀時隙期間必須釋放總線 ,并且在時隙起始后的 15 us 之內(nèi)采樣總線狀態(tài)。
讀時間隙時序圖如下所示:
三、單總線實例—DS18B20
當(dāng)主機對多個DS18B20的某一設(shè)備進行操作時,主機首先逐個與掛在總線設(shè)備掛接,使用搜索ROM(FOh)指令,讀出其序列號(33H),然后發(fā)送匹配指令(55h),緊接著提供64位序列號,之后就是操作該DS18B20了。
如果只有一個DS18B20測溫,就不需要搜索ROM、讀ROM以及匹配ROM操作了,只需要指令跳過ROM(CCh)指令,就可指令溫度轉(zhuǎn)換(44h)和讀取溫度(BEh)操作了。
#include "ds18b20.h" #include "delay.h" // //實驗平臺:STM32F103 ////復(fù)位DS18B20 void DS18B20_Rst(void) { DS18B20_IO_OUT(); //SET PG11 OUTPUTDS18B20_DQ_OUT=0; //拉低DQdelay_us(750); //拉低750usDS18B20_DQ_OUT=1; //DQ=1 delay_us(15); //15US } //等待DS18B20的回應(yīng) //返回1:未檢測到DS18B20的存在 //返回0:存在 u8 DS18B20_Check(void) { u8 retry=0;DS18B20_IO_IN(); //SET PG11 INPUT while (DS18B20_DQ_IN&&retry<200){retry++;delay_us(1);}; if(retry>=200)return 1;else retry=0;while (!DS18B20_DQ_IN&&retry<240){retry++;delay_us(1);};if(retry>=240)return 1; return 0; } //從DS18B20讀取一個位 //返回值:1/0 u8 DS18B20_Read_Bit(void) {u8 data;DS18B20_IO_OUT(); //SET PG11 OUTPUTDS18B20_DQ_OUT=0; delay_us(2);DS18B20_DQ_OUT=1; DS18B20_IO_IN(); //SET PG11 INPUTdelay_us(12);if(DS18B20_DQ_IN)data=1;else data=0; delay_us(50); return data; } //從DS18B20讀取一個字節(jié) //返回值:讀到的數(shù)據(jù) u8 DS18B20_Read_Byte(void) { u8 i,j,dat;dat=0;for (i=1;i<=8;i++) {j=DS18B20_Read_Bit();dat=(j<<7)|(dat>>1);} return dat; } //寫一個字節(jié)到DS18B20 //dat:要寫入的字節(jié) void DS18B20_Write_Byte(u8 dat) { u8 j;u8 testb;DS18B20_IO_OUT(); //SET PG11 OUTPUT;for (j=1;j<=8;j++) {testb=dat&0x01;dat=dat>>1;if (testb) {DS18B20_DQ_OUT=0; // Write 1delay_us(2); DS18B20_DQ_OUT=1;delay_us(60); }else {DS18B20_DQ_OUT=0; // Write 0delay_us(60); DS18B20_DQ_OUT=1;delay_us(2); }} } //開始溫度轉(zhuǎn)換 void DS18B20_Start(void) { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); // skip romDS18B20_Write_Byte(0x44); // convert } //初始化DS18B20的IO口 DQ 同時檢測DS的存在 //返回1:不存在 //返回0:存在 u8 DS18B20_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); //使能PORTG口時鐘 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PORTG.11 推挽輸出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_SetBits(GPIOG,GPIO_Pin_11); //輸出1DS18B20_Rst();return DS18B20_Check(); } //從ds18b20得到溫度值 //精度:0.1C //返回值:溫度值 (-550~1250) short DS18B20_Get_Temp(void) {u8 temp;u8 TL,TH;short tem;DS18B20_Start (); // ds1820 start convertDS18B20_Rst();DS18B20_Check(); DS18B20_Write_Byte(0xcc); // skip romDS18B20_Write_Byte(0xbe); // convert TL=DS18B20_Read_Byte(); // LSB TH=DS18B20_Read_Byte(); // MSB if(TH>7){TH=~TH;TL=~TL; temp=0; //溫度為負(fù) }else temp=1; //溫度為正 tem=TH; //獲得高八位tem<<=8; tem+=TL; //獲得底八位tem=(float)tem*0.625; //轉(zhuǎn)換if(temp)return tem; //返回溫度值else return -tem;} #ifndef __DS18B20_H #define __DS18B20_H #include "sys.h" // ////IO方向設(shè)置 #define DS18B20_IO_IN() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;} #define DS18B20_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;} IO操作函數(shù) #define DS18B20_DQ_OUT PGout(11) //數(shù)據(jù)端口 PA0 #define DS18B20_DQ_IN PGin(11) //數(shù)據(jù)端口 PA0 u8 DS18B20_Init(void);//初始化DS18B20 short DS18B20_Get_Temp(void);//獲取溫度 void DS18B20_Start(void);//開始溫度轉(zhuǎn)換 void DS18B20_Write_Byte(u8 dat);//寫入一個字節(jié) u8 DS18B20_Read_Byte(void);//讀出一個字節(jié) u8 DS18B20_Read_Bit(void);//讀出一個位 u8 DS18B20_Check(void);//檢測是否存在DS18B20 void DS18B20_Rst(void);//復(fù)位DS18B20 #endif總結(jié)
單總線技術(shù)以其線路簡單、硬件開銷少、成本低廉、軟件設(shè)計簡單優(yōu)勢而有著無可比擬的應(yīng)用前景。基于單總線技術(shù)能較好地解決傳統(tǒng)識別器普遍存在的攜帶不便、易損壞、易受腐饋、易受電磁干擾等不足,可應(yīng)用于高度安全的門禁、身份識別等領(lǐng)域。其通信可靠簡單,很容易實現(xiàn)。因此單總線技術(shù)有著廣闊的應(yīng)用前景,是值得產(chǎn)注的一個發(fā)展領(lǐng)域。
總結(jié)
- 上一篇: Django2.2框架小白项目心得(一)
- 下一篇: 五种通信总线协议详解