gpt4 book ai didi

linux - Beaglebone am335x 通过 mmap、设置和清除引脚访问 GPIO

转载 作者:太空狗 更新时间:2023-10-29 11:23:27 25 4
gpt4 key购买 nike

我正在编写一个简单的程序来设置和清除一个引脚(目的是将该引脚用作自定义 spi_CS)。我能够导出该引脚(gpio1_17,端口 9 引脚 23 bb 白色)并通过文件系统使用它,但我必须更快地驱动它。

这是代码:

uint32_t *gpio;

int fd = open("/dev/mem", O_RDWR|O_SYNC);
if (fd < 0){
fprintf(stderr, "Unable to open port\n\r");
exit(fd);
}

gpio =(uint32_t *) mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO1_offset); // start of GPIOA

if(gpio == (void *) -1) {
printf("Memory map failed.\n");
exit(0);
} else {
printf("Memory mapped at address %p.\n", gpio);
}

printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);
gpio[GPIO_OE/4]=USR1;
printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);

printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);
gpio[GPIO_CLEARDATAOUT/4]=USR1;
printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);


sleep(1);

printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);
gpio[GPIO_DATAOUT/4]=USR1;
printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);

#define GPIO1_offset  0x4804c000
#define GPIO1_size 0x4804cfff-GPIO1_offset
#define GPIO_OE 0x134
#define GPIO_SETDATAOUT 0x194
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_DATAOUT 0x13C
#define USR1 1<<17

我能够输出启用该引脚,因为如果我在运行程序之前将其设置为高电平,那么 ping 信号就会变低。但我无法设置和重置它。有什么想法吗?

最佳答案

为什么要直接修改寄存器?将它用作 linux GPIO 更容易:

#define GPIO_1_17                  "49"                        

int gpio;
status_codes stat = STATUS_SUCCESS;

//Export our GPIOs for use
if((gpio = open("/sys/class/gpio/export", O_WRONLY)) >= 0) {
write(gpio, GPIO_1_17, strlen(GPIO_1_17));
close(gpio);
} else {
stat = STATUS_GPIO_ACCESS_FAILURE;
break;
}

//Set the direction and pull low
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/direction", O_WRONLY)) >= 0) {
write(gpio, "out", 3); // Set out direction
close(gpio);
} else {
stat = STATUS_GPIO_ACCESS_FAILURE;
break;
}
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/value", O_WRONLY)) >= 0) {
write(gpio, "0", 1); // Pull low
close(gpio);
} else {
stat = STATUS_GPIO_ACCESS_FAILURE;
break;
}

然后确保它在您的 init 中作为 gpio 进行复用。

就您上面的 mmap 方法而言,您的寻址看起来是正确的。 ref 手册中的地址是字节地址,您使用的是 32 位指针,因此您所拥有的是正确的。但是,这一行:gpio[GPIO_OE/4]=USR1 使 GPIO1 上的每个引脚都成为输出,但 17 引脚除外,它是输入(0 = 输出,1 = 输入)。你可能是这个意思:gpio[GPIO_OE/4] &= ~USR1

另外我相信你的意思是让 gpio[GPIO_SETDATAOUT/4]=USR1;而不是 gpio[GPIO_DATAOUT/4]=USR1;它们都会导致设置 GPIO1_17;但是,使用您所拥有的也会将 GPIO1 上的所有其他引脚设置为 0。

我肯定会推荐使用设计好的内核接口(interface),因为同样由内核控制的 mmap 操作可能会带来麻烦。

祝你好运! :)

编辑: 我的坏人刚刚意识到你说过为什么你不直接通过文件系统驱动它,因为你需要更快地驱动它!您可能还想考虑编写/修改 SPI 驱动程序,以便在您追求速度的情况下在内核领域完成这些工作。 omap gpio 接口(interface)在那里使用起来也很简单,只需请求和设置 : )。

关于linux - Beaglebone am335x 通过 mmap、设置和清除引脚访问 GPIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17831367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com