操作寄存器点亮led(速度快些)

1、现在能找到的寄存器是控制输出值的寄存器,直接对寄存器赋值最快接近2Mhz频率

2、例如开发板上的led是属于416组号的,所以输入命令
cat /sys/class/gpio/gpiochip416/label 得到3022000.gpio 0x3022000是这个组gpio的基址

3、经过测试更改这个地址的值,相应的gpio值也会变,440是led的GPIO编号 例如
写1就这个地址 或一下 0x01<<(440-416)
写0为赋值 ~(0x01<<(440-416))

4、对gpio初始化还是用原来的 两条命令

 echo 440 > /sys/class/gpio/export

 echo out > /sys/class/gpio/gpio440/direction

5、操作寄存器代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> 
#include <sys/mman.h>
#define PAGE_SIZE (0x1000)

static int gpio_fd=0;
static int page_ailgned =0;
static char *gpio_address = NULL;

int main()
{
    int GPIO_BASE_ADDRESS;
    int lishi;
    GPIO_BASE_ADDRESS=0x3022000;//这个组gpio的基址

    gpio_fd=open("/dev/mem",O_RDWR);
    
    if(gpio_fd < 0)
    {
        printf("open /dev/mem failed\r\n");
    }
    else
    {
        page_ailgned = (GPIO_BASE_ADDRESS & (~(PAGE_SIZE - 1)));
        gpio_address = (char *)mmap(NULL,PAGE_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,gpio_fd,page_ailgned);
        if((void *)-1 == gpio_address)
        {
            printf("mmap gpio address failed\r\n");
        }
    }
    
    while(1)
    {
        *((int *)(gpio_address + (GPIO_BASE_ADDRESS-page_ailgned))) |= 0x01<<(440-416);//赋值高电平
    usleep(100000);
        *((int *)(gpio_address + (GPIO_BASE_ADDRESS-page_ailgned))) &= ~(0x01<<(440-416));//赋值低电平
    usleep(100000);
    }
    return 0;
}

6、只需要改代码里的440和416和0x3022000,分别是gpio编号、gpio linux组号、这个组号的基址,其他gpio也可以操作。

7、补充
1. 属于GPIOA下的 为 linux组号为480,基址为0x3020000,gpio编号为 linux组号+GPIOA后面的数字
2.属于GPIOC下的 为 linux组号为416,基址为0x3022000,gpio编号为 linux组号+GPIOC后面的数字
3.属于GPIO下的 为 linux组号为352,基址为0x5021000,gpio编号为 linux组号+GPIO后面的数字

8、方便对寄存器 读写调试程序 代码如下

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> 
#include <sys/mman.h>
#define PAGE_SIZE (0x1000)

static int gpio_fd=0;
static int page_ailgned =0;
static char *gpio_address = NULL;

int main(int argc,char* argv[])
{
    int GPIO_BASE_ADDRESS;
    int lishi;
    sscanf(argv[2],"%x",&GPIO_BASE_ADDRESS);  //读取命令行的第三个字符串

    gpio_fd=open("/dev/mem",O_RDWR);//打开文件
  
    if(gpio_fd < 0)
    {
        printf("open /dev/mem failed\r\n");
    }
    else
    {
        page_ailgned = (GPIO_BASE_ADDRESS & (~(PAGE_SIZE - 1)));
        gpio_address = (char *)mmap(NULL,PAGE_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,gpio_fd,page_ailgned);
        if((void *)-1 == gpio_address)
        {
            printf("mmap gpio address failed\r\n");
        }
    }
    
    if(argv[1][0] == 'r')
    {
        printf("内容:0x%x\r\n",*((int *)(gpio_address + (GPIO_BASE_ADDRESS-page_ailgned))));
    }
    else if (argv[1][0] == 'w')
    {
        sscanf(argv[3],"%x",&lishi);
        *((int *)(gpio_address + (GPIO_BASE_ADDRESS-page_ailgned))) = lishi;
    }
    else
    {
        printf("输入错误,请从新运行!\r\n");
    }

    return 0;
}
1.编译代码,下载到开发板。
2.例如编译出的文件叫main,那么运行命令为  ./main (w或r) (地址) (如果填的是w就需要)
3. (w)为写,(r)为读。第三个参数为写入的数据
4.例如 我要读一个内存命令为 : ./main r 0x3020000
5.例如 我要写一个内存命令为 :./main w 0x3020000 0x00aa
6.地址和写入的值只可以为 0x 开头十六进制,打印出来的值也是十六进制

寄存器补充:
下面的寄存器都是一个gpio只有寄存器的一个比特

1、基址+0x04为 设置 out或in 寄存器 ········out为1
2、基址+0x50为 如果gpio设置为in,gpio的值在这个寄存器
3、例如 基址+0x04需要赋值给 上面代码的GPIO_BASE_ADDRESS

示例 led的gpio------440为编号,416为组号
基址+0x04 |= 0x01 << (440-416) 将gpio设置为out
基址+0x04 &= ~(0x01 << (440-416)) 将gpio设置为in
读 基址+0x50 的第440-416位为值

5 Likes

5、操作寄存器代码如下:这里的代码修改一下,否则点不亮,即基址+0x04为 设置 为out

*((int *)(gpio_address + (GPIO_BASE_ADDRESS-page_ailgned)+0x04)) |= 0x01<<(440-416);//赋值高电平 in–>out

while(1)

echo 440 > /sys/class/gpio/export
cat /sys/class/gpio/gpio440/value
cat /sys/class/gpio/gpio440/direction

/root/gpio_led2 r 0x3022004 #方向 in=0x00000000 out=0x01000000
/root/gpio_led2 r 0x3022000 #值 板载灯GPIOC24 暗=0x00000000 亮=0x01000000
/root/gpio_led2 w 0x3022004 0x1000000 #打开
/root/gpio_led2 w 0x3022000 0x1000000 #亮
/root/gpio_led2 w 0x3022000 0x0000000 #暗

验证一下
cat /sys/class/gpio/gpio440/value
cat /sys/class/gpio/gpio440/direction

大佬你好,请问这个组号是从哪里的呀?
///////////////////////

这是我整理的设置pinmux的工具, gtxzsxxk/cvi_pinmux: MilkV Duo’s pinmux tool (github.com),可能对你有些帮助?