当前位置: 首页 > news >正文

STM32中断编程入门

文章目录

  • 一、 理论部分
    • 1.中断系统
    • 2.中断执行流程
    • 3.NVIC的基本结构
    • 4.EXTI介绍
    • 5.AFIO复用IO口
  • 二、实验目的:学习stm32中断原理和开发编程方法。使用标准完成以下任务:
    • (一)实验一 开关控制LED的亮灭
      • 1.代码部分
      • 2.运行结果
    • (二)实验二 接收单个字符控制发送数据
      • 1.代码部分
      • 2.运行结果
    • (三)实验三 接收字符串控制发送数据
      • 1.代码部分
      • 2.运行结果
  • 三、总结

一、 理论部分

1.中断系统

在这里插入图片描述

2.中断执行流程

在这里插入图片描述

3.NVIC的基本结构

在这里插入图片描述

在这里插入图片描述

4.EXTI介绍

在这里插入图片描述在这里插入图片描述

5.AFIO复用IO口

在这里插入图片描述

二、实验目的:学习stm32中断原理和开发编程方法。使用标准完成以下任务:

用stm32F103核心板的GPIOA端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED亮灯;接低电平时,LED灭灯。
可参考教材课件上的6.4.3示例
采用串口中断方式重做上周的串口通信作业,分别实现:1)当stm32接收到字符“s”时,停止持续发送“hello windows!”; 当接收到字符“t”时,持续发送“hello windows!”(提示:采用一个全局标量做信号灯);2)当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”(提示:要将接收到的连续字符保存到一个字符数组里,进行判别匹配。写一个接收字符串的函数。

(一)实验一 开关控制LED的亮灭

1.代码部分

//exti_key.c文件
#include "exti_key.h"
#include "misc.h"void EXTI_Key_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);  //打开GPIOA和复用输入输出口的时钟//配置GPIO口GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Pin_3;     GPIO_InitStructure.GPIO_Pin = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置NVIC(Nested Vectored Interrupt Controller:嵌套向量中断控制器)NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//配置EXTI(External Interrupt/Event Controller:外部中断/事件控制器)EXTI_InitTypeDef EXTI_InitStructure;EXTI_ClearITPendingBit(EXTI_Line3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource3);EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStructure);}
#include "stm32f10x.h"  
#include "exti_key.h"
#include "LED.h"uint8_t led = 1;
int main()
{GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET); //默认为熄灭EXTI_Key_Init();while(1){}
}void EXTI3_IRQHandler()
{if(EXTI_GetITStatus(EXTI_Line3) != RESET ){led = ~led;if(led == 1){GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);}else{GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);}		EXTI_ClearITPendingBit(EXTI_Line3);}}

2.运行结果

20240519_002

(二)实验二 接收单个字符控制发送数据

采用串口中断方式,当stm32接收到1个字符“s”时,停止持续发送“hello windows!”; 当接收到1个字符“t”时,持续发送“hello windows!”(提示:采用一个全局标量做信号灯);

