BBB板第六课:C++编程控制GPIO基础
在一上课我们通过Shell脚本编程实现了对GPIO端口的简单输出控制,实现对两个LED指示灯的交替点亮和关闭,接下来的一两节课,将通过C++程序来实现Shell脚本的功能。为了实现对应的程序控制,我查阅了好多资料,测试过程中发觉网上的一些程序套用过来总是出现各种各样的编译错误,压根就控制不了BBB板,不知是我的BBB板太新,还是以前的程序太旧。最后还是从头开始,重新研究BBB板的文件系统,找出头文件,找出所有相关的函数,终于实现GPIO的C++程序控制。
先不急于写程序,在这一节课先把一些基础讲解下,是非常重要的,当然C语言高手就不用看了。
一、IO读写函数
输入输出的函数基本上全在头文件stdio.h中定义,具体在/usr/include目录中,这个目录还包括其他头文件,最好仔细看下提供了哪些有效的函数,再结合百度到的知识掌握这些经常用的函数。
1、打开文件fopen()和写入数据fwrite()
Fopen(文件名,打开模式),其中文件名必须是完整路径,使用双引号;打开模式比较多,比较常用就是只读r、读写r+,只写w,函数返回值为文件指针(也叫文件描述符);
fwrite(数据,字节数,写入个数,文件指针),有四个参数,少写一个编译都会出错,其中字节数固定为sizeof(char)或sizeof(int),都是4个字节,对应32位系统,BBB板就是32位系统,我就当做常数来用,这个参数理解了很久,反复实验才编译及实验成功;写入个数,就是实际需要的字符数,比如高低电平1或0就是1个字符,out和in分别为3个和2个字符,长度比数据大才能完整写入,如果写小了,就只能写入前面的几个字符,这个得慢慢理解;文件指针就是打开文件获得的文件指针变量。
2、sleep()延时函数
这个延时函数定义在unistd.h头文件里,我也是慢慢查看BBB板里的头文件才找出来,原来套用网上的一些程序总是出错,头文件也乱列了N个。最后还是自己从BBB板里找出来,确认清楚,所以学习BBB板的文件系统和相关库函数的头文件很重要。
sleep(N秒),使用很简单,参数就是秒,要几秒就写几秒。
3、关闭文件指针fclose()函数
fclose(文件指针),文件打开使用完毕都要关闭,否则在编译执行会报错。
4、文件数据传递读函数
fscanf(文件指针,输出格式,传递变量),通过这个函数把fopen()打开的文件数据传递到变量,BBB板我们使用的变量要定义为字符串数组,输出格式为”%s”,就行了。其他的东西大家自己去挖掘吧。我的课程里主要是把BBB板相关的东西写出来。
二、简单的函数测试
测试前提:先登陆BBB板的终端模式,进入/sys/class/gpio目录下通过echo命令手动打开gpio44端口,因为程序打开端口较复杂,这里只是进行简单的输出测试。
1、读写输出函数实验:点亮和关闭指示灯
#include
#define GPIO_DIR "/sys/class/gpio/gpio44/"
int main()
{
FILE*stream=NULL;
stream=fopen(GPIO_DIR"direction","r+"); /*读写模式打开direction*/
fwrite("out",sizeof(char),3,stream); /*设置为输出模式*/
fclose(stream);
stream=fopen(GPIO_DIR"value","r+"); /*读写模式打开value*/
fwrite("1",sizeof(char),1,stream); /*输出高电平1,二极管灯亮*/
fclose(stream);
return 0;
}
把以上程序编译执行后,接在P8.12端口上的二极管指示灯一定点亮了。然后修改程序,输出低电平0,指示灯就关掉了。
fwrite("0",sizeof(char),1,stream); /*输出低电平0,二极管灯灭*/
还有个问题要说下,就是在BBB板上的编译和执行,比如这个小程序保存为/home/binc/led2.cpp,其中binc目录是我自己在home目录下建立的,专门做实验用的目录,在当前目录下编译的指令是这样的:(led2是编译想得到的可执行程序名,随意写)
/home/binc# g++ -o led2 led2.cpp
运行程序这样执行:(./ 这两字符是必须的,不同于shell脚本用bash led2)
/home/binc# ./led2
注意:如果你的BBB板上编译时提示没有g++命令,可能是环境变量没设置好,那就得把g++命令的全路径写上就可以了。
2、LED灯每秒闪亮1次共5次实验
再编写如下程序,或者修改上一程序led2.cpp,增加个for语句,这里循环5次,你可以根据自己喜欢改多几次,主要是多感受一次,熟悉下相关函数。
#include
#include
#define GPIO_DIR "/sys/class/gpio/gpio44/"
int main()
{
FILE *stream=NULL;
int i=0;
stream=fopen(GPIO_DIR"direction","r+"); /*读写模式打开direction*/
fwrite("out",sizeof(char),3,stream); /*设置为输出模式*/
fclose(stream);
for (i=0;i<5;i++)
{
stream=fopen(GPIO_DIR"value","r+");
fwrite("1",sizeof(char),1,stream); /*输出高电平1,二极管灯亮*/
sleep(1); /*延时一秒*/
fclose(stream);
stream=fopen(GPIO_DIR"value","r+");
fwrite("0",sizeof(char),1,stream); /*输出低电平0,二极管灯灭*/
sleep(1); /*延时一秒*/
fclose(stream);
}
return 0;
}