|
目前树莓派python版本的硬件驱动库只能使用GPIO,SPI等,很多外设的功能都没办法用.
可以使用mmap映射物理地址,直接操作外设的寄存器,这样树莓派的整个硬件资源就可以打通了.下面是通过操作GPIO寄存器控制一个引脚的例子,其他的外设也可以参照操作.
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h> // 文件打开、加锁等操作
- #include <unistd.h> // unistd.h 是 C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称。是Unix Standard的缩写。
- #include <errno.h> // errno.h是C语言C标准库里的头文件,定义了通过错误码来回报错误信息的宏:
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h> // 内存管理,包括POSIX 共享内存 (进程间通信)与内存映射文件
- #define PERIPH_BASE_RPI2 0x3F000000
- #define GPIO_OFFSET 0x00200000
- typedef struct
- {
- uint32_t fsel[6]; // GPIO Function Select
- uint32_t resvd_0x18;
- uint32_t set[2]; // GPIO Pin Output Set
- uint32_t resvd_0x24;
- uint32_t clr[2]; // GPIO Pin Output Clear
- uint32_t resvd_0x30;
- uint32_t lev[2]; // GPIO Pin Level
- uint32_t resvd_0x3c;
- uint32_t eds[2]; // GPIO Pin Event Detect Status
- uint32_t resvd_0x48;
- uint32_t ren[2]; // GPIO Pin Rising Edge Detect Enable
- uint32_t resvd_0x54;
- uint32_t fen[2]; // GPIO Pin Falling Edge Detect Enable
- uint32_t resvd_0x60;
- uint32_t hen[2]; // GPIO Pin High Detect Enable
- uint32_t resvd_0x6c;
- uint32_t len[2]; // GPIO Pin Low Detect Enable
- uint32_t resvd_0x78;
- uint32_t aren[2]; // GPIO Pin Async Rising Edge Detect
- uint32_t resvd_0x84;
- uint32_t afen[2]; // GPIO Pin Async Falling Edge Detect
- uint32_t resvd_0x90;
- uint32_t pud; // GPIO Pin Pull up/down Enable
- uint32_t pudclk[2]; // GPIO Pin Pull up/down Enable Clock
- uint32_t resvd_0xa0[4];
- uint32_t test;
- } __attribute__((packed, aligned(4))) gpio_t;
- volatile gpio_t * gpio;
- void GPIO_WriteHigh(gpio_t * gpio, int pin)
- {
- if (pin > 53)
- return;
- int reg = pin >> 5;
- int offset = (pin & 0x1F);
- gpio->set[reg] |= (1 << offset);
- }
- void GPIO_WriteLow(gpio_t * gpio, int pin)
- {
- if (pin > 53)
- return;
- int reg = pin / 32;
- int offset = pin % 32;
- gpio->clr[reg] |= (1 << offset);
- }
- typedef enum
- {
- GPIO_Function_Input = 0,
- GPIO_Function_Output = 1,
- GPIO_Function_Alternate0 = 2,
- GPIO_Function_Alternate1 = 3,
- GPIO_Function_Alternate2 = 4,
- GPIO_Function_Alternate3 = 5,
- GPIO_Function_Alternate4 = 6,
- GPIO_Function_Alternate5 = 7
- }GPIO_FUNCTION_SEL;
- void GPIO_SetMode(gpio_t * gpio, int pin, GPIO_FUNCTION_SEL sel)
- {
- if (pin > 53)
- return;
- int reg = pin / 10;
- int offset = (pin % 10) * 3;
- gpio->fsel[reg] &= ~(0x00000007 << offset);
- gpio->fsel[reg] |= (sel << offset);
- }
- int main(int argc, char * argv[])
- {
- int mem_fd;
- mem_fd = open("/dev/mem", O_RDWR);
- if (mem_fd == -1)
- {
- perror("mem");
- exit(0);
- }
- gpio = mmap(0, sizeof(gpio_t), PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, (PERIPH_BASE_RPI2 + GPIO_OFFSET));
- if (gpio == MAP_FAILED)
- {
- perror("mmap");
- exit(0);
- }
- GPIO_SetMode(gpio, 18, GPIO_Function_Output);
- while (true)
- {
- GPIO_WriteHigh(gpio, 18);
- sleep(1);
- GPIO_WriteLow(gpio, 18);
- sleep(1);
- }
- return 0;
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|