Linux学习_GPIO中断编程

Linux学习_GPIO中断编程

  • 配置GPIO口为输入/中断
  • 配置GPIO作为中断的触发方式
  • 清零中断状态
  • 控制GPIO与GIC使能中断
  • CPU中断使能
  • start.s函数改写
  • 写处理函数

Linux学习_GPIO中断编程_第1张图片

配置GPIO口为输入/中断

  1. 使能GPIO口(从CCM里面找)
  2. 将该口设置工作在GPIO功能下(从MUX里面找)
  3. 选择该口为输入/输出,中断需要其工作在中断/输入模式下。

配置GPIO作为中断的触发方式

芯片手册的GPIOx部分,可以设置其高电平/低电平/上升沿/下降沿/双边沿触发

清零中断状态

为防止先前留有其他的中断状态产生干扰,先对中断状态进行清除,置位ISR寄存器清除GPIO,并调用clear_gic_irq()函数清除GIC。

控制GPIO与GIC使能中断

  1. 需要在GPIO_IMR寄存器中设置使能,否则该使能位默认置0屏蔽。
  2. 需要利用gic_enable_irq函数使能gic使其工作在irq状态下。(函数输入的中断号从芯片手册找)

CPU中断使能

CPU的CPSR寄存器中有一位:I位,用来使能/禁止中断
可以使用以下汇编指令修改I位:

CPSIE I  ; //清除I位,使能中断
CPSID I  ; //设置I位,禁止中断

CPSIE I ;这一行加入start.s中,放在main函数调用前。

start.s函数改写

加入do_irq函数的定义

do_irq:
		/* 设置SP_irq */
		ldr sp, =STACK_BASE - STACK_SIZE - STACK_SIZE - STACK_SIZE
		
		/* 保存现场 */
		subs lr, lr, #4
		stmdb sp!, {R0-R3,R12,LR}
		
		/* 调用处理函数 */
		bl do_irq_c
		
		/* 恢复现场 */
		ldmia sp!, {R0-R3,R12,PC}^

在_start函数中加入:ldr PC, =do_irq;以将其加入调用

写处理函数

void do_irq_c(void)
{
	int irq;
	GPIO_Type *gpio4 = (GPIO_Type *)0x020A8000;
	/* 1. 分辨中断 */
	irq = get_gic_irq();
	/* 2. 调用处理函数 */
	if (irq == IRQ_GPIO4_0_15)
	{
		if (gpio4->DR & (1<<14)) puts("KEY2 pressed!\n\r");
		else puts("KEY2 released!\n\r");
		gpio4->ISR |= (1<<14);//清除中断源头GPIO
	}
	/* 3. 清除中断 */
	clear_gic_irq(irq);//清除中断控制器gic
}

你可能感兴趣的:(linux,学习,单片机)