天天看點

一起玩轉樹莓派(7)——樹莓派模數/數模轉換實踐(二)

下面我們來詳細解釋下上面的代碼,首先smbus是一個Python子產品,我們之前并沒使用過,我們這次實驗不使用GPIO,使用smbus來進行I2C總線管理。

在核心邏輯執行前,首先需要進行總線管理器的執行個體化,使用如下方法:

bus = smbus.SMBus(1)

其中的參數表示要使用的I2C版本。

前面我們分析過,在I2C總線通信中,主機先要發送指令告訴從機要做什麼,對應代碼中就是write_byte方法,這個方法用來向PCF晶片發送一個8位的控制指令,通過查閱晶片手冊,很容易找到這個8位的控制指令每一位的意義,如下圖所示:

一起玩轉樹莓派(7)——樹莓派模數/數模轉換實踐(二)

我們從左往右來分析上圖。

對于上圖,我們在多解釋一下,這個8位的控制指令,第1位和第5位都是預設填充位,都用0填充,目前沒有任何意義。

第2位表示是否開啟AOUT輸出口,隻有這一位為1,數模轉換才會工作,數字信号才會被轉換為模拟信号從AOUT引腳輸出。(本次實驗我們暫不使用)

第3位和第4位用來程式設計控制輸入模式,這兩位可以組成的數值有00,01,10,11共四種,設定為00表示AIN端口與輸入通道一一對應。01,10,11這3種模式通道的值都是經過 處理的,上圖有明确的标注,比如在11模式下,通道0的值是AIN0和AIN1輸入的差分,通道1的值是AIN2和AIN3輸入的差分。(本次實驗我們也無需使用這一功能)

第6位的作用是設定是否自動切換通道,當其設定為1時,每次讀取資料後,通道都會切換,例如第一次讀取通道0的數值,第二次會在讀取時,會自動讀取通道1的數值。

第7位和第8位用來指定從哪個通道讀取數值,有4個通道可用,分别通過00,01,10,11進行設定。

我們再來看下write_byte方法:

bus.write_byte(0x48,0x00)  

這個方法有兩個參數,第2個參數就是我們上面說的指令參數,其用16進制表示,例如0x03設定為:

第1位 第2位 第3位 第4位 第5位 第6位 第7位 第8位

0(占位) 0(不使用AOUT) 0(一一對應模式) 0(一一對應模式) 0(占位) 0(不啟動切換通道) 1(設定要讀取的通道) 1(設定要讀取的通道)

write_byte這個方法的第1個參數用來設定I2C總線中要為哪一個從機設定指令,PCF的位址設定是7位,查閱手冊如下:

一起玩轉樹莓派(7)——樹莓派模數/數模轉換實踐(二)

可以看到第4位到第7位都是固定的,前3位是可程式設計的,還記得PCF的A0到A3引腳吧,就是讓主機來配置設定從機位址使用的。我們可以知道,PCF從機的位址一定在二進制數01001000(0x48)到01001111(0x4F)之間,要查閱目前連接配接到樹莓派的PCF從機的位址,可以在樹莓派終端輸入如下指令:

sudo i2cdetect -y 1

效果如下圖所示:

一起玩轉樹莓派(7)——樹莓派模數/數模轉換實踐(二)

從圖中可以看到,樹莓派目前隻連接配接了一個I2C從機子產品,配置設定的位址是0x48。

現在,上面的代碼對你來說非常好了解了,需要注意,其中除了0x48表示的是PCF從機的位址外,其他十六進制數都是指令。指令設定完成後,接下來就可以進行資料的通信,使用如下方法:

bus.read_byte(0x48)  

這個方法用來通過I2C總線從PCF讀取資料,上面代碼中我們在讀取資料時連續調用了兩次,這是因為PCF8591接收到讀取資料的指令後會同時進行上一次轉換資料的傳輸和本次資料的轉換,空讀一次可以消費掉不正确的資料。

還有一點需要注意,對于我們使用的PCF8591子產品來說,其自帶的可調節電壓會輸出到第4個通道,光敏傳感器的資料會輸出到第1個通道,熱敏傳感器的資料會輸出到第2個通道,在本次實驗中,第3個通道不被使用(如果你使用的PCF8591子產品和筆者的不太一樣,對應通道可能會不同,可以自行測試)。

三、盡情玩耍

現在,你可以嘗試在樹莓派上運作寫好的程式,通過輸出可以看到目前的可調節電壓、環境亮度和環境溫度的情況。你可以嘗試使用螺絲刀對電位計進行調節,可以實時的看到輸出電壓的改變,可以關燈和開燈來改變環境亮度,你也可以将熱敏傳感器握在手中,這些都可以明顯的從輸出資訊上看到環境資料的變化。如下圖所示:

一起玩轉樹莓派(7)——樹莓派模數/數模轉換實踐(二)

這次,關于樹莓派程式設計,我們學到了一些新的東西,使用I2C總線和數模轉換子產品我們可以做出更多有意思的東西,比如紅外控制的自制電視機?比如有有馬達驅動的遙控小車?等等...。你可以做好準備,我們後面會一起開發一些更好玩的東西!