stm32 外部事件<按键>中断输入实现过程<寄存器>

前题:

  前面,通过分析中断的那几个库函数实现过程,加上对各种资料的阅读,于是自己也用寄存器实现了按键输入中断,呵呵~~~

  首先,外部事件/中断过程如下:

 A) 配置输入线: I/O口的模式,特性等等;

 B) 配置外部事件,并使能外部事件;

 C) 给该外部事件所带来的中断分组,分级<优先级>;

 D) 中断服务程序:当中断触发后,将跳到该程序中。

按部就班,先说说我的硬件连接:

  按键1     PD^11;

  按键2     PD^12;

  LED1  PD^2;

  LED2  PD^3;

软件实现:

  按键1 按下:led 1、led2 循环亮、灭;按键2按下,led2 独亮。

直接上代码:

1:头文件exit.h

 1 #ifndef _EXIT_H_
 2 #define _EXIT_H_
 3 
 4 #include <stm32f10x.h>
 5 
 6 void ExitInit(void);
 7 void Button_Init(void);
 8 void EXTI_Configuration(void);
 9 void NVIC_Configuration(void);
10 void EXTI15_10_IRQHandler(void);
11 
12 #endif /*_EXIT_H_*/

2 exit.c

  1 #include "exit.h"
  2 
  3 volatile unsigned char Flag = 0;
  4 
  5 /********************************
  6 Name:    Exit_Init
  7 Parameters:    Null
  8 Retural Value:     NULL
  9 Function:    Initialization of interrupt 
 10 ********************************/
 11 
 12 void ExitInit(void)
 13 {
 14   Button_Init();
 15   EXTI_Configuration();
 16   NVIC_Configuration();
 17 }
 18 
 19 
 20 /************************
 21 Name:    Button_Init
 22 Parameters:    Null
 23 Retural Value:     NULL
 24 Function:    Initialization of interrupt 
 25 *************************/
 26 
 27 void Button_Init(void)
 28 {
 29     RCC->APB2ENR |= 0x01; //AFIO clock enable
 30     RCC->APB2ENR |= 0x01 << 5; // I/O  port D clock enable
 31     
 32     GPIOD->CRH &= ~(0x0F << 12); //PD^11 input
 33     GPIOD->CRH |= 0x02 << 14;    //PD^11 up/down input
 34     GPIOD->ODR |= 0x01 << 11;    //up
 35     GPIOD->CRH &= ~(0x0F << 16); //    PD^12 input
 36     GPIOD->CRH |= 0x02 << 18; //PD^12 up/down input
 37     GPIOD->ODR |= 0x01 << 12;  //up
 38 
 39     AFIO->EXTICR[2] &= ~(0x0F << 12);
 40     AFIO->EXTICR[2] |= 0x03 << 12; //mapping pD^11 to EXTI 11
 41     AFIO->EXTICR[3] &= ~(0x0F << 0);
 42     AFIO->EXTICR[3] |= 0x03 << 0;    //mapping pD^12 to EXTI 12
 43 }
 44 
 45 #define ExTI_ADDR_BASE EXTI_BASE
 46 #define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)
 47 
 48 /**********************************************************
 49 
 50 ***********************************************************/
 51 
 52 void EXTI_Configuration()
 53 {
 54     unsigned long tmp = 0;
 55 //    tmp = (unsigned long)ExTI_ADDR_BASE;
 56     EXTI->IMR &= ~(0x03 << 11);     //clear interrupt 11,12
 57     EXTI->EMR &= ~(0x03 << 11); //clear exti  11,12
 58 //    *(volatile unsigned long*)tmp |= 0x1800;
 59     EXTI->IMR |= 0x03 << 11; 
 60 
 61     EXTI->RTSR &= ~(0x03 << 11); //clear rings
 62     EXTI->FTSR &= ~(0x03 << 11); //clear rings
 63 //    tmp = (unsigned long)ExTI_ADDR_BASE;
 64 //    tmp += 0x0C;                 //Falling addr offset
 65 //    *(volatile unsigned long*)tmp |= 0x1800;
 66     EXTI->FTSR |= 0x03 << 11;     
 67 }
 68 
 69 /******************************************************
 70 
 71 *******************************************************/
 72 
 73 
 74 void NVIC_Configuration(void)
 75 {
 76    SCB->AIRCR = AIRCR_VECTKEY_MASK | 0x500;        //PriorityGroup_2
 77    NVIC->IP[40] = 0x10;    //     PriorityGroup_2 \ EXTI15_10_IRQn
 78    NVIC->ISER[1] = 0x01 << 8;
 79 }
 80 
 81 
 82 /********************************************************
 83 
 84 *********************************************************/
 85 
 86 
 87 void EXTI15_10_IRQHandler(void)
 88 {
 89 
 90     if((EXTI->PR & 0x0800) && (EXTI->IMR & 0x0800))
 91     {
 92         Flag = 0;
 93         EXTI->PR |= 0x0800;
 94     }
 95 
 96     if ((EXTI->PR & 0x1000) && (EXTI->IMR & 0x1000))
 97     {
 98         Flag = 1;
 99         EXTI->PR |= 0x1000;
100     }
101 
102 }

