• 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

  • 相关阅读:
    java实现oracle数据库基本操作
    在Myeclipse中用Java语言操作mysql数据库
    Linux面试题
    Python fabric远程自动部署简介
    使用RobotFramework的DataBaseLibrary(Java实现)
    如何编写Robot Framework测试用例2(测试用例语法1)
    如何编写Robot Framework测试用例1(基本格式篇)
    使用远程接口库进一步扩展Robot Framework的测试能力
    TweenLite参数说明 中文翻译
    TweenFilterLite参数说明 中文翻译
  • 原文地址:https://www.cnblogs.com/chineseboy/p/2970163.html
Copyright © 2020-2023  润新知