开头先吐槽下海思的gpio的寄存器,之前是玩三星的,比较容易理解,海思的gpio玩法,云里雾里的
一:海思的官方文档,关于gpio的介绍
在hisi文档,如下章节有介绍
1:gpio基地址:
2:gpio控制寄存器基地址
3:gpio控制寄存器控制方法;
二。实操举例:
我的项目是控制两个led灯,和按键,分别对应原理图上的:GPIO1_0,GPIO1_1,GPIO2_0
根据手册资料,设置为输出模式是1: 设置为输入模式是0:输出高电平是1:输出低电平是0:
0x01 OUT //0x00 IN
0x01 HIGH //0x00 LOW
1:下面是我定义设置的:
//GPIO1_0
#define GPIO1_0_DIR 0x12141400
#define GPIO1_0_DATA 0x12141004
//GPIO1_1
#define GPIO1_1_DIR 0x12141400
#define GPIO1_1_DATA 0x12141008
//GPIO2_0
#define GPIO2_0_DIR 0x12142400
#define GPIO2_0_DATA 0x12142004
2:DIR的地址怎么来的和怎么控制呢:?
首先我的led要设置为输出模式,输出高或低电平
GPIO1_0_DIR 的地址是怎么来的?
(基地址+ 控制寄存器偏移地址)
所以是( 0x12141000 + 0x400)
GPIO1_1和GPIO1_0基地址是一样的,偏移地址也是一样的
所以也是( 0x12141000 + 0x400)
控制是通过掩码来控制的,bit[7:0],相应的位设置为1则为输出模式,设置为0则为输入模式,默认是输入模式
设置各个gpio不同模式,比如:
0000 0000 //第0个-7个gpio为输入模式
0000 0001 //第0个gpio为输出模式
0000 0000 //第0个-7个gpio为输入模式
0000 0010 //第1个gpio为输出模式
0000 0000 //第0个-7个gpio为输入模式
0000 0011 //第0个和1个gpio为输出模式
现在海思平台,控制台输入命令测试一下:
himm 0x12141400 0x01 //第0个gpio为输出模式
himm 0x12141400 0x02 //第0个gpio为输出模式
himm 0x12141400 0x03 //第0个和1个gpio为输出模式
3:DATA 怎么控制呢?这个可能不好理解
首先我的led要输出高或低电平,就要对对应的寄存器进行写入:
地址是怎么来的?
基地址 + dtat偏移地址:
#define GPIO1_0_DATA 0x12141004
#define GPIO1_1_DATA 0x12141008
[9:2] 对应 [7:0] ,对相应位设置为1,则可以操作,对相应位设置为0,则会被屏蔽:
第九位需要三个字节来表达,所以是 0x000 - 0x3fc
第0个gpio对应是第2bit
0000 0000 0100 就是0x004
GPIO1_0_DATA = 基地址 + dtat偏移地址:
0x12141000 + 004
第1个gpio对应是第3bit
0000 0000 1000 就是0x008
则GPIO1_0_DATA = 基地址 + dtat偏移地址:
0x1214100 + 008
控制GPIO1_0就是对第0位输出0或1
现在海思平台,控制台输入命令测试一下:
himm 0x12141400 0x01 / /第0个gpio为输出模式
himm 0x12141004 0x01 //第0个gpio为高
himm 0x12141004 0x00 //第0个gpio为低
、、、、
控制GPIO1_1就是对第1位输出0或1
现在海思平台,控制台输入命令测试一下:
himm 0x12141400 0x02 / /第1个gpio为输出模式
himm 0x12141008 0x02 //第1个gpio为高
himm 0x12141008 0x00 //第1个gpio为低
控制两个一起亮呢?
himm 0x12141400 0x03 / /gpio为输出模式
himm 0x1214100C 0x03 //gpio为高
himm 0x1214100C 0x00 //gpio为低
关于管脚控制,,如果有gpio有复用的,iic和普通gpio复用,需要先设置寄存器,在如下文档里
如下,设置管脚复用
i2c9_pin_mux()
{
himm 0x1F0010D0 0x1452; #I2C9_SCL
himm 0x1F0010D4 0x1452; #I2C9_SDA
}
gpio_pin_mux()
{
himm 0x1F000000 0x0450; #gpio1_0
himm 0x1F000004 0x0450; #gpio1_1
himm 0x1F000008 0x0450; #gpio1_2
himm 0x1F000030 0x1450; #gpio2_0
}
uart2_pin_mux()
{
himm 0x1F0000E4 0x1551; #UART2_RXD
himm 0x1F0000E8 0x1551; #UART2_TXD
}
二、控制台测试方法
设置4个管脚输出模式,输出高或低
//0x12151020 //0x12151040 //0x12151008 // 0x12151010
//gpio17_3 gpio17_4 gpio17_1 gpio17_2
system("himm 0x12151400 0x1e");// set out mode
system("himm 0x12151010 0x0");//gpio 2 //reset
delay_ms(100);
system("himm 0x12151010 0x04");//gpio 2 //reset
delay_ms(100);
system("himm 0x12151020 0x0");//gpio 3
system("himm 0x12151040 0x0");//gpio 4
system("himm 0x12151008 0xff");//gpio 1
//gpio17_1 = 17 * 8 + 1 根据下面文档介绍,算得编号是137,使用命令查看管脚输出值
echo 137 > /sys/class/gpio/export
cat /sys/class/gpio/gpio137/value
1
可以看到输出是1,
三、hisi官方文档,控制台控制gpio方法
参考hisi官方文档,关于内核态,用户态,怎么控制gpio的,在下面路径里有介绍说明
在控制台或应用层调用system控制这些命令的用法,设置为输出模式,可以直接这样写
文档例程如下
此操作示例通过命令实现对GPIO的读写操作。
步骤 1 在控制台使用echo命令将要操作的GPIO编号export:
echo N > /sys/class/gpio/export
每组GPIO有8个GPIO管脚。
N为要操作的GPIO编号,该编号等于GPIO组号 * 8 + 组内偏移号,例如GPIO4_2的编号为4 * 8 + 2 = 34。
export之后就会生成/sys/class/gpio/gpioN目录
例如:exportGPIO4_2:
echo 34 > /sys/class/gpio/export
步骤 2 在控制台使用echo命令设置GPIO方向:
对于输入:echo in > /sys/class/gpio/gpioN/direction
对于输出:echo out > /sys