1.代码部分

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int status = 0;//设置是否发送数据的标志位
int main()
{	//开启GPIOA和USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//实例化控制器的对象GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//先配置GPIO控制器//1.设置PA9为复用推挽输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置为复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(GPIOA,&GPIO_InitStructure);   //老子草了没写这一句,以为只GPIO_Init()一次就可以了,结果忘了这些参数会覆盖的。//2.设置PA10为浮空输入模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置为浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//再配置USART控制器USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //硬件流控制:选择无流控制USART_InitStructure.USART_Mode = USART_Mode_Tx |USART_Mode_Rx; //模式选择发送和接收USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_ClearFlag(USART1, USART_FLAG_TC);USART_Init(USART1,&USART_InitStructure);  //初始化串口1//配置中断源USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//当USART串口接收到数据的时候,就触发USART中断// 4.给这个中断源配置相应的抢占优先级和执行优先级NVIC_InitTypeDef  NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //设置抢占(主)优先级    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;      // 设置子优先级   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             NVIC_Init(&NVIC_InitStructure);    USART_Cmd(USART1,ENABLE);			//使能串口1char transmitArray[18]={"hello windows! \r\n "};   //windows系统串口发送时,用回车换行组合 (\r\n) 来实现换行while(1){	if(status == 1) //标志位status = 1 发送{for(int i=0;i<=17;i++){USART_SendData(USART1,transmitArray[i]);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);  //RESET就是0,表示不符合,TXE的E是empty,表示发送寄存器不符合为空,即里面有东西,还在发送。	}Delay_s(1);}}}void USART1_IRQHandler(void)
{while(USART_GetITStatus(USART1,USART_IT_RXNE) == RESET ) //这里不再是USART_GetFlagStatus、USART_FLAG_RXNE,而是USART_GetITStatus、SART_IT_RXNE,要换成中断{};  uint8_t RData=USART_ReceiveData(USART1);if(RData == 's'){status = 0;}else if (RData == 't'){status = 1;}}

2.运行结果

在这里插入图片描述

(三)实验三 接收字符串控制发送数据

1.代码部分

#include "stm32f10x.h"                  // Device header
#include "Delay.h"void InitRDataArray();int status = 0;//设置是否发送数据的标志位char RDataArray[20];//接收指令的字符数组int main()
{	//开启GPIOA和USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//实例化控制器的对象GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//先配置GPIO控制器//1.设置PA9为复用推挽输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置为复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(GPIOA,&GPIO_InitStructure);   //老子草了没写这一句,以为只GPIO_Init()一次就可以了,结果忘了这些参数会覆盖的。//2.设置PA10为浮空输入模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置为浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//再配置USART控制器USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //硬件流控制:选择无流控制USART_InitStructure.USART_Mode = USART_Mode_Tx |USART_Mode_Rx; //模式选择发送和接收USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_ClearFlag(USART1, USART_FLAG_TC);USART_Init(USART1,&USART_InitStructure);  //初始化串口1//配置中断源USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//当USART串口接收到数据的时候,就触发USART中断// 4.给这个中断源配置相应的抢占优先级和执行优先级NVIC_InitTypeDef  NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //设置抢占(主)优先级    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;      // 设置子优先级   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             NVIC_Init(&NVIC_InitStructure);    USART_Cmd(USART1,ENABLE);			//使能串口1char transmitArray[18]={"hello windows! \r\n "};   //windows系统串口发送时,用回车换行组合 (\r\n) 来实现换行InitRDataArray();  //初始化用来接收指令的字符数组while(1){	if(status == 1) //标志位status = 1 发送{for(int i=0;i<=17;i++){USART_SendData(USART1,transmitArray[i]);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);  //RESET就是0,表示不符合,TXE的E是empty,表示发送寄存器不符合为空,即里面有东西,还在发送。	}Delay_s(1);}}}//初始化字符数组
void InitRDataArray()
{for(int i=0;i<20;i++){RDataArray[i]=0;}
}void USART1_IRQHandler(void)
{int i=0;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//判断中断是接收数据中断{RDataArray[i]= USART_ReceiveData(USART1); //接收字符i++;} if (strcmp(RDataArray,"stop stm32!")==0){status = 0;//结束发送InitRDataArray();  //初始化用来接收指令的字符数组}
else if (strcmp(RDataArray,"go stm32!")==0){status = 1;//发送数据InitRDataArray();  //初始化用来接收指令的字符数组}
}

2.运行结果

在这里插入图片描述

三、总结

我刚把串口通信学得差不多,现在又来了这个中断,中断我感觉比之前学的东西都要难。我也说不出为什么,就是觉得它很抽象。

相关文章:

STM32中断编程入门

文章目录 一、 理论部分1.中断系统2.中断执行流程3.NVIC的基本结构4.EXTI介绍5.AFIO复用IO口 二、实验目的&#xff1a;学习stm32中断原理和开发编程方法。使用标准完成以下任务&#xff1a;&#xff08;一&#xff09;实验一 开关控制LED的亮灭1.代码部分2.运行结果 &#xff…...

《我的阿勒泰》读后感

暂没时间写&#xff0c;记录在此&#xff0c;防止忘记&#xff0c;后面补上!!! 【经典语录】 01、如果天气好的话&#xff0c;阳光广阔地照耀着世界&#xff0c;暖洋洋又懒洋洋。这样的阳光下&#xff0c;似乎脚下的每一株草都和我一样&#xff0c;也把身子完全舒展开了。 02、…...

Android.mk简单介绍、规则与基本格式

文章目录 Android.mk与makefile区别Android.mk规则Android.mk基本格式 Android.mk与makefile区别 Android.mk 和 Makefile 都是用于构建代码项目的构建脚本文件&#xff0c;但是它们在特定上下文中有一些区别&#xff1a; Android.mk: Android.mk 是用于构建 Android 应用或库…...

【MySQL精通之路】InnoDB(3)-MVCC多版本管理

InnoDB是一个多版本&#xff08;MVCC&#xff09;的存储引擎。 它保留有关更改行的旧版本的信息&#xff0c;以支持事务性功能&#xff0c;如并发和回滚。 这些信息存储在称为回滚段的数据结构中的Undo表空间中。 参见“Undo表空间”。 InnoDB使用回滚段&#xff08;rollback…...

uniapp 对接 微信App/支付宝App 支付

相关文档&#xff1a;uni.requestPayment(OBJECT) | uni-app官网 示例代码&#xff1a; import qs from qsasync aliPay(){const { provider } await uni.getProvider({ service:payment })if(provider.includes(alipay)){uni.request({url:后端接口地址,data:{ //传参 },suc…...

cmake配置opencv与boost库

Cmake配置外部依赖库&#xff08;以Opencv和Boost为例&#xff09; Cmake对于外部依赖库&#xff0c;需要知道外部库的头文件路径&#xff0c;库文件路径以及库的名字。比如&#xff0c;对于要使用的Boost库&#xff0c;需要知道头文件的位置&#xff0c;库目录的位置以及库依…...

【Kotlin 一】Kotlin入门知识简介、变量声明、数字类型

1. Kotlin简介 Kotlin旨在解决 Java语言在编码效率和代码质量上存在的问题&#xff0c;并且与Java语言完全兼容。Kotlin通过简化语法、提供更强大的函数以及减少样本代码的编写&#xff0c;使开发者能够更高效地编写代码。Kotlin适用于Android、Web后端开发等多种场景 2.Kotl…...

Java 微信小程序登录(openId方式)

1 需求 在开发微信小程序项目时&#xff0c;登录采用的是openId方式&#xff0c;这是一种用户无感的登录方式&#xff0c;用户点开微信小程序时&#xff0c;去调用后端的登录接口。 核心代码 Slf4j Component public class WeChatUtil {private static final String …...

为何程序员35岁就开始被嫌弃了?程序员该如何避免中年危机?

文章目录 一、为何程序员35岁就开始被嫌弃了&#xff1f;1、技术更新迅速2、职业发展瓶颈3、成本考虑4、年龄歧视5、市场供需变化6、个人因素 二、程序员该如何避免中年危机&#xff1f;1、持续学习与技能更新2、拓展技术广度与深度3、提升软技能4、关注行业趋势与市场变化5、建…...

【2024软考】史上最全!软考刷题+解析大合集(9万字全手工打,货真价实)

计算机基础知识 1.中断向量表用来保存各个中断源的中断服务程序的入口地址。当外设发出中断请求信号&#xff08;INTR&#xff09;以后&#xff0c;由中断控制器&#xff08;INTC&#xff09;确定其中断号&#xff0c;并根据中断号查找中断向量表来取得其中断服务程序的入口地…...

【Spring Security + OAuth2】授权

Spring Security OAuth2 第一章 Spring Security 快速入门 第二章 Spring Security 自定义配置 第三章 Spring Security 前后端分离配置 第四章 Spring Security 身份认证 第五章 Spring Security 授权 第六章 OAuth2 文章目录 Spring Security OAuth21、基于request的授权1…...

失落的方舟台服预下载教程 一键下载+账号注册教程

失落的方舟台服预下载教程 一键下载&#xff0b;账号注册教程 是一款今年备受瞩目的游戏&#xff0c;将于5月30日正式上线&#xff0c;这款游戏搭建在虚幻引擎的基础上&#xff0c;为玩家们带来了极佳的视觉体验。这款游戏秉承着MMO类型游戏一贯的玩法&#xff0c;但是制作组在…...

【启明智显技术分享】SOM2D02-2GW核心板适配ALSA(适用Sigmastar ssd201/202D)

提示&#xff1a;作为Espressif&#xff08;乐鑫科技&#xff09;大中华区合作伙伴及sigmastar&#xff08;厦门星宸&#xff09;VAD合作伙伴&#xff0c;我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…...

人工智能的发展现状,AI将如何改变IT行业,哪些职业将最先失业

文章目录 一、人工智能的发展现状1、技术进展与突破2、商业应用与市场3、挑战与问题4、未来趋势 二、AI将如何改变IT行业1、工作方式的转变&#xff1a;2、未来发展的推动&#xff1a;3、用户服务和体验的提升&#xff1a;4、创新和转型的推动&#xff1a;5、融入日常生活和工作…...

request.js使用Promise.all等待所有请求完成再进行数据赋值

在JavaScript中&#xff0c;使用request.js发送多个并发请求&#xff0c;并使用Promise.all来处理这些请求的结果可以通过以下方式实现&#xff1a; 首先&#xff0c;确保你已经安装了request.js&#xff0c;如果没有&#xff0c;可以通过npm安装&#xff1a; npm install re…...

Java开发者必知的时间处理工具:SimpleDateFormat类详解

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…...

构造函数的用法

c 子类构造函数初始化及父类构造初始化_构造函数对父类进行初始化-CSDN博客...

环形链表Ⅱ-力扣

第一种解法时哈希表&#xff0c;set在使用insert插入时&#xff0c;会返回一个pair&#xff0c;如果pair的值为0&#xff0c;则插入失败&#xff0c;那么返回这个插入失败的节点&#xff0c;就是入环的第一个节点&#xff0c;代码如下&#xff1a; /*** Definition for singly…...

【microros】解决 microros安装过程中的 undefined reference to `fmt::v6 问题

目录 问题解决方案参考链接 问题 在 ubuntu-20 arm 开发板上根据官方文档手动编译安装 microros 过程中&#xff0c;执行 ros2 run micro_ros_setup build_agent.sh 命令时&#xff0c;遇到了 undefined reference to fmt::v6 的问题&#xff0c;大概报错如下&#xff1a; Yo…...

29. 相似矩阵,若尔当型

文章目录 1. 相似矩阵1.1 A T A A^TA ATA正定性证明 2. 相似矩阵2.1 举例2.2 证明相似矩阵具有相同特征值 1. 相似矩阵 假设矩阵A&#xff0c;B为正定矩阵&#xff0c;那么对于任意非零列向量x来说&#xff0c;二次型 x T A x , x T B x x^TAx,x^TBx xTAx,xTBx恒为正 x T A …...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...