查看: 3321|回复: 0

SAM4N试用之按键程序(中断方式)

[复制链接]
  • TA的每日心情
    奋斗
    2015-1-22 18:04
  • 签到天数: 189 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-10-27 22:51:40 | 显示全部楼层 |阅读模式
    分享到:
    一、准备工作:
         将上一节搭建的工程复制一份,命名为“6.key interrupt”。这一节主要讲如何使用SAM4NGPIO中断功能,实现按键的中断输入。
    二、程序编写:
         这个程序主要是在上一个程序中进行改进,实现按键的中断输入。
    图片3.png file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-32720.png
    上图可以看出按键一边连接在PA30上面,一边连接到GND,当按下按键时,PA30管脚的电平会被拉低,将按键管脚设置成上拉电阻方式,这样松开按键时PA30会被拉高。
    所以要实现按键的输入中断可以捕获PA30的上升沿或是下降沿。
    #define USER_BUTTON (0x01UL<<30)
    /************************************************************
    *函数名: Key_GPIO_Config()
    *参 数 :void
    *返回值:void
    *功 能 :按键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的时钟,接着使能PIOA30GPIO功能,然后禁止PIOA30的输出,只作为输入功能,接着使能PIOA30的上拉电阻。第二步,打开PIOA30管脚的滤波功能,这样可以起到一个硬件消抖的作用,然后通过PIO_IER寄存器使能PIOA30的中断功能。默认情况下中断会被设置成边沿触发,这明显不是我们要的,我们需要的是下降沿触发或上升沿触发。SAM4NGPIO中断提供边沿触发、下降沿触发、上升沿触发、低电平触发、高电平触发五种类型。除了边沿触发为默认方式外,其他方式类型需要通过配置。首先配置PIO_AIMER寄存器,使能其他中断模式,接着配置PIO_ESR寄存器,使能上升/下降沿触发方式,最后配置PIO_REHLSR寄存器,配置成上升沿触发方式,下面是结构图:
        图片4.png file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-21988.png
         接着需要设置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");
       }         
    }
       这里我们需要读取PIOAPIO_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);
    }
    }   
      和上一个程序一样,下载运行,按下按键串口会打印出如下信息:
    图片5.png

    6.key(interrupt).rar (168.32 KB, 下载次数: 6)
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 10:39 , Processed in 0.119556 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.