zoukankan      html  css  js  c++  java
  • 外部中断实验

    一、实验目的

    理解中断的基本概念。

    掌握STM32的中断源及中断优先级。

    掌握STM32外部中断技术的基本使用方法。

    掌握STM32中断处理程序的编程方法。

    二、实验内容

    硬件设计原理图如下图1所示:LED的连接在上一节已经介绍过了,在STM32开发板上的按键KEY0是接在PE4上,KEY1是接在PE3上的,KEY2是连在PE2上,WK_UP接在PA0上。

                           

     

     

    三、实验预备知识

    中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加复杂。今天就将来探讨一下关于STM32中的中断系统。

    ARM Coetex-M3内核共支持256个中断,其中16个内部中断,240个外部中断和可编程的256级中断优先级的设置。STM32目前支持的中断共84个(16个内部+68个外部),还有16级可编程的中断优先级的设置,仅使用中断优先级设置8bit中的高4位。

    STM32可支持68个中断通道,已经固定分配给相应的外部设备,每个中断通道都具备自己的中断优先级控制字节PRI_n(8位,但是STM32中只使用4位,高4位有效),每4个通道的8位中断优先级控制字构成一个32位的优先级寄存器。68个通道的优先级控制字至少构成17个32位的优先级寄存器。

    STM32的每个IO口都可以作为中断输入,这点很好用。要把IO口作为外部中断输入,有以下几个步骤:

    1)初始化IO口为输入。

    这一步设置你要作为外部中断输入的IO口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。

    2)开启IO口复用时钟,设置IO口与中断线的映射关系。

    STM32的IO口与中断线的对应关系需要配置外部中断配置寄存器EXTICR,这样我们要先开启复用时钟,然后配置IO口与中断线的对应关系。才能把外部中断与中断线连接起来。

    3)开启与该IO口相对的线上中断/事件,设置触发条件。

    这一步,我们要配置中断产生的条件,STM32可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置。同时要开启中断线上的中断,这里需要注意的是:如果使用外部中断,并设置该中断的EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置EMR位。

    4)配置中断分组(NVIC),并使能中断。

    这一步,我们就是配置中断的分组,以及使能,对STM32的中断来说,只有配置了NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。关于NVIC的详细介绍,请参考前面章节。

    5)编写中断服务函数。

    这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。

    通过以上几个步骤的设置,我们就可以正常使用外部中断了。

    四、实验步骤

    1. 课下完成作业

    按照教材42页-55页,新建工程,命名为“INT+你的学号”,文件夹名和工程名都为“INT+你的学号”(所需的“库函数、HARDWARE和SYSTEM文件夹”在本次实验文件夹中,自已添加即可)。工程建好后,按照教材153页,编写好main()主函数,之后编译。

    1. 2.         实验室完成

    (1)           在课下完成的工程中修改代码,让串口向PC机打印你的“学号姓名”,之后编译、下载到开发板,看现象。

     

    (2)           修改代码实现如下功能

    • 系统开机后,LED0,LED1闪两次,蜂鸣器响一声后停止;
    • 设置中断优先级分组为组3;
    • 按键KEY0抢占优先级为2,响应优先级为0,控制蜂鸣器,按一次,叫一声;
    • 按键KEY1抢占优先级为3,响应优先级为1,控制LED0,按一次,LED0亮一次,再按一次LED0灭;
    • 按键KEY2抢占优先级为3,响应优先级为1,控制LED1,按一次,LED1闪一次;
    • 按键WK_UP抢占优先级为2,响应优先级为1,控制LED0和LED1反转一次;
    • 问KEY0、KEY1、KEY2、WK_UP的中断优先级顺序为?

    KEY0>WK_UP>KEY1=KEY2  (KEY2 KEY2看谁先按下谁优先)

    • KEY0、KEY1、KEY2、WK_UP分别对应的外部中断线为?

    KEY0对于外部中断线 EXTI4

    KEY1对于外部中断线 EXTI3

    KEY2对于外部中断线 EXTI2

    WK_UP 对于外部中断线 EXTI0

    (3)           完成下列问题

    假设KEY3接在PE6上,KEY4接在PE7上,输入方式配置成上拉输入,并分别控制LED0和LED1,每按一次各反转一次。

    • 按键初始化代码KEY_Init(void):

    答:

     

       void  KEY_Init(void)

    {

    GPIO_InitTypeDef   GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

               GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;

               GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

               GPIO_Init(GPIOE,&GPIO_InitStructure);

    }

    • 中断初始化代码EXTIX_Init(void):

    答:

               void EXTIX_Init(void)

              {

               KEY_Init();

               EXTI_InitTypeDef   EXTI_InitStructure;

               NVIC_InitTypeDef   NVIC_InitStructure;

              

               RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

              

           //GPIOE.6  KEY3

               GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource6);

                    EXTI_InitStructure.EXTI_Line=EXTI_Line6;    

                             EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;      

                             EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

                             EXTI_InitStructure.EXTI_LineCmd = ENABLE;

                             EXTI_Init(&EXTI_InitStructure);     

                 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;                

      //优先级

              

                     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        

                   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                                          

                  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                    

                  NVIC_Init(&NVIC_InitStructure);    

      

           //GPIOE.7  KEY3

               GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource6);

                    EXTI_InitStructure.EXTI_Line=EXTI_Line7;    

                             EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;      

                             EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

                             EXTI_InitStructure.EXTI_LineCmd = ENABLE;

                             EXTI_Init(&EXTI_InitStructure);     

                 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;                

      //优先级

                     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        

                   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                                          

                   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                  

                   NVIC_Init(&NVIC_InitStructure);   

    • 中断服务程序函数名为?

    答:

    void EXTI9_5_IRQHandler(void)

    • 编写中断服务程序:

    答:

    void EXTI9_5_IRQHandler(void)

    {

       If (EXTI_GetITstatus(EXTI_Line6)==Set)

     {

    delay_ms(10);

      if(KEY6==1)

       {

       LED0 =!LED1;

    }

                        EXTI_ClearITPendingBit(EXTI_Line6);

    }

    If (EXTI_GetITstatus(EXTI_Line7)==Set)

     {

      delay_ms(10);

    if(KEY7===1)

    {

       LED1 =!LED1;

    }

                       EXTI_ClearITPendingBit(EXTI_Line7);

    }

    }

    • 查看“STM32中文参考手册.pdf”第132-134页,根据“其它STM32F10XXX产品向量表”。

    ü     说明STM32F10xxx有多少个中断源?

    答:  73

     

    ü     EXTI9_5、和EXTI15_10的中断入口地址是多少?

    答: 0x0000_009C

         0x0000_00E0

  • 相关阅读:
    c语言判断最大数
    c语言复制字符
    C语言简单小问题
    c语言实现用指针遍历二维数组
    C语言有趣小程序
    C语言实现输入一个数,输出这个数的立方根
    C语言实现输入一个数,输出这个数的sin值
    c语言实现输出10000内所有素数,5个换一行
    输出10000内所有素数
    判断素数
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/8436439.html
Copyright © 2011-2022 走看看