3

全志F1C200S嵌入式驱动开发(GPIO输出)

 1 year ago
source link: https://feixiaoxing.blog.csdn.net/article/details/131778696
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

全志F1C200S嵌入式驱动开发(GPIO输出)

嵌入式-老费 于 2023-07-18 08:30:29 发布 546

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】



        和v3s一样,f1c200s本身的外部引脚比较少。所以这个时候,不可避免地,很多引脚的功能就会重叠在一起。这种情况下,我们就要学会取舍了。比如说,如果是学习sd卡的时候,那么spi的相关pin脚其实可以省略下来;如果用不到camera,那么camera的接口也可以被省下来了。至于哪些pin脚bind到哪些功能,这部分需要参考一下具体的芯片手册。



1、芯片手册参考

        目前为止,可以参考的芯片手册主要有两份。一份是F1C200s Datasheet,它主要告诉我们一些芯片的基本信息,比如功能、pin脚、封装等等,它长这个样子,

b0ceee504f544f4e9be9a89d31256ec4.png

        另外一份,就是 F1C200s User Manual,它主要告诉我们寄存器怎么配置,软件驱动代码要怎么写。它是这样的,

19e49e7b09364bbd907db0cde7cf89db.png

        当然,我们今天主要处理的问题是关于GPIO输出的。所以,按道理来说,看第一份文档、也就是F1C200s Datasheet就足够了。第一步,一般先看看哪些引脚可以被配置成gpio功能,

<

嵌入系统中,GPIO驱动是控制IO口的重要手段。在点亮8个LED灯的场景中,我们需要使用8个GPIO口,分别连接到每个LED灯的正极。下面给出一个简单的C语言程序,实现点亮8个LED灯的功能。

首先,我们需要初始化GPIO口,使其可以控制LED灯。以下代码使用Linux内核提供的GPIO API进行初始化:

```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h>

#define GPIO_BASE 0x3F200000 // GPIO控制器基地址 #define GPIO_SIZE 4096 // GPIO控制器内存大小

// GPIO寄存器偏移地址 #define GPFSEL0 0x00 #define GPSET0 0x1C #define GPCLR0 0x28 #define GPPUD 0x94 #define GPPUDCLK0 0x98

// 设置GPIO口的功能模 void set_gpio_mode(int pin, int mode) { volatile unsigned *gpio = NULL; int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) { perror("open"); exit(-1); } gpio = (volatile unsigned *)mmap(NULL, GPIO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); if (gpio == MAP_FAILED) { perror("mmap"); exit(-1); }

int offset = pin / 10; int shift = (pin % 10) * 3; gpio[offset] &= ~(0b111 << shift); // 清除原来的模 gpio[offset] |= mode << shift; // 设置新的模

munmap((void *)gpio, GPIO_SIZE); close(fd); }

// 设置GPIO口的电平 void set_gpio_level(int pin, int level) { volatile unsigned *gpio = NULL; int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd < 0) { perror("open"); exit(-1); } gpio = (volatile unsigned *)mmap(NULL, GPIO_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); if (gpio == MAP_FAILED) { perror("mmap"); exit(-1); }

if (level) { gpio[GPSET0 / 4] = 1 << pin; } else { gpio[GPCLR0 / 4] = 1 << pin; }

munmap((void *)gpio, GPIO_SIZE); close(fd); }

int main() { // 设置GPIO口的功能模输出 for (int i = 0; i < 8; i++) { set_gpio_mode(i, 0b001); }

// 点亮LED灯 for (int i = 0; i < 8; i++) { set_gpio_level(i, 1); usleep(500000); // 延时500ms }

// 关闭LED灯 for (int i = 0; i < 8; i++) { set_gpio_level(i, 0); }

return 0; } ```

在上述代码中,我们首先使用`set_gpio_mode`函数将8个GPIO口设置为输出。然后,使用`set_gpio_level`函数将每个GPIO口的电平设置为高电平,从而点亮LED灯。为了让LED灯持续一段时间,我们使用`usleep`函数进行延时。最后,使用`set_gpio_level`函数将每个GPIO口的电平设置为低电平,关闭LED灯。

需要注意的是,上述代码中使用了Linux内核提供的GPIO API进行GPIO口的控制。在不同的嵌入系统中,GPIO口的控制方可能有所不同,需要根据实际情况进行调整。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK