实验三 外部中断实验
一、实验目的
1. 掌握基于固件库进行中断编程(NVIC)的方法
2. 掌握基于固件库进行外部中断编程(EXTI)的方法
二、实验内容
1.基于固件库编程通过检测按键状态控制LED点亮状态。实现当按键按下时流水灯速度变化的目的。可以通过proteus电路仿真也可以下载到开发板上执行(指南者开发板可实现控制不同颜色交替闪烁速度)。
三、预备知识
1. 基于STM32固件库进行编程的方法
2. STM32中断及外部中断编程方法
四、实验设备
1. 硬件环境配置
计算机:Intel(R) Pentium(R) 及以上;
内存:1GB及以上;
实验设备:嵌入式开发平台,USB转串口数据线;
2. 软件环境配置
操作系统:Microsoft Windows XP Professional Service Pack 2;
集成开发环境:Keil μVision5 IDE;
五、实验过程
1.电路设计
2.中断及外部中断初始化过程
STM32中断是通过向NVIC寄存器中写入相应的值来实现的。以下是STM32中断及外部中断初始化的一般过程:
1. 选择要使用的外部中断线:在STM32中,有多个外部中断线可供选择,需要根据具体的应用需求和硬件连接情况来选择使用的外部中断线。
2. 配置GPIO引脚:在使用外部中断时,需要将相应的GPIO引脚设置为中断输入模式,以便能够检测到中断事件。
3. 配置外部中断触发方式:外部中断的触发方式有边沿触发和电平触发两种,需要根据具体的应用需求来选择合适的触发方式。
4. 编写中断服务函数:中断服务函数是处理中断事件的函数,需要根据具体的应用需求编写相应的中断服务函数。
5. 初始化NVIC寄存器:在STM32中,中断优先级通过NVIC寄存器来设置。需要使用NVIC_Configuration()函数来初始化NVIC寄存器,同时设置中断优先级。
6. 注册中断服务函数:在使用外部中断时,需要将编写的中断服务函数注册到相应的中断向量表中。
7. 使能中断:使用NVIC_EnableIRQ()函数来使能外部中断,以便能够检测到中断事件。
3.软件设计及代码
1、定义按键引脚
#ifndef __EXTI_H
#define __EXTI_H
#include "stm32f10x.h"
//引脚定义
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
#define KEY1_INT_EXTI_LINE EXTI_Line0
#define KEY1_INT_EXTI_IRQ EXTI0_IRQn
#define KEY1_IRQHandler EXTI0_IRQHandler
void EXTI_Key_Config(void);
#endif /* __EXTI_H */
2、中断初始化
#include "bsp_exti.h"
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置NVIC为优先级组1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源:按键1 */
NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
/* 配置抢占优先级 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_Key_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/*开启按键GPIO口的时钟*/
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
/* 配置 NVIC 中断*/
NVIC_Configuration();
/*--------------------------KEY1配置-----------------------------*/
/* 选择按键用到的GPIO */
GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
/* 配置为浮空输入 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);
/* 选择EXTI的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
3、中断服务函数
void KEY1_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
// LED1 取反
nCount=0x000FFF;
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
}
3、中断服务函数
void KEY1_IRQHandler(void)
{
//确保是否产生了EXTI Line中断
if(EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET)
{
// LED1 取反
nCount=0x000FFF;
//清除中断标志位
EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
}
}