用STM32F103C8T6的中断原理点亮一个LED灯(标准库方式)【STM32开发板】

用STM32F103C8T6的中断原理点亮一个LED灯(标准库方式)【STM32开发板】

实验要求

用stm32F103核心板的GPIOA端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。

关于中断

中断的定义及处理流程

计算机在执行程序过程中,当出现异常情况(断电等)或特殊请求(数据传输等)时,计算机暂停现行程序的运行,转向对这些异常情况或特殊请求进行处理,处理完毕后再返回到现行程序的中断处,继续执行原程序,这就是“中断”。中断是单片机实时处理内部或外部事件的一种机制。中断和异常其本质都是对主程序的“中断”。

中断处理流程:中断请求、中断响应、中断服务和中断返回。单重中断的处理流程如下。

在这里插入图片描述

多重中断的处理流程如下。

在这里插入图片描述

STM32的内部中断处理机制

在这里插入图片描述

STM32的外部中断 (EXTI)

STM32芯片之外的外设的中断(I/O端口)由EXTI和NVIC共同负责,即STM32的每一个GPIO引脚都可以配置成一个外部中断触发源。

EXTI(External interrupt/event controller,外部中断/事件控制器)支持19个外部中断/事件请求,每个中断/事件都有独立的触发和屏蔽设置,具有中断模式和事件模式两种设置模式。STM32 EXTI内部功能框图如下。

在这里插入图片描述

GPIO的中断是以组为单位的,同组的外部中断公用一条外部中断线。例如:PA0、PB0、PC0、PD0、PE0、PF0、PG0这些为一组,如果使用PA0作为外部中断源,那么PB0、PC0、PD0、PE0、PF0、PG0就不能同时再作为外部中断使用了,在此情况下,只能使用类似于PB1、PC2这种末端序号不同的外部中断源。

在这里插入图片描述

uEXTI0-EXTI4这5个外部中断有着各自独立的中断服务函数,如EXTI3的中断服务函数为void EXTI3_IRQHandler(void);uEXTI5-9共用一个中断服务函数void EXTI9_5_IRQHandler(void);uEXTI10-15共用一个中断服务函数void EXTI15_10_IRQHandler(void)。

标准库方式的开发环境搭建

STM32F1的Keil固件包的下载安装

在Keil官网 (www.keil.com) 上下载STM32F1的Keil固件包。具体过程是:进入Keil官网后点击 “Products”,点击 “ARM development tools”,进入ARM产品页面后点击 “Public Software Packs”,在 “MDK5 Software Packs” 下方找到Keil,接着在Keil下方找到 “STMicroelectronics STM32F1 Series Device Support”,即STM32F1的Keil固件包,点击“下载”。下载完成后打开该文件,安装固件包即可。

STM32F10x固件库的下载

在ST官网上下载STM32F10x的固件库。

下载完成并解压后的固件库包含_htmresc, Libraries, Project, Utilities四个文件夹以及使用手册和帮助文档。

开发环境的搭建与配置

选择STM32F103C8芯片建立工程后,在工程内Target下建立4个文件夹:User文件夹用于存放主程序 (main.c), 中断程序stm32f10x_it.c和系统文件system_stm32f10x.c; BSP文件夹用于存放用户编写的头文件等,如本次实验的LED.h, LED.c; Core文件夹用于存放core_cm3.c和启动文件startup_stm32f10x_hd.s; FWLib存放STM32标准外设库的src和inc两个文件夹,这两个文件夹下存有各种驱动文件。在该工程文件所在的文件夹下新建这四个文件夹,从STM32固件库复制上述文件及其头文件并粘贴到相应的文件夹。再在工程内将上述文件添加到相应的文件夹。

之后,打开Options,在Target选项页中设置晶振为8MHz,勾选 “Use MicroLIB”(使用Micro库);在Output选项页中勾选 “Create HEX File”(生成HEX文件);在C/C++选项页的Define中输入宏 “USE_STDPERIPH_DRIVER”,并将全部头文件所在的文件夹添加进搜索路径 (include path) 中;在Debug选项页中选择使用ST-Link调试器,点击设置 (settings),选择 “Erase Full Chip”,勾选 “Reset and Run”。这样开发环境的配置就算完成了。

