Linkit 系列博文:
聯發科Linkit 7688 (一) 上手及在Mac下搭建OpenWrt交叉編譯環境,C語言編譯Hello,World
聯發科Linkit 7688 (二)GPIO基本操作與C語言編程
聯發科Linkit 7688 DUO(三): 通過 Arduino 控制外設和感應器
Linkit 7688 DUO(四): 接上各種Arduino感應器和模組——基礎篇
Linkit 7688 DUO(五) 接上各種Arduino感應器和模組—擴充篇
Linkit 7688 DUO(六) 加入MQTT物聯網協議
GPIO ( General Purpose Input Output ) 全名為通用輸入輸出,是CPU的一種管腳,即可以做輸入、也可以做輸出, 常用於將開關、按鍵、LED、感應器等接到CPU。
Linkit 7688 有40多個GPIO管腳, 分別編號為:gpio1, gpio2, ... gpioxx
一、GPIO 基礎
GPIO 管腳支援最高 4 mA 電流, 啟用時電壓為3.3V. 管腳有兩個狀態:HIGH 或 LOW, HIGH就是高電壓(3.3V), LOW是低電壓(0 V)
根據串連電路的不同,串連GPIO管腳的裝置有兩種啟用方式:
Active high: 當 GPIO 為 HIGH時,裝置被啟用 Active low: 當 GPIO為 LOW時,裝置被啟用 下圖顯示 LED 和 按鈕 分別以 Active High 和 Active Low 兩種方式 接入GPIO的電路圖
二、GPIO的軟體控制
在Linux中, GPIO 表達為一個裝置檔案, 對GPIO的操作採用檔案讀寫方式即可完成。 在 目錄 /sys/class/gpio/ 下 存放著 GPIO 的裝置檔案。 查看一個7688的gpio這個目錄
ls /sys/class/gpio
返回結果:
export gpiochip0 gpiochip127 gpiochip32 gpiochip64 unexport
其中: export 和 unexport 是兩個檔案, 其它是目錄。
要操作某一個GPIO, 首先要將GPIO 管腳編號首先寫入 export 檔案中 輸入命令列: echo 44 > /sys/class/gpio/export 然後 查看gpio目錄 ls /sys/class/gpio 結果是:
export gpiochip0 gpiochip32 unexport
gpio44 gpiochip127 gpiochip64
可以看到,該目錄下多了一個名為 gpio44的目錄。 進入這個目錄即可對GPIO44口進行操作。
查看一下gpio44目錄: ls /sys/class/gpio/gpio44
結果有幾個檔案:
active_low device direction edge subsystem uevent value
其中:
direction 檔案是GPIO的輸入輸出方向,寫入文本"out" 到該檔案,則 GPIO口被置為輸出狀態。寫入"in" 到該檔案,則 GPIO口被置為輸入狀態。
value 檔案是GPIO的目前狀態值,為1或0 (即 HIGH 或 LOW). 寫入文本"1" 到該檔案,則 GPIO置為HIGH(高電壓), 寫入文本"0" 到該檔案,則 GPIO置為LOW(低電壓)
以命令列操作一下, 將gpio44的direction設成 "out", 值設為 "0"
echo out > /sys/class/gpio/gpio44/direction
echo 0 > /sys/class/gpio/gpio44/value
則此時, 開發板上的WIFI燈亮起。 (開發板的WIFI燈串連了 gpio44, 由於WIFI燈的接入方式是Active Low,故寫入 “0“ 燈亮)
寫入 “1“ , 則開發板上的WIFI燈滅了,命令如下:
echo 1 > /sys/class/gpio/gpio44/value
操作完成後,可以將GPIO 管腳編號寫入 unexport 檔案中
echo 44 > /sys/class/gpio/unexport
則目錄 /sys/class/gpio/gpio44 將消失, 不能操作GPIO 44腳了
上述過程是適用於所有 Linux 版本的通用處理方式,不僅是OpenWrt專屬的。
三、C語言編程操作GPIO
明白上述過程後,也就明白了:C語言編程操作GPIO其實就是讀寫檔案。
比如: 將 gpio44 置為HIGH
int fp =open("/sys/class/gpio/gpio44/value", O_WRONLY);
write(fp, "1", 2 );
close(fp);
一般來說,對裝置檔案的操作使用 open(), close(), 而不使用 fopen(), fclose(). 前者是作業系統函數、無緩衝的,後者是標準C函數、有緩衝的。
為方便使用,我寫了一個gpio模組,包含兩個檔案 gpio.c, gpio.h, 有幾個GPIO的常用操作函數。 比如:
/**
* Export specified GPIO pin
* @param pin_number specified the pin
* @return 1 if success.
* return negative integer error code if fail.
*/
int gpio_export(int pin_number) ;
/**
* Write specified GPIO pin
* @param pin_number specified the pin
* @param value
* @return 1 if success.
* return negative integer error code if fail.
*/
int gpio_write(int pin_number,int value);
/**
* set direction of specified GPIO pin
* @param pin_number specified the pin
* @param direction could be GPIO_IN or GPIO_OUT, GPIO_OUT_HIGH, GPIO_OUT_LOW
* @return 1 if success.
* return negative integer error code if fail.
*/
int gpio_set_direction(int pin_number,int direction);
...
具體看 gpio.h 標頭檔 和 example吧
常式:
#include "gpio.h"
int main() {
gpio_export(44); //export gpio44
gpio_set_direction(44, GPIO_OUTPUT); //設 gpio44 為 輸出狀態
gpio_write(44, GPIO_LOW); //設 gpio44 值為 LOW, 在7688板上則WIFI燈亮起
}
gpio模組和常式在我的下載中分享 :GPIO庫
對於CPU直接引出的 GPIO管腳 , 上述操作就可以了。
但是,在Linkit 7688 DUO開發板, 板上引出的GPIO引腳都是由一片 ATmega32U4 晶片提供的,這片晶片提供Arduino的開發介面。
因此,要操作 Linkit 7688 DUO開發板的GPIO口,需要安裝 Arduino IDE, 並用Arduino編程ATmega32U4 控制GPIO口,
Linkit 7688主晶片通過串口控制ATmega32U4 。(具體見後續博文)