STM32实验四:外部中断实验

32F103提供19个外部中断:

0-15:对应外部IO口输入中断

16:连接到PVD输出

17:连接到RTC闹钟事件

18:连接到USB唤醒事件

IO设备线只有16条,但是GPIO口远远不止16个,所以需要映射

ABCDEFG的0都连接在一个线0,中断线每次只能连接到一个IO口上,这样就需要通过配置来决定对应的中断线配置到哪个GPIO上了。

这种映射关系通过:

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

eg:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

中断线2和EXTI2中断线链接,设置好中断线映射后,设置中断线上中断初始化参数来触发IO中断。

初始化通过:

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

同样里面有一个结构体:

EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line=EXTI_Line4; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct中指定的参数初始化EXTI寄存器

可以看到是下降沿触发的,第一个参数中断线标号,第二个中断模式,第三个触发方式,第四个是使能中断线。

设置好了中断线和GPIO的映射关系,又设置好了中断的触发模式等参数,依然是外部中断,涉及到中断我们当然还要设置NVIC中断优先级。(和串口实验一样)

配置完中断优先级后,编写终端服务程序,32一共有6个外部中断函数。编写过程中经常用到两个函数:

1、判断中断线上是否有终端发生(标志位是否置位)

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

2、清除某个中断线上的中断表示位:

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

用于终端服务函数结束之前清除中断标志位。

最后总结IO口外部中断一般步骤:

1、初始化IO口为输入

2、开启Io口复用时钟,设置IO口和中断线的映射管理

3、初始化线上中断,设置触发条件

4、配置终端分组NVIC,并使能中断

5、编写中断服务函数

这次我们要实现的功能是通过中断来检测按键,WKUP蜂鸣器按一次叫一次,再按一次停

KEY2控制DS0,按一次亮再按一次灭

KEY1控制DS1,效果和KEY2一样,KEy0同时控制0,1按一次翻转一次

下面这段例程就是完全按照我们所阐述的中断设定方式进行的:

//外部中断初始化函数
void EXTIX_Init(void)
{
 
       EXTI_InitTypeDef EXTI_InitStructure;
       NVIC_InitTypeDef NVIC_InitStructure;

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟

      KEY_Init();//初始化按键对应io模式

    //GPIOC.5 中断线以及中断初始化配置
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

      EXTI_InitStructure.EXTI_Line=EXTI_Line5;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);         //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //GPIOA.15      中断线以及中断初始化配置
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);

      EXTI_InitStructure.EXTI_Line=EXTI_Line15;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);          //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //GPIOA.0      中断线以及中断初始化配置
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

       EXTI_InitStructure.EXTI_Line=EXTI_Line0;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);        //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


 
      NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;            //使能按键所在的外部中断通道
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;                    //子优先级1
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
      NVIC_Init(&NVIC_InitStructure);        //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;            //使能按键所在的外部中断通道
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2, 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                    //子优先级1
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
      NVIC_Init(&NVIC_InitStructure); 
 
 
       NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;            //使能按键所在的外部中断通道
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2, 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                    //子优先级1
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
      NVIC_Init(&NVIC_InitStructure); 
 
}

 
void EXTI0_IRQHandler(void)
{
  delay_ms(10);    //消抖
    if(WK_UP==1)
    {      
        LED0=!LED0;
        LED1=!LED1;    
    }
    EXTI_ClearITPendingBit(EXTI_Line0);  //清除EXTI0线路挂起位
}
 void EXTI9_5_IRQHandler(void)
{            
    delay_ms(10);   //消抖             
    if(KEY0==0)    {
        LED0=!LED0;
    }
      EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}


