sdk模板程序:gpio_irq - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
说明
- AXI_GPIO的中断,只区分CH1和CH2,不区分具体是哪个bit产生的IRQ
- AXI_GPIO的中断,每按键一次,会产生2次中断,上升沿一次,下降沿一次。这让人很难用。
程序
/*
* 使用PS_GPIO实现了按键控制LED功能:
* PS端按键按下→PL端的灯亮起,松开熄灭
* PL端按键按下→PS端的灯亮起,松开熄灭
*/
#include "ACZ702_Lib/COMMON.h"
#define PS_KEY 15
#define PS_LED 11
#define PS_EMIO_KEY (54+0)
#define PS_EMIO_KEY2 (54+1)
#define PS_EMIO_LED (54+2)
uint8_t State=0;
void PS_GPIO_IRQ_Handler(void *CallBackRef, uint32_t Bank, uint32_t Status)
{
if(XGpioPs_IntrGetStatusPin(&GpioPs, PS_EMIO_KEY)) {
State=!State; PS_GPIO_SetPort(PS_LED,State);
printf("ps_emio_key pressed!\r\n");
XGpioPs_IntrClearPin(&GpioPs, PS_EMIO_KEY);
}
if(XGpioPs_IntrGetStatusPin(&GpioPs, PS_EMIO_KEY2)) {
State=!State; PS_GPIO_SetPort(PS_LED,State);
printf("ps_emio_key2 pressed!\r\n");
XGpioPs_IntrClearPin(&GpioPs, PS_EMIO_KEY2);
}
/*
* 说明,不知道为什么ps_io能触发中断,但这里的if函数判断一直为0?但ps_emio可以正常工作
*/
if(XGpioPs_IntrGetStatusPin(&GpioPs, PS_KEY)) {
//if(PS_GPIO_GetPort(PS_KEY)==0){
State=!State; PS_GPIO_SetPort(PS_LED,State);
//printf("ps_io_key pressed!\r\n");
XGpioPs_IntrClearPin(&GpioPs, PS_KEY);
}
}
//GPIO的中断处理程序,只要GPIO通道0有电平变化就会进入该中断
void AXI_GPIO_IRQ_Handler(void *CallbackRef)
{
uint32_t Key_Int_State;
//判断哪一位出现中断(只有bit0和bit1有效,分别对应ch1和ch2,不能区分ch1和ch2中具体是哪个gpio)
//axi-gpio有点扯淡,每按一次按键,会触发2次中断,上升沿一次,下降沿一次。
Key_Int_State = XGpio_InterruptGetStatus(&AXI_GPIO0);
/* ↓↓↓用户处理↓↓↓ */
if(Key_Int_State & 0b00000001) {
State=!State; PS_GPIO_SetPort(PS_LED,State);
// if(AXI_GPIO_GetPin(&AXI_GPIO0,XGPIO_IR_CH1_MASK,0)==1)
// printf("axi_ch1_io_key0 pressed!\r\n");
//
// if(AXI_GPIO_GetPin(&AXI_GPIO0,XGPIO_IR_CH1_MASK,1)==1)
// printf("axi_ch1_io_key1 pressed!\r\n");
}
if(Key_Int_State & 0b00000010) {
}
/* ↑↑↑结束处理↑↑↑ */
//清除中断标志
XGpio_InterruptClear(&AXI_GPIO0, XGPIO_IR_CH1_MASK);
}
/*
* PS_GPIO的地址0xe000a000
*/
int main_gpio_irq(void)
{
//GIC通用中断控制器初始化
ScuGic_Init();
{
//初始化AXI GPIO 驱动程序
AXI_GPIO_Init(&AXI_GPIO0, XPAR_AXI_GPIO_0_DEVICE_ID);
//设置KEY_S1方向
AXI_GPIO_SetPin_Dir(&AXI_GPIO0,XGPIO_IR_CH1_MASK,0,INPUT);
AXI_GPIO_SetPin_Dir(&AXI_GPIO0,XGPIO_IR_CH1_MASK,1,INPUT);
//初始化AXI GPIO中断
AXI_GPIO_Intc_Init(&AXI_GPIO0,XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR,
XGPIO_IR_CH1_MASK, AXI_GPIO_IRQ_Handler);
}
{
//初始化PS端GPIO
PS_GPIO_Init();
PS_GPIO_SetMode(PS_LED, OUTPUT, 0);
//设置PS_KEY(MIO47)方向为输入
PS_GPIO_SetMode(PS_EMIO_KEY, INPUT, 0);
//设置按键PS_KEY的中断为边沿敏感
PS_GPIO_SetInt(PS_EMIO_KEY,XGPIOPS_IRQ_TYPE_EDGE_RISING);
//设置PS_KEY(MIO47)方向为输入
PS_GPIO_SetMode(PS_EMIO_KEY2, INPUT, 0);
//设置按键PS_KEY的中断为边沿敏感
PS_GPIO_SetInt(PS_EMIO_KEY2,XGPIOPS_IRQ_TYPE_EDGE_RISING);
//设置PS_KEY(MIO47)方向为输入
PS_GPIO_SetMode(PS_KEY, INPUT, 0);
//设置按键PS_KEY的中断为边沿敏感
PS_GPIO_SetInt(PS_KEY,XGPIOPS_IRQ_TYPE_EDGE_RISING);
//初始化PS GPIO中断
PS_GPIO_Int_Init(PS_GPIO_IRQ_Handler);
}
while(1)
{
}
return 0;
}
int main(void)
{
main_gpio_irq();
return 0;
}
波形
AXI_GPIO,每按下一次会触发2次中断。上升沿一次,下降沿一次。