[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

相關文章
相關標籤/搜索