筆者今天來講講Linux下IO口的使用。用的硬件是三大開源器件之一的BeagleBone(狗骨頭)。
(PS 三大開源器件:樹莓派、Arduino和Beagle Bone)
硬件介紹
- TI公司的AM3358 集成 1G MHz ARM Cortex™ A8 內核,
- 4GB eMMC Flash 存儲器
- 512MB DDR3 SDRAM 存儲器,
- 集成 NEON™ SIMD 協處理器,集成 SGX 530 圖形 引擎,集成可編程實時單元子系統,集成 32KB 指令緩存 和 32KB 數據緩存 ,支持奇偶校驗,集成 256KB 二級緩存,支持錯誤校驗碼
- 一個 HDMI D type 接口( 16 位色輸出,支持音頻輸出),一個 10/100M 以太網接口( RJ45 連接器),一個集成了 PHY 的高速 USB 2.0 OTG 接口( Mini USB B 型連接器),一個集成了 PHY 的高速 USB 2.0 HOST 接口( USB A 型連接器),一個 TF 卡接口(兼容 SD/MMC,一個 3 線調試串口( 6 pin 2.54 間距連接器)
一個 HDMI D type 接口,兩個擴展接口,可擴展 LCD 、 UART 、 eMMC 、 ADC 、 I2C 、 SPI 和 PWM 等接,一個 JTAG 接口( 20 pin 標準接口, 默認未焊接 連接器)
軟件使用
使用的 Eclipse C/C++ 來進行操作。
如果不懂如何利用Eclipse操作的話,推薦看這兩篇博客介紹。
Eclipse 進行Linux遠程開發
Eclipse 遠程Debug調試C程序
IO口的使用
在使用GPIO的時候,首先需要查看一下當前哪些IO口可以直接使用。在 /sys/class/gpio下面,
引腳分配圖如下:
如果要使用的IO口沒有找到,則需要使用export指令將IO口導成用戶可以使用的狀態,這個時候就可以發現多了一個要使用的IO口的目錄。
在這個目錄裏面就可以直接操作IO口,設置輸入輸出,查看當前值。
之前聽到過一句很經典的話,Linux下一切皆文件,所以IO設備也當文件處理即可。
1. IO口初始化
編寫思路同上文講的一樣,注意的一點是操作的IO口的路徑要寫正確。
a. 首先要export對應的端口,現在用fopen fwrite函數來寫入對應的端口名。
b. 設置輸出還是輸入模式。同樣使用文件操作函數進行,寫入out/in即可。
//頭文件定義設備路徑
#ifndef _IO_H_
#define _IO_H_
#include "stdio.h"
#include "string.h"
#include "time.h"
#include "unistd.h"
#define GPIO_DIR "/sys/class/gpio/"
void GPIOInit(int PinName,int InOrOut);
void SetGPIO(int PinName);
void ResetGPIO(int PinName);
unsigned char ReadGPIO(int PinName);
#endif
//.c文件函數實現
void GPIOInit(int PinName,int InOrOut) //1代表輸出,0代表輸入
{
FILE *stream = NULL;
char Path[50];
char Temp[20];
stream = fopen(GPIO_DIR"export","w");
sprintf(Temp,"%d",PinName);
fwrite(Temp,sizeof(int),2,stream);
fclose(stream);
if(InOrOut==1)
{
sprintf(Path,"%s%s%d%s",GPIO_DIR,"gpio",PinName,"/direction");
stream = fopen(Path,"r+"); //已存在文件並且可以讀寫
fwrite("out",sizeof(char),3,stream);
fclose(stream);
}
else
{
sprintf(Path,"%s%s%d%s",GPIO_DIR,"gpio",PinName,"/direction");
stream = fopen(Path,"w+"); //新建文件並且讀寫
fwrite("in",sizeof(char),2,stream);
fclose(stream);
}
}
2. IO口輸出
通過fwrite函數對IO設備文件寫入1或者0,即可設置IO口 高低電平
void SetGPIO(int PinName)
{
FILE *stream = NULL;
char Path[50];
sprintf(Path,"%s%s%d%s",GPIO_DIR,"gpio",PinName,"/value");
stream = fopen(Path,"w+");
fwrite("1",sizeof(char),1,stream);
printf("On\n");
fclose(stream);
}
void ResetGPIO(int PinName)
{
FILE *stream = NULL;
char Path[50];
sprintf(Path,"%s%s%d%s",GPIO_DIR,"gpio",PinName,"/value");
stream = fopen(Path,"w+");
fwrite("0",sizeof(char),1,stream); //設置GPIO高低電平
printf("Off\n");
fclose(stream);
}
3. IO口輸入
讀IO口 電平狀態 使用fread函數或者fscanf函數都可以
unsigned char ReadGPIO(int PinName)
{
FILE *stream = NULL;
char Path[50];
char Temp;
sprintf(Path,"%s%s%d%s",GPIO_DIR,"gpio",PinName,"/value");
stream = fopen(Path,"w+"); //w+,新建文件並且讀寫,r+存在文件,且讀寫
//fscanf(stream,"%s",Temp);
fread(&Temp,sizeof(char),1,stream); //掃描或者讀端口數據都可以
fclose(stream);
return Temp;
}
下一篇博文: Linux下C語言編程(2):ADC編程