beaglebone_black_学习笔记——(5)闪烁LED之C语言
上一篇笔记中,主要记录了通过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的方法。