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.运行结果

在这里插入图片描述

三、总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/15805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【简单易用,新人友好】一个轻量级生物信息学流程框架,从此解决99%的生物信息学流程搭建问题...

生物信息学数据分析流程的搭建是一项繁重而复杂的工作。随着行业的发展&#xff0c;各种生信流程框架层出不穷&#xff0c;比如有: NextflowSnakemakeCWLWDL 各种标准&#xff0c;各种规则&#xff0c;令人眼花缭乱。选择太多&#xff0c;往往令人无所适从。特别是新进入行业的…

小程序的深层了解

一:wxss的全局样式和局部样式 写在文件上,第一个路径会执行全局和局部自带的wxss给wxml,会执行wxml,会执行json和js. 无论那个文件都会执行文件夹内的和外部的app.wxss,但是如果有一样的属性,则看属性的权重,权重一样,则设置局部样式. 二:全局配置 wx:key"写的是data内…

17.7K星开源产品分析平台:Posthog

Posthog&#xff1a;开源洞察&#xff0c;产品优化的得力助手 - 精选真开源&#xff0c;释放新价值。 概览 PostHog是一个全面开源的平台&#xff0c;旨在帮助团队构建更好的产品。它提供了从产品分析到会话回放、功能标志和A/B测试等一系列工具&#xff0c;支持自托管&#x…

读人工智能时代与人类未来笔记14_管控人工智能

1. 管控人工智能 1.1. 历史上的战场进一步推进到与数字网络相连的所有地方 1.2. 数字程序现在控制着一个由众多实体系统构成的庞大且仍在不断增长的领域&#xff0c;而且越来越多的此类系统已实现网络化 1.2.1. 在某些情况下甚至连门锁和冰箱都实现了网络化 1.2.2. 这催生出…

2024年汉字小达人活动4个多月开赛:18道历年选择题和答案、解析

根据近年的安排&#xff0c;2024年第11届汉字小达人比赛还有4个多月就启动&#xff0c;那么孩子们如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。②把历年真题刷…

联想端游联运SDK接入指南

1. 接入流程 本文档主要介绍了 联想PC游戏SDK接入流程、联想游戏提供的功能、接入注意事项等。 1.1. 接入方式 1. 联想游戏SDK2.1版本支持“账号防沉迷支付”接入方式&#xff1b; a. 联想提供账号注册、登录等能力 b. 联想提供防沉迷服务 c. 联想提供游戏内支付 1.2. 对…

【学习笔记】计算机组成原理(八)

CPU 的结构和功能 文章目录 CPU 的结构和功能8.1 CPU的结构8.1.1 CPU的功能8.1.2 CPU结构框图8.1.3 CPU的寄存器8.1.4 控制单元CU和中断系统 8.2 指令周期8.2.1 指令周期的基本概念8.2.2 指令周期的数据流 8.3 指令流水8.3.1 指令流水原理8.3.2 影响流水线性能的因素8.3.3 流水…

数据库-SQL性能分析

SQL执行频率 慢查询日志 慢查询日志记录了所有执行时间超过指定参数&#xff08;long_query_time&#xff0c;单位&#xff1a;秒&#xff0c;默认10秒&#xff09;的所有 SQL语句的日志。 MySQL的慢查询日志默认没有开启&#xff0c;我们可以查看一下系统变量 slow_query_l…

html5 笔记02

目录 01 svg的基本使用 02 svg绘图 03 进程和线程 01 svg的基本使用 svg和canvas的区别: canvas: 1.canvas作为一个容器只有一个dom元素 ,内部元素无法使用dom操作 (canvas不能展开然后选择不到 svg查看元素能选中因为是通过标签控制的) 2.canvas 是配合js完成各种绘制效果 …

指纹识别概念解析

目录 1. 指纹是物证之首 1.1 起源于中国 1.2 发展于欧洲 1.3 流行于全世界 2. 指纹图像 3. 指纹特征 4. 指纹注册 5. 指纹验证 6. 指纹辨识 1. 指纹是物证之首 指纹识别技术起源于中国、发展于欧洲、流行于全世界。自20世纪以来&#xff0c;指纹在侦破刑事案件、解决诉…