Button_Init()函数是对PD^11,PD^12两个I/O的配置:包括模式等等;并将它们作为外部事件中断来使用<开启AFIO时钟和映射中断线>

EXTI_Configuration()外部事件配置:包括触发方式、事件/中断屏蔽的设置。

NVIC_Configuration()配置中断:包括中断分组、优先级、使能/失能。

EXTI15_10_IRQHandler()中断服务例程:如果按键1按下,则Flag = 0; 如果按键2按下,则Flag = 1;Flag为全局变量,后面其他函数可以使用它。另外注意清中断。

3 main.h

1 #ifndef _MAIN_H_
2 #define _MAIN_H_
3 
4 #include <stm32f10x.h>
5 #include "led.h"
6 #include "exit.h"
7 #include "gpio.h"
8 
9 #endif /*_MAIN_H_*/

4 main.c

 1 #include "main.h"
 2 extern volatile unsigned char Flag;
 3 
 4 
 5 int main(void)
 6 {
 7     unsigned long time;
 8     LedInit();
 9     ExitInit();
10     while(1)
11     {
12         if(Flag == 0)
13         {
14             LedOnOff();
15             
16         }else
17             GPIOD->ODR |= 1 << 2;    
18     }
19 }

以上过程原理在前一篇中断函数分析中已经记述了,这里不再赘述。下面附上LED和GPIO的代码配置<其实前面也有了>

 1 #include "led.h"
 2 /******************************************
 3 Name:    LedInit
 4 Parameters:    Null
 5 Retural Value:     NULL
 6 Function:    Initialization of Led
 7 ******************************************/
 8 void LedInit(void)
 9 {
10     GPIO_Configuration();
11 }
12 
13 
14 /******************************************
15 Name:    LedRecyc
16 Parameters:    Null
17 Retural Value:     NULL
18 Function:    On and Off the Led
19 ******************************************/
20 void LedOnOff(void)
21 {
22     volatile unsigned long delay = 2000000;;
23     GPIOD->ODR |= 1 << 2;
24     while(delay--);
25     GPIOD->ODR &= ~(1 << 2);
26     delay = 2000000;;
27     while(delay--);
28     GPIOD->ODR &= 0x0;
29     GPIOD->ODR |= 1 << 3;
30     delay = 2000000;;
31     while(delay--);
32     GPIOD->ODR &= ~(1 << 3);
33     delay = 2000000;;
34     while(delay--);
35 }
 1 #include "gpio.h"
 2 
 3 
 4 /******************************************
 5 Name:    GPIO_Configuration
 6 Parameters:    Null
 7 Retural Value:     NULL
 8 Function:    Initialization of GPIO;
 9 Detailed description:    GPIOD.2: push-pull output,50MHz output rate, high level
10 ******************************************/
11 void GPIO_Configuration(void)
12 {
13     RCC->APB2ENR |= 1 << 5;
14     GPIOD->CRL &= 0xFFFFF0FF;
15     GPIOD->CRL |= 0x3 << 8;
16     GPIOD->ODR &= ~(1 << 2);
17     
18     GPIOD->CRL &= ~(0x0F << 12);
19     GPIOD->CRL |= 0x03 << 12;
20     GPIOD->ODR &= ~(1 << 3);    
21 }

 其余参考前面<stm32 中断库函数分析>

本文来自博客园,作者:鱼竿的传说,转载请注明原文链接:https://www.cnblogs.com/chineseboy/archive/2013/03/19/2970163.html

原文地址:https://www.cnblogs.com/chineseboy/p/2970163.html