linux写一个高低电平交替触发中断程序
时间: 2023-06-26 13:05:32 浏览: 129
程序功能为外部8个高电平有效的中断触发源共用外部中断0作为中断触发端口
下面是一个简单的示例程序,可以让GPIO引脚在高低电平间交替触发中断:
```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define GPIO_BASE_ADDR 0x3F200000 // 树莓派GPIO控制器的物理地址
#define BLOCK_SIZE 4096
// GPIO控制器寄存器的偏移地址
#define GPFSEL0 0x00
#define GPFSEL1 0x04
#define GPSET0 0x1c
#define GPCLR0 0x28
#define GPLEV0 0x34
#define GPEDS0 0x40
#define GPREN0 0x4c
#define GPFEN0 0x58
#define GPHEN0 0x64
#define GPLEN0 0x70
#define GPAREN0 0x7c
#define GPAFEN0 0x88
volatile unsigned int *gpio; // 用于存储GPIO控制器寄存器的指针
// 初始化GPIO控制器
void gpio_init() {
int fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd < 0) {
perror("open /dev/mem failed");
exit(-1);
}
gpio = (unsigned int *)mmap(NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE_ADDR);
if (gpio == MAP_FAILED) {
perror("mmap failed");
exit(-1);
}
close(fd);
}
// 设置GPIO引脚为输入模式
void gpio_input(unsigned int pin) {
unsigned int reg = pin / 10;
unsigned int shift = (pin % 10) * 3;
gpio[reg] &= ~(7 << shift);
}
// 设置GPIO引脚为输出模式
void gpio_output(unsigned int pin) {
unsigned int reg = pin / 10;
unsigned int shift = (pin % 10) * 3;
gpio[reg] |= (1 << shift);
}
// 设置GPIO引脚为高电平
void gpio_high(unsigned int pin) {
gpio[GPSET0 / 4] = 1 << pin;
}
// 设置GPIO引脚为低电平
void gpio_low(unsigned int pin) {
gpio[GPCLR0 / 4] = 1 << pin;
}
// 读取GPIO引脚的电平值
int gpio_read(unsigned int pin) {
return (gpio[GPLEV0 / 4] >> pin) & 1;
}
// 设置GPIO引脚触发中断的方式
void gpio_set_edge(unsigned int pin, unsigned int edge) {
unsigned int reg = pin / 32;
unsigned int shift = (pin % 32);
gpio[reg == 0 ? GPREN0 / 4 : GPHEN0 / 4] = edge << shift;
}
// 清除GPIO引脚触发中断的标志位
void gpio_clear_event(unsigned int pin) {
gpio[GPEDS0 / 4] = 1 << pin;
}
int main() {
gpio_init();
gpio_input(17); // 设置GPIO17为输入模式
gpio_output(18); // 设置GPIO18为输出模式
gpio_set_edge(17, 0b10); // 设置GPIO17为上升沿触发中断
while (1) {
if (gpio_read(17)) {
gpio_high(18); // 如果GPIO17的电平为高,则设置GPIO18为高电平
} else {
gpio_low(18); // 如果GPIO17的电平为低,则设置GPIO18为低电平
}
gpio_clear_event(17); // 清除GPIO17的中断标志位
usleep(100000); // 等待100毫秒
}
return 0;
}
```
在上面的程序中,我们使用了树莓派GPIO控制器的物理地址和寄存器偏移地址来控制GPIO引脚的输入输出和中断触发方式。具体来说,我们使用了 `mmap()` 函数将GPIO控制器的物理地址映射到用户空间,通过访问对应的寄存器地址来操作GPIO引脚。在 `main()` 函数中,我们不断地读取GPIO17的电平值,如果它为高电平,则设置GPIO18为高电平;如果它为低电平,则设置GPIO18为低电平。同时,我们还设置了GPIO17为上升沿触发中断的方式,并在每次循环结束时清除GPIO17的中断标志位。这样,当GPIO17的电平从低电平变为高电平时,就会触发中断,从而执行相应的中断处理函数。
阅读全文