水泥超低排平台哪家好?

随着环保政策的加强和绿色发展理念的深入人心&#xff0c;水泥行业的超低排放改造已成为行业发展的新趋势。选择一个合适的水泥超低排平台对于确保改造效果和实现企业的可持续发展至关重要。朗观视觉小编将从多个角度出发&#xff0c;为您提供一份综合评估与选择攻略&#xff0…

[C语言]自定义类型详解:结构体、联合体、枚举

目录 &#x1f680;结构体 &#x1f525;结构体类型的声明 &#x1f525;结构的自引用 &#x1f525;结构体变量的定义和初始化 &#x1f525;结构体内存对齐 &#x1f525;结构体传参 &#x1f525;结构体实现位段&#xff08;位段的填充&可移植性&#xff09; &a…

安装 Ubuntu桌面版,详细步骤(附引导 U盘制作工具)

下载镜像 安装Ubuntu首先要下载镜像包&#xff0c;访问下面网址下载镜像包 https://releases.ubuntu.com/ 选择你要安装的Ubuntu版本 将 .iso 文件保存到所需位置&#xff0c;下面会使用此文件创建可引导 U盘。 制作 Ubuntu 引导 U 盘 首先要找到一个大于4G的U盘&#xff…

猫头虎 解析:为什么AIGC在国内适合做TOB,在国外适合做TOC?

猫头虎 解析&#xff1a;为什么AIGC在国内适合做TOB&#xff0c;在国外适合做TOC&#xff1f; 博主 猫头虎 的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面…

ps进程查看命令详解

1、PS 命令是什么 查看它的man手册可以看到&#xff0c;ps命令能够给出当前系统中进程的快照。它能捕获系统在某一事件的进程状态。如果你想不断更新查看的这个状态&#xff0c;可以使用top命令。 2、ps命令支持三种使用的语法格式 UNIX 风格&#xff0c;选项可以组合在一起…

鸿蒙ArkUI-X平台差异化:【运行态差异化(@ohos.deviceInfo)】

平台差异化 简介 跨平台使用场景是一套ArkTS代码运行在多个终端设备上&#xff0c;如Android、iOS、OpenHarmony&#xff08;含基于OpenHarmony发行的商业版&#xff0c;如HarmonyOS Next&#xff09;。当不同平台业务逻辑不同&#xff0c;或使用了不支持跨平台的API&#xf…

Postman快捷功能-批量断言与快速查询替换

大家好&#xff0c;在我们日常的接口测试工作中&#xff0c;经常需要对接口返回的数据进行断言&#xff0c;以确保接口的正确性。当接口数量较多时&#xff0c;逐个编写断言语句会变得非常繁琐。此外&#xff0c;在接口测试过程中&#xff0c;我们还可能需要频繁地查找和替换某…

Python自动化工具(桌面自动化、Web自动化、游戏辅助)

工具介绍 连点工具是一款可以模拟键鼠后台操作的连点器工具。支持鼠标连点、键鼠脚本录制&#xff0c;支持辅助您实现办公自动化以及辅助游戏操作。功能简洁易用&#xff0c;非常方便操作。连点工具让您在在玩游戏、网购抢购的时候全自动点击鼠标&#xff01;主要功能有&#…

MySQL数据库的数据文件保存在哪?MySQL数据存在哪里

在安装好MySQL数据库使用一段时间后&#xff0c;会产生许多的数据库和数据。那这些数据库的数据文件存放在本地文件夹的什么位置呢 一、默认位置 一般来说MySQL数据库的数据文件都是存放在data文件夹之中&#xff0c;但是根据使用的存储引擎不同&#xff0c;产生的一些文件也…

24李林跌落神坛,880还刷吗?还是换1000、900、660?

“李林今年跌落神坛了&#xff01;” “全是固定题型没新题&#xff0c;结果今年考的全是新题。” 880是“老真题的神”&#xff0c; 遇到24年&#xff0c;冷门考点多&#xff0c;计算量又大&#xff0c;就不灵了。 但“老真题”&#xff0c;还是得刷。就像往年真题是要刷的…