本文使用环境:
主控:ZYNQ-7020
一、项目概述
^^^^就是单纯的linux下点灯。偶尔也遇到问这个问题的人,所以就详细的写一篇文章,这篇文章主要是在ZYNQ7020上做的实验,当然也会适配所有的Linux平台,应用不挑硬件。
二、理论
^^^^应用层读写GPIO不需要改写底层的设备树,也不需要编写驱动,较为简单,可以直接查看下一章节的程序。首先简单说一些理论上的知识,都是较为简单的知识。
^^^^首先要理解GPIO的编号,在CPU中每个管脚要对应一个单独的GPIO,所以要查手册直到GPIO的编号。这里以ZYNQ7020为例子:
^^^^7020分MIO和EMIO。MIO是PS的资源,EMIO是PL的资源。(54个MIO+64个EMIO)。本实验使用MIO的资源,EMIO的实验emmmmmmm如下:ZYNQ-Linux下EMIO使用教程,GPIO分配及编号,涉及到vivado中的IO分配。
1. 找到CPU的初始编号
^^^^进入如下文件夹查看:
^^^^从上图可以看到设备中第一个IO编号为903,这个编号属于MIO的编号。即第一个GPIO为gpio903。你需要操作某个GPIO直接找出对应的GPIO编号,比如:我要使用MIO的第10个GPIO对应的编号为:gpio912。注意第一个为903,第十个应该为903+10-1才对。
找到编号后直接进入程序。
二、编程
1、程序流程
2、程序
^^^^无需多言,上代码:
#include <iostream>
#include<string>
#include <cstring>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#define out 0
#define in 1
//led pc11 75
typedef unsigned char u8;
/*函数名:LED_Init
*描 述:LED初始化
*参 数:led_num:GPIO编号; ONorOFF :输出 out 或者输如 in
*返回值: 无
*/
void LED_Init(int led_num, bool dir)
{
FILE *fp=NULL;
char path[64];
fp=fopen("/sys/class/gpio/export","w");
if (fp == NULL)
perror("export open filed");
else
fprintf(fp,"%d",led_num); //创建接口
fclose(fp);
memset(path,0,sizeof path);
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", led_num);//将可变参数格式化成字符串存入path[]
fp = fopen(path,"w");
if(1 == dir)
fprintf(fp,"in"); //设置为输出
else
fprintf(fp,"out"); //设置为输出
fclose(fp);
}
/*函数名:ON_OFF_Lamp
*描 述:输出高或者低
*参 数:led_num:GPIO编号; ONorOFF :输出高 1 或者输出低 0
*返回值: 无
*/
void ON_OFF_Lamp(int led_num, bool ONorOFF)
{
FILE *fp=NULL;
char path[50] = {"\0"};
memset(path,0,sizeof path);
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", led_num);//将可变参数格式化成字符串存入path[]
fp = fopen(path,"w");
fprintf(fp,"out"); //设置为输入
fclose(fp);
sprintf(path,"/sys/class/gpio/gpio%d/value",led_num);
fp = fopen(path,"w");
fprintf(fp,"%d",ONorOFF); //输出ONorOFF值电平
fclose(fp);
}
/*Get_LED_State
*描 述:查询GPIO输入数据
*参 数:led_num:要查询的GPIO
*返回值:GPIO电平 0 1
*/
int Get_LED_State(int led_num)
{
char path[64];
char value_str[3];
int fd;
int n;
FILE *fp=NULL;
memset(path,0,sizeof path);
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", led_num);//将可变参数格式化成字符串存入path[]
fp = fopen(path,"w");
fprintf(fp,"in"); //设置为输入
fclose(fp);
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", led_num); //将可变参数格式化成字符串存入path[]
fd = open(path, O_RDONLY);
if (fd < 0)
{
perror("Failed to open gpio value for reading!");
return -1;
}
if (read(fd, value_str, 3) < 0)
{
perror("Failed to read value!");
return -1;
}
close(fd);
return (atoi(value_str));
}
#define LED 912
int main()
{
LED_Init(LED,out);
while(1)
{
ON_OFF_Lamp(LED,1);
sleep(1);
ON_OFF_Lamp(LED,0);
sleep(1);
printf("LED data:%d \r\n",Get_LED_State(LED));
}
}
3、测试
^^^^运行程序后可以查看设备已经创建好GPIO912。