void EXTI15_10_IRQHandler(void)
{
  delay_ms(10);    //消抖             
  if(KEY1==0)    {
        LED1=!LED1;
    }
     EXTI_ClearITPendingBit(EXTI_Line15);  //清除LINE15线路挂起位

最后再来看一下主函数:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "exti.h" 
 int main(void)
 {    
 
    delay_init();             //延时函数初始化    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
    uart_init(9600);     //串口初始化为9600
    LED_Init();               //初始化与LED连接的硬件接口 
     EXTIX_Init();        //外部中断初始化
  LED0=0;                //点亮LED
    while(1)
    {        
        printf("OK\n");    
        delay_ms(1000);      
    } 
}

效果跟按键输入输出差不多,但是它是通过中断来进行处理的。这就完全不一样了。

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验三 定时中断实验 一、实验目的 1. 掌握51单片机外部中断的应用。 2. 掌握中断函数的写法。 3. 掌握定时器的定时方法。 4. 掌握LED数码管的显示。 二、实验内容 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来。 2. 用外部中断改变流水灯的方式。 3. 用定时器T1的方式2控制两个LED以不同周期闪烁。 使用定时器T1的方式2来控制P0.0、P0.1引脚的两个LED分别以1s和2s的周期闪烁。 三、实验仿真硬件图 在Proteus软件中建立如下图所示仿真模型并保存。 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来(用中断方式做计数 器)。 2.用外部中断改变流水灯的方式。 中断前:开始时,P0.0~P0.7的8个灯依次点亮。 外部中断0:P0.0~P0.7的左右4个灯闪烁亮8次 外部中断1: P0.0~P0.7的8个灯间隔闪烁8次 改变中断优先级和保护现场,观察运行结果 编程提示 外部中断0请求,由P3.2管脚输入,通过IT0位来决定是低电平有效还是下降沿 有效。一旦输入信号有效,即向CPU申请中断,并建立IE0中断标志。 以外部中断0为例,开放中断源采用以下语句: EA=1; //开放中断总允许位 EX0=1; //开放外部中断0允许位 IT0=1; //置外部中断为边沿(下边沿)触发方式 中断函数结构如下: void int_0() interrupt 0 // interrupt 0表示该函数为中断类型号0的中断函数 { } 同级自然优先级: 外部中断0 定时器T0中断 外部中断1 定时器T1中断 串行口中断。 中断优先级别的设定: 实验二要求: 初始状态为P0.0~P0.7的8个LED显示灯依次循环点亮;外部中断0服务程序为8个LED灯, 左4个,右4个闪烁8次,外部中断1服务程序8个LED灯,间隔闪烁8次。 设定外部中断0为高优先级,先执行外部1中断,过程中用外部0中断来将其中断,反之不 行。注意保护现场。 设定外部中断1为高优先级,先执行外部0中断,过程中用外部1中断来将其中断,反之不 行。注意保护现场。 实验三(调试下列程序,在错误行后面注明错误及改正方法): #include <reg51.h> #define uchar unsigned char; sbit D0=P1^0; sbit D1=P1^1; uchar a,b; void main() { EA=1; ET1=1; TMOD=0x20; TL1=6; TR0=1; a=0; b=0; while(1) ; } void t1() interrupt 1 { a++; b++; if(a=1000) { D0=~D0 a=0; } if(b=4000) { D1=~D1; b=0; } 写出源程序,并注释 实验报告格式 实验三 定时中断实验 学院: 专业: 年级: 实验时间: 姓名: 学号: 指导教师: 一、实验目的 1. 掌握51单片机外部中断的应用。 2. 掌握中断函数的写法。 3. 掌握中断优先级别的使用。 4. 掌握LED数码管的显示。 二、实验内容 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来。 2. 用外部中断改变流水灯的方式。 三、电路图(贴Protues仿真图) 、程序与注释 1)程序1 2)程序2 3)程序3 六、简答题 1)电平触发和下降沿触发在程序中如何设置? 2)如何设置INT1为优先级?何谓优先? 3)中断服务函数的interrupt后面的数字表示什么? 七、体会 ----------------------- 实验3-外部中断实验报告全文共4页,当前为第1页。 实验3-外部中断实验报告全文共4页,当前为第2页。 实验3-外部中断实验报告全文共4页,当前为第3页。 实验3-外部中断实验报告全文共4页,当前为第4页。
STM32F407ZGTX是一款高性能的微控制器,具有强大的外部中断功能。外部中断是通过引脚上的外部信号触发的,可以用于检测、处理外部事件。下面我将以300字回答关于STM32F407ZGTX外部中断实验的问题。 首先,我们需要准备好实验所需的硬件和软件。硬件方面,需要准备一块STM32F407ZGTX开发板和一些外部设备,如按钮或开关等。软件方面,需要使用STM32CubeMX和Keil MDK工具进行代码开发和编译。 接下来,我们可以使用STM32CubeMX来配置外部中断。打开STM32CubeMX,选择对应的芯片型号,创建一个新工程。在Pinout & Configuration选项中,选择需要使用的引脚作为外部中断触发引脚。然后,打开Configuration选项卡,选择相应引脚的GPIO模式为GPIO_EXTI和GPIO模式为EXTI Mode。配置完成后,点击生成代码按钮,并将生成的代码导入到Keil MDK中进行编译和烧录。 接下来,在Keil MDK中进行代码开发。打开生成的代码工程,找到main.c文件,在HAL_GPIO_EXTI_Callback函数中编写对外部中断的处理代码。在这个函数中,可以实现对外部中断触发事件的检测和相应的处理逻辑。例如,可以在按下按钮时,让LED灯亮起或发送一个响应的信号。 最后,编译并烧录代码到STM32F407ZGTX开发板上。连接好外部设备(如按钮)后,运行实验。当外部中断(按钮按下)发生时,相应的处理代码会被触发执行。 要注意的是,实验中还需要注意配置外部中断的触发模式,如上升沿触发、下降沿触发等,可根据实际需求进行配置。 总结来说,STM32F407ZGTX外部中断实验的步骤包括:硬件和软件准备、配置外部中断引脚、编写处理代码、编译和烧录代码,最后进行实验。希望以上回答能帮助到你对STM32F407ZGTX外部中断实验的理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值