上一篇筆記中,主要記錄了通過shell腳本的方式實現對LED燈的亮滅控制。不難看出,實際上對GPIO的控制主要是通過對內核接口/sys/class/gpio下的文件進行操作。同樣的方法,也可以通過C語言實現對GPIO口的控制。這篇筆記就記錄了筆者通過C語言的方法實現對LED的控制。
第一步:先點亮LED
1、新建led.c文件,方法講過:touch led.c。
2、利用vi編輯器對led.c進行編輯。源碼如下所示:
1 #include <stdio.h> 2 #define GPIO_DIR "/sys/class/gpio/" 3 4 int main() 5 { 6 FILE *stream=NULL; 7 stream=fopen(GPIO_DIR"export","w"); 8 9 fwrite("44",sizeof(int),2,stream); 10 fclose(stream); 11 12 13 stream=fopen(GPIO_DIR"gpio44/direction","r+"); 14 fwrite("out",sizeof(char),3,stream); 15 fclose(stream); 16 17 stream=fopen(GPIO_DIR"gpio44/value","r+"); 18 fwrite("1",sizeof(char),1,stream); 19 fclose(stream); 20 21 return 0; 22 }
幾點說明:
(1)第1行:包含了標准輸入輸出頭文件stdio.h,程序里用到的fopen(),fwrite(),fclose()函數都是包含在stdio.h里面;
(2)第2行:定義一個路徑;
(3)第6~10行:通過操作export文件添加gpio44引腳,相當於注冊GPIO44端口;
(4)第13~15行:設置gpio44的方向屬性;
(5)第17~19行:設置gpio44的數據為1,即高電平。
3、第二篇筆記已經詳細的說明怎樣編譯,請參考:http://www.cnblogs.com/zhezhe1988/p/4246713.html
這里直接進行編譯並運行,運行完LED燈點亮了。
4、要實現LED燈的閃爍,還需要添加循環語句和延遲語句來控制亮滅的交替變化。接下來將上邊的代碼在進行更改,於是得到下邊的代碼。
1 #include <stdio.h> 2 #define GPIO_DIR "/sys/class/gpio/" 3 4 int main() 5 { 6 FILE *stream=NULL; 7 stream=fopen(GPIO_DIR"export","w"); 8 fwrite("44",sizeof(int),2,stream); 9 fclose(stream); 10 11 stream=fopen(GPIO_DIR"gpio44/direction","r+"); 12 fwrite("out",sizeof(char),3,stream); 13 fclose(stream); 14 15 while(1) 16 { 17 printf("led on\n"); 18 stream=fopen(GPIO_DIR"gpio44/value","r+"); 19 fwrite("1",sizeof(char),1,stream); 20 fclose(stream); 21 usleep(500000); 22 printf("led of\n"); 23 stream=fopen(GPIO_DIR"gpio44/value","r+"); 24 fwrite("0",sizeof(char),1,stream); 25 fclose(stream); 26 usleep(500000); 27 } 28 return 0; 29 }
幾點說明:
(1)第2行:此處修改了GPIO_DIR的路徑,使其指向/sys/class/gpio/文件,注意第7,11,18,23行也做了相應修改;
(2)15~27行:添加了while循環語句,再循環里面先點亮LED,延遲0.5s,然后再熄滅,延遲0.5s;
(3)usleep()函數是微秒級的延遲。
5、修改后的代碼運行后就能實現LED燈交替閃爍了,其中閃爍間隔為0.5s。
第二步:講解幾個重要的知識
1、fopen()函數
包含頭文件 #include <stdio.h> 函數原型 FILE *fopen(char * filename,char * mode); 函數功能 以mode指定的方式打開名為filename的文件 傳入參數 filename: 文件名
mode:打開模式
r 只讀方式打開一個文本文件
rb 只讀方式打開一個二進制文件
w 只寫方式打開一個文本文件
wb 只寫方式打開一個二進制文件
a 追加方式打開一個文本文件
ab 追加方式打開一個二進制文件
r+ 可讀可寫方式打開一個文本文件
rb+ 可讀可寫方式打開一個二進制文件
w+ 可讀可寫方式創建一個文本文件
wb+ 可讀可寫方式生成一個二進制文件
a+ 可讀可寫追加方式打開一個文本文件
ab+ 可讀可寫方式追加一個二進制文件返回值 成功,返回一個文件指針(文件信息區的起始地址),否則返回0 2、fwrite()函數
包含頭文件 #include <stdio.h> 函數原型 int fwrite(char *ptr,unsigned size,unsigned n,FILE *fp); 函數功能 把ptr所指向的n*size個字節輸出到fp所指向的文件中 傳入參數 ptr-存放要寫入的數據,
size-每個數據單位的字節數,
n-讀入的數據單位個數
fp需要寫入的文件返回值 寫到fp文件中的數據項個數 3、 fclose()函數
包含頭文件 #include <stdio.h> 函數原型 int fclose(FILE * fp); 函數功能 關閉fp所指的文件,釋放文件緩沖區 傳入參數 fp需要關閉的文件 返回值 0-無錯,否則非零
注:以上三個函數都包含在標准輸入輸出頭文件stdio.h里面
4、usleep()函數
這個函數是Linux系統函數。有一個函數與這個函數比較相似,也就是sleep()函數。下面對比說明一下
函數原型 void usleep(int micro_seconds); sleep(unisgned long); 函數功能 本函數可暫時使程序停止執行。 本函數可暫時使程序停止執行。 傳入參數 micro_seconds 要暫停的微秒數 long 要暫停的秒數 返回值 無 無
5、sizeof()函數
(1)功能:計算數據空間的字節數
(2)與strlen比較:
1) strlen()計算字符數組的字符數,以"\0"為結束判斷,不計算為'\0'的數組元素。
2)sizeof計算數據(包括數組、變量、類型、結構體等)所占內存空間,用字節數表示。
6、stdio.h包含的函數
文件訪問
fopen
freopen
fflush
fclose
二進制輸入/輸出
fread
fwrite
非格式化輸入/輸出
fgetc
/
getc
fputc
/
putc
ungetc
fgets
fputs
格式化輸入/輸出
scanf
/
fscanf
/
sscanf
printf
/
fprintf
/
sprintf
perror
文件定位
ftell
fseek
fgetpos
fsetpos
rewind
錯誤處理
feof
ferror
文件操作
remove
rename
tmpfile
其中常用到的幾個函數原型:
int
getchar
()
//從標准輸入設備讀入一個字符
int
putchar
()
//向標准輸出設備寫出一個字符
int
scanf
(
char
*format[,argument…])
//從標准輸入設備讀入格式化后的數據
int
printf
(
char
*format[,argument…])
//向標准輸出設備輸出格式化字符串
char
*
gets
(
char
*string)
//從標准輸入設備讀入一個字符串
int
puts
(
char
*string)
//向標准輸出設備輸出一個字符串
int
sprintf
(
char
*string,
char
*format[,…])
//把格式化的數據寫入某個字符串緩沖區
總結:通過這個實驗掌握了利用C語言的方式去操作GPIO的方法。