天天看點

Linux ds18b20驅動心得

在進入正題之前不得不說,由于自己的一個錯誤,導緻此驅動寫了近3天,查閱了無數的資料,基本上都能把ds18b20的原理和使用過程背下來了,可以說有失有得,如果當初一兩次就成功了,可能也就不會深入的去查閱各種資料了。

下面進入正題,心得的角度從快速使用的角度出發。
           
Linux ds18b20驅動心得
開發闆将引腳設為輸出,發送一個高電平再拉低,維持480-960US;
	引腳拉高釋放總線,主機等待60US-200US;
	讀取引腳資料,0為初始化成功;1為初始化失敗;
	讀取資料完畢後,延遲等待400US;
	
	程式示範:
		void de18b20_init_start(void)
		 {
	    	int ack = 1;
	    	gpio_direction_output(ds18b20.gpionum, 0);	//驅動初始化已經将此GPIO配置輸出高電平,這裡直接就拉低了。
	    	udelay(480);//延遲時間範圍,根據自己的闆子測試更改。
	    	gpio_direction_output(ds18b20.gpionum, 1);//釋放總線等待響應
	    	udelay(60);
	    	ack = gpio_get_value(ds18b20.gpionum);//傳回值為0說明初始化成功,反則為1
	    	printk("ack = %d\n",ack);
	    	udelay(400);//配置完成後延遲400us
	    	gpio_direction_output(ds18b20.gpionum, 1);
	 	 }
           
Linux ds18b20驅動心得

寫資料

引腳拉高2us,然後拉低(保持1us),産生一個下降沿,表示寫資料開始;
将要寫的1或0放在總線上;
整個過程在15us之内完成;
然後主機延時等待至少50us;
拉高釋放總線;
每寫兩位資料之間的間隔要大于1us;

程式示範
    void ds18b20_wriet_data(unsigned char byte)
    {
    	unsigned char i = 0;
    		for (i = 0; i < 8; i++) {
    			gpio_set_value(ds18b20.gpionum, 1);	//拉高引腳
    			udelay(2);//保持2us
    			gpio_set_value(ds18b20.gpionum, 0);		//拉低引腳,産生寫間隙
    			udelay(2);		//簡單延時
    			gpio_set_value(ds18b20.gpionum, 1);		//15us之内釋放總線
    			udelay(2);		//簡單延時
    			gpio_set_value(ds18b20.gpionum, byte & 0x01);	//将位元組低位寫入單總線
    			udelay(50);		//在15~60us内等待DS18B20來采集信号
    			gpio_set_value(ds18b20.gpionum, 1);		//釋放總線
    			byte >>= 1;       	//每次講要讀取的資料位移至最低位
    			udelay(2);
    			}	
    }
           

讀資料

拉高引腳,延時2us,然後拉低1us,産生一個下降沿,表示讀資料;
拉高釋放總線,必須在下降沿之後的15us内将端口資料讀取;
讀取資料後,延時60us;
每兩個資料位之間間隔大于1us;

程式示範
unsigned char de18b20_read_data(void)
{
	unsigned char i = 0;
	unsigned char byte = 0;
	for (i = 0; i < 8; i++) {
		gpio_set_value(ds18b20.gpionum, 1);//産生讀時序
		udelay(2);
		gpio_set_value(ds18b20.gpionum, 0);//産生讀時序
		udelay(2);			//簡單延時
		gpio_set_value(ds18b20.gpionum, 1);//釋放總線
		byte >>= 1;     		//先進行移位
		if(gpio_get_value(ds18b20.gpionum))
			{
			byte |= 0x80;
			printk("1\n");//調試資訊
			}else{
			printk("0\n");//調試資訊
			}
		udelay(60);			//延時60us
		gpio_set_value(ds18b20.gpionum, 1);	//釋放總線
		udelay(1);
	}
	return byte;
}
           

使用過程

ds18b20_init_start();//複位ds18b20
ds18b20_wriet_data(0xcc);
ds18b20_wriet_data(0x44);
//以上内容是告訴ds18b20,跳過ROM指令(0xcc),轉換溫度(0x44);
//此處需要等待溫度的轉換完成,可以使用延遲函數,也可以使用以下方法,等待第一時間轉換完整讀取資料。
while(!gpio_get_value(ds18b20.gpionum));
ds18b20_init_start();//複位ds18b20
ds18b20_wriet_data(0xcc);
ds18b20_wriet_data(0xbe);
//以上内容是告訴ds18b20,跳過ROM指令(0xcc),讀取溫度寄存器的值(0xbe);
//剩下就是調用read來讀取相應的數值了。
           

繼續閱讀