一板网
发表于: 2015-6-3 13:24:41 | 显示全部楼层

一、准备工作:     


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


二、程序编写:

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

29143958-6cec503df41640ac89bf9ee6ab425d02.png


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


所以要实现按键的输入中断可以捕获PA30的上升沿或是下降沿。



  1. #define USER_BUTTON (0x01UL<<30)

  2. /************************************************************

  3. *函数名: Key_GPIO_Config()

  4. *参 数 :void

  5. *返回值:void

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

  7. *************************************************************/

  8. void Key_GPIO_Config(void)

  9. {

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

  11.   PMC->PMC_WPMR = 0x504D4300;

  12.     /*使能PIOA时钟*/

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

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

  15.   PMC->PMC_WPMR = 0x504D4301;

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

  17. PIOA->PIO_PER=(USER_BUTTON);

  18. /*禁止USER_BUTTON管脚*/

  19. PIOA->PIO_ODR=(USER_BUTTON);

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

  21. PIOA->PIO_PUER=(USER_BUTTON);

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

  23. PIOA->PIO_IFER=USER_BUTTON;

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

  25. PIOA->PIO_IER=USER_BUTTON;

  26.     /*使能USER_BUTTON管脚中断为其他中断触发*/

  27. PIOA->PIO_AIMER=USER_BUTTON;

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

  29. PIOA->PIO_ESR=USER_BUTTON;

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

  31. PIOA->PIO_REHLSR=USER_BUTTON;

  32. PIOA->PIO_ISR;

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

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

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

  36.     NVIC_EnableIRQ(PIOA_IRQn);

  37. }
复制代码
  

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

29143959-ec8e29ff4e7b489da452bfcfdc174112.png      

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



  1.    /***************************************************************

  2. * 函数名:PIOA_Handler()

  3. * 参数  :void

  4. * 返回值:void

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

  6. *************************************************************/

  7. void PIOA_Handler(void)

  8. {

  9. /*检测是否为USER_BUTTON引发的中断*/

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

  11. {

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

  13.    }

  14. }
复制代码


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


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


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



  1. int main(void)

  2. {

  3. systick_hw_init();

  4. led_hw_init();

  5. UART0_Init(115200);

  6. Key_GPIO_Config();

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

  8. while(1){

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

  10. delay_ms(200);

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

  12.    delay_ms(200);

  13. }

  14. }  
复制代码

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


29144000-72ab62703fa14502b41a4abe8ad9f3ba.png



跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 28 | 回复: 31



手机版|

GMT+8, 2024-4-25 18:32 , Processed in 0.037513 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表