君正T40 GPIO接口及操作方法

GPIO是“General Purpose Input/Output”的简称,具有输入输出,功能复用的功能。开发者在开发硬件驱动时往往需要操作GPIO,以控制外设硬件。

ISVP使用Linux标准的GPIOLIB接口。GPIOLIB提供了统一的GPIO申请/释放/设置/获取接口,按照GPIOLIB的设定,需要在Kernel space进行调用。如果是User space需要操作GPIO,有两种方法可以选择:

通过sysfs GPIO接口进行操作
应用程序调用相关的驱动,驱动中实现GPIO的设置
1. GPIOLIB
2.1 头文件及API
GPIOLIB的头文件为:include/linux/gpio.h

在驱动程序中加入头文件引用:

#include <linux/gpio.h>
API在头文件include/asm-generic/gpio.h中定义,例如:
  1. int gpio_request(unsigned gpio, const char *label);
  2. void gpio_free(unsigned gpio);
  3. int gpio_direction_input(unsigned gpio);
  4. int gpio_direction_output(unsigned gpio, int value);
  5. int gpio_get_value(unsigned int gpio);
  6. void gpio_set_value(unsigned int gpio, int value);
  7. int gpio_to_irq(unsigned int gpio);
复制代码
等等。详细的文档说明可参考kernel/Documentation/gpio.txt。

2.2 参考代码
Linux kernel中标准驱动的GPIO操作均使用标准的GPIOLIB,比如Software I2C,Fixed regulator,以及中断等等。

2. sysfs GPIO
sysfs GPIO是Linux标准的用户空间操作GPIO的接口。用户可用过命令行或者应用程序直接设置GPIO的输入/输出,高低电平等属性。一般情况下,GPIO调试或者简单的GPIO应用(比如IR-Cut操作),可通过sysfs GPIO接口进行快速开发。

2.1 内核选项
在内核源码根目录下执行$ make menuconfig命令进入配置界面,选中以下选项:
 
  1. Device Drivers  --->
  2.       -*- GPIO Support  --->
  3.            [*]   /sys/class/gpio/... (sysfs interface)
复制代码
一般情况下,内核的默认配置已经勾选了此选项。

2.2 sysfs GPIO的申请与释放
在操作sysfs GPIO之前需要对其进行申请。值得注意的是,由于申请sysfs GPIO会在内核request_gpio,因此在内核中已经申请过的GPIO在sysfs GPIO再次申请会失败。

申请/释放GPIO方法如下:
 
  1. $ cd /sys/class/gpio
  2. $ echo [gpio_num] > export         #申请GPIO
  3. $ echo [gpio_num] > unexport       #释放GPIO
  4. 注:gpio_num即GPIO号。计算公式为:
  5. PA(n) = 0 * 32 + n
  6. PB(n) = 1 * 32 + n
  7. PC(n) = 2 * 32 + n
复制代码
...
例如:申请PB(10) = 1 * 32 + 10 = 42
 
  1. $ echo 42 > export
复制代码
申请后在/sys/class/gpio目录下即会出现gpio42目录。
 
  1. $ echo 42 > unexport
复制代码
释放后gpio42目录也会消失。释放后的GPIO状态并不会恢复,会保持申请时的状态(电平等)。

2.3 设置输入/输出方式
在申请GPIO后,进入gpioN目录,例如gpio42,进行如下操作:
  1. $ echo out > direction             #设置PB10为输出模式
  2. $ echo in > direction              #设置PB10为输入模式
复制代码
2.4 设置有效电平
gpioN目录下有active_low节点,表示当前GPIO的有限电平,默认为0,其意义为,当输入/输出value为0时,GPIO为低电平,当输入/输出value为1时,GPIO为高电平。同样的,当active_low为1时,当输入/输出value为0时,GPIO为高电平,当输入/输出value为1时,GPIO为低电平。 也就是说,GPIO的真实电平=value^active_low。
 
  1. $ echo 0 > active_low       #value是0,表示低电平。value是1,表示高电平
  2. $ echo 1 > active_low       #value是1,表示低电平。value是0,表示高电平
复制代码
2.5 输入/输出
gpioN目录下有value节点,表示gpioN的电平:当GPIO为输入模式时,读取到value的值异或active_low即为GPIO的电平;当GPIO为输出模式时,写入到value的值异或active_low即为GPIO的输出电平。
 
  1. $ cat value                 #读取电平(输入模式)
  2. $ echo 0 > value            #设置电平(输出模式)
复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
君正 T40 芯片可以使用 GPIO 接口来发送时钟信号,以下是一个发送 CLK 信号的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #define GPIO_BASE 0x01C20800 #define GPIO_SIZE 4096 // GPIO 控制寄存器偏移地址 #define GPIO_SWPORTA_DR_OFFSET 0x00 #define GPIO_SWPORTA_DDR_OFFSET 0x04 volatile unsigned int *gpio_ctrl_regs = NULL; int init_gpio_ctrl_regs() { int mem_fd; void *gpio_map; // 打开 /dev/mem 设备文件 mem_fd = open("/dev/mem", O_RDWR | O_SYNC); if (mem_fd < 0) { perror("open /dev/mem failed"); return -1; } // 映射 GPIO 控制寄存器 gpio_map = mmap(NULL, GPIO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, GPIO_BASE); if (gpio_map == MAP_FAILED) { perror("mmap GPIO failed"); close(mem_fd); return -1; } // 关闭文件句柄,不再需要 close(mem_fd); // 设置 GPIO 控制寄存器映射指针 gpio_ctrl_regs = (volatile unsigned int *)gpio_map; return 0; } // 发送一个 CLK 信号脉冲 void send_clk_signal() { // 置 1 输出 GPIO0 gpio_ctrl_regs[GPIO_SWPORTA_DR_OFFSET] |= (1 << 0); // 短暂延时 usleep(10); // 置 0 输出 GPIO0 gpio_ctrl_regs[GPIO_SWPORTA_DR_OFFSET] &= ~(1 << 0); // 短暂延时 usleep(10); } int main(int argc, char **argv) { // 初始化 GPIO 控制寄存器映射指针 if (init_gpio_ctrl_regs() != 0) { return -1; } // 配置 GPIO0 为输出口 gpio_ctrl_regs[GPIO_SWPORTA_DDR_OFFSET] |= (1 << 0); // 循环发送 CLK 信号脉冲 while (1) { send_clk_signal(); } return 0; } ``` 需要注意的是,以上代码仅供参考,实际使用时需要根据具体硬件平台和接口标准进行修改。同时,为了保证 CLK 信号的精度和稳定性,还需要考虑 CLK 信号的频率、占空比等参数的设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值