[SAM4N学习笔记]按键程序(中断方式)

1、准备工做:

     将上一节搭建的工程复制一份,命名为“6.key interrupt”。这一节主要讲如何使用SAM4N的GPIO中断功能,实现按键的中断输入。函数

2、程序编写:

     这个程序主要是在上一个程序中进行改进,实现按键的中断输入。wps_clip_image-6949this

上图能够看出按键一边链接在PA30上面,一边链接到GND,当按下按键时,PA30管脚的电平会被拉低,将按键管脚设置成上拉电阻方式,这样松开按键时PA30会被拉高。blog

因此要实现按键的输入中断能够捕获PA30的上升沿或是降低沿。ip

#define USER_BUTTON (0x01UL<<30)get

/************************************************************it

*函数名: Key_GPIO_Config()io

*参 数 :voidtest

*返回值:voidcli

*功 能 :按键GPIO的初始化函数,使用按键前必须先调用此函数进行初始化配置

*************************************************************/

void Key_GPIO_Config(void)

{

/*禁止外设管理控制寄存器(PMC)写保护*/

  PMC->PMC_WPMR = 0x504D4300;

    /*使能PIOA时钟*/

  PMC->PMC_PCER0 = (1UL << ID_PIOA); 

/*使能外设管理控制寄存器(PMC)写保护*/

  PMC->PMC_WPMR = 0x504D4301; 

  /*使能USER_BUTTON管脚,对应为PA30*/

PIOA->PIO_PER=(USER_BUTTON);

/*禁止USER_BUTTON管脚*/

PIOA->PIO_ODR=(USER_BUTTON);

/*使能USER_BUTTON管脚的上拉电阻,设置为上拉*/

PIOA->PIO_PUER=(USER_BUTTON);

/*使能USER_BUTTON管脚滤波功能*/

PIOA->PIO_IFER=USER_BUTTON;

/*使能USER_BUTTON管脚中断功能*/

PIOA->PIO_IER=USER_BUTTON;

    /*使能USER_BUTTON管脚中断为其余中断触发*/

PIOA->PIO_AIMER=USER_BUTTON;

    /*使能USER_BUTTON管脚中断为边沿触发*/

PIOA->PIO_ESR=USER_BUTTON;

/*使能USER_BUTTON管脚中断为上降沿触发*/

PIOA->PIO_REHLSR=USER_BUTTON;

PIOA->PIO_ISR;

/*配置PIOA的先占优先级为1,从优先级为1*/

   NVIC_SetPriority(PIOA_IRQn, ((0x01<<3)|0x01));

/*使能PIOA的中断通道*/

    NVIC_EnableIRQ(PIOA_IRQn);

}

   第一步,打开PIOA的时钟,接着使能PIOA30的GPIO功能,而后禁止PIOA30的输出,只做为输入功能,接着使能PIOA30的上拉电阻。第二步,打开PIOA30管脚的滤波功能,这样能够起到一个硬件消抖的做用,而后经过PIO_IER寄存器使能PIOA30的中断功能。默认状况下中断会被设置成边沿触发,这明显不是咱们要的,咱们须要的是降低沿触发或上升沿触发。SAM4N的GPIO中断提供边沿触发、降低沿触发、上升沿触发、低电平触发、高电平触发五种类型。除了边沿触发为默认方式外,其余方式类型须要经过配置。首先配置PIO_AIMER寄存器,使能其余中断模式,接着配置PIO_ESR寄存器,使能上升/降低沿触发方式,最后配置PIO_REHLSR寄存器,配置成上升沿触发方式,下面是结构图:

wps_clip_image-22211

     接着须要设置PIOA向量中断优先级,最后使能PIOA的向量中断。在PIOA的中断函数中写中断处理程序:

   /***************************************************************

* 函数名:PIOA_Handler()

* 参数  :void

* 返回值:void

* 描述  :PIOA管脚中断服务函数

*************************************************************/

void PIOA_Handler(void)

/*检测是否为USER_BUTTON引起的中断*/

  if((PIOA->PIO_ISR&USER_BUTTON)!=0)

{

     printf("USER_BUTTON按键被按下\r\n");

   }

}

   这里咱们须要读取PIOA的PIO_ISR寄存器,判断是否是PIOA30中断,读取中断寄存器之后,中断标志位会自动清除,若是在这里不读去这个PIO_ISR,中断不清楚将会连续触发,这点须要注意。

   在PIOA30中断后,也是打印按键被按下的信息到串口。

在main函数中只要去初始化按键便可:

int main(void)

{

systick_hw_init();

led_hw_init();

UART0_Init(115200);

Key_GPIO_Config();

UART0_SendString("this is a key test demo!\r\n");

while(1){

  PIOB->PIO_CODR=(0x01<<LED0_PIN);

delay_ms(200);

  PIOB->PIO_SODR=(0x01<<LED0_PIN);

   delay_ms(200);

}

}  

  和上一个程序同样,下载运行,按下按键串口会打印出以下信息:

wps_clip_image-1673

相关文章
相关标签/搜索