项目编写

LED.h

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"
void LED_Init(void); //函数声明

#endif

LED.c

#include "LED.h"
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypeDef类型的结构体变量
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启GPIOB的时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //选择要使用的I/O引脚,此处选择PB5引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚输出模式为推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚的输出速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStructure); //调用初始化库函数初始化GPIOB端口
}

exti_key.h:

#ifndef __EXTI_KEY_H
#define __EXTI_KEY_H
#include "stm32f10x.h"
void EXTI_Key_Init(void);
#endif

exti_key.c:

#include "exti_key.h"
#include "misc.h"

void EXTI_Key_Init(void)
{	
    //GPIO初始化配置
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); //开启I/O端口的时钟和复用时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
    //初始化NVIC,配置NVIC参数并使能
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure); 
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_ClearITPendingBit(EXTI_Line3);  
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource3); //设置I/O引脚与中断线路的映射关系
    //初始化EXTI,配置EXTI相关参数并使能
	EXTI_InitStructure.EXTI_Line = EXTI_Line3;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
}

main.c

#include "stm32f10x.h"
#include "LED.h"
#include "exti_key.h"

//编写中断服务程序
void EXTI3_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line3) != RESET)
	{
		GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))));
		EXTI_ClearITPendingBit(EXTI_Line3);
	}
}

int main(void)
{
	LED_Init();
	GPIO_ResetBits(GPIOB,GPIO_Pin_5);
	EXTI_Key_Init();
	while(1)
	{
	
	}
}

STM32开发板实现

如下图所示,将STM32开发板插入面包板并与ST-link连接(相接的两接口应同名),分别用导线将开发板两侧的3.3V输出接至面包板两侧的正极槽、接地输入接至面包板两侧的负极槽。将一个LED接在开发板的B5接口上,具体做法是将正极(长管脚)接至正极槽,负极(短管脚)接至开发板B5接口所接在的一槽。再将一根导线的一端接至开发板A3接口所在的一槽。实验时将此导线的另一端接地,观察灯的亮灭变化;再将该导线的接地端拔出,观察灯的亮灭变化。

在这里插入图片描述

代码在Keil中编译完成后,点击“下载”,即可将代码载入STM32单片机中并开始运行。运行结果如下。

在这里插入图片描述

总结

本次实验学习了STM32的中断原理,并将其应用到点灯等简单操作中。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要基于STM32F103C8T6创建并点亮一个LED,你需要进行以下步骤: 1. 配置开发环境:首先,你需要安装Keil MDK软件,并确保你的STM32F103C8T6开发板已正确连接到计算机上。 2. 创建新工程:在Keil MDK软件中,选择“File” -> “New Project”来创建一个新的工程。选择适合你的开发板的芯片型号(STM32F103C8T6),并选择一个合适的存储路径。 3. 配置工程设置:在创建工程后,你需要配置一些工程设置。例如,选择合适的编译器、调试器和目标设备等。 4. 编写代码:在Keil MDK软件中,打开新建的工程,并在源文件夹中创建一个新的C文件。在该文件中编写代码来点亮LED。 下面是一个简单的示例代码,用于点亮一个LED(连接到GPIO Port C的Pin 13): ```c #include "stm32f10x.h" int main(void) { // 使能GPIOC时钟 RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // 配置GPIOC Pin 13为推挽输出模式 GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13); GPIOC->CRH |= GPIO_CRH_MODE13; while (1) { // 点亮LED GPIOC->BSRR = GPIO_BSRR_BS13; // 延时一段时间 for (int i = 0; i < 1000000; i++); // 熄灭LED GPIOC->BSRR = GPIO_BSRR_BR13; // 延时一段时间 for (int i = 0; i < 1000000; i++); } } ``` 5. 编译和下载:在Keil MDK软件中,点击“Build”按钮来编译你的代码。如果编译成功,就可以将生成的可执行文件下载到STM32F103C8T6开发板上进行调试和运行。 以上是基于STM32F103C8T6创建并点亮一个LED的基本步骤。如果你有任何进一步的问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值