中断编程入门

STM32第十节(中级篇):EXTI(第二节)——GPIO外部中断代码讲解 好久不见,从今天开始我们接着学习有关EXTI中断的内容。本节课我们通过分析GPIO外部中断代码来讲解我们新的知识点。 阅读详情

 实验一

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

一、硬件连接
将LED连接到STM32F103核心板的GPIOA端口的一个引脚。将开关(用杜邦线模拟)连接到STM32F103核心板的GPIOB端口的一个引脚。
二、STM32中断编程
配置GPIOA引脚为输出模式,用于控制LED。配置GPIOB引脚为输入模式,用于接收开关信号。配置GPIOB引脚的中断,当引脚状态发生变化时触发中断。在中断服务函数中,检测GPIOB引脚的状态,根据高低电平控制LED的亮灭。
三、串口通信
初始化串口通信,设置波特率等参数。在main函数中加入一个定时器,每隔1秒发送一个字符到串口。

代码如下:

#include "stm32f10x.h"

void GPIO_Config(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 配置GPIOA引脚为输出模式,控制LED
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置GPIOB引脚为输入模式,接收开关信号
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置中断线0,用于GPIOB引脚的中断
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发中断
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI0_IRQHandler(void) {
    if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == Bit_SET) {
        GPIO_SetBits(GPIOA, GPIO_Pin_0); // 开关接高电平,LED亮
    } else {
        GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 开关接低电平,LED灭
    }

    EXTI_ClearITPendingBit(EXTI_Line0);
}

int main(void) {
    GPIO_Config();

    while (1) {
        // 主循环中可以放一些其他的操作
    }
}

在这个代码中,配置了一个外部中断线(EXTI0),当GPIOB引脚接收到下降沿信号时,会触发中断,并在中断服务函数EXTI0_IRQHandler中根据开关状态控制LED的亮灭。在main函数中是一个简单的主循环。

内容2:如果完成后,尝试在main函数while循环中加入一个串口每隔1s 发送一次字符的代码片段,观察按键中断对串口发送是否会带来干扰或延迟。

在STM32F103核心板上使用中断模式编程,根据开关的状态控制LED灯的亮灭,并在main函数的while循环中每隔1秒发送一个字符到串口,观察按键中断对串口发送是否会带来干扰或延迟

代码如下:

#include "stm32f10x.h"
#include <stdio.h>

void GPIO_Config(void) {
    // 配置GPIOA引脚为输出模式,控制LED
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置GPIOB引脚为输入模式,接收开关信号
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // 配置中断线0,用于GPIOB引脚的中断
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发中断
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI0_IRQHandler(void) {
    if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == Bit_SET) {
        GPIO_SetBits(GPIOA, GPIO_Pin_0); // 开关接高电平,LED亮
    } else {
        GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 开关接低电平,LED灭
    }

    EXTI_ClearITPendingBit(EXTI_Line0);
}

void USART_Config(void) {
    // 初始化串口通信,设置波特率等参数
    // 请根据具体的串口初始化函数进行配置
}

void sendCharacter(void) {
    // 每隔1秒发送一个字符到串口
    USART_SendData(USART1, 'A');
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

int main(void) {
    GPIO_Config();
    USART_Config();

    while (1) {
        sendCharacter();
        Delay(1000); // 延时1秒
    }
}

在这个代码中,在main函数的while循环中添加了一个定时发送字符到串口的函数sendCharacter()。可以通过观察串口发送是否会受到按键中断的影响来判断是否会带来干扰或延迟。

LED111

实验二:采用串口中断方式重做上周查询方式的串口通信

内容1:当stm32接收到1个字符“s”时,停止持续发送“hello windows!”; 当接收到1个字符“t”时,持续发送“hello windows!”

代码如下:

#include "stm32f10x.h"
#include <stdio.h>

volatile uint8_t continueSending = 1; // 全局变量作为信号灯,控制是否持续发送

void USART_Config(void) {
    // 初始化串口通信,设置波特率等参数
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

    // 配置USART1的TX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1的RX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_Init(USART1, &USART_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能串口接收中断
    NVIC_EnableIRQ(USART1_IRQn); // 使能串口中断
    USART_Cmd(USART1, ENABLE);
}

void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        char receivedChar = USART_ReceiveData(USART1);

        if (receivedChar == 's') {
            continueSending = 0; // 收到字符's',停止发送
        } else if (receivedChar == 't') {
            continueSending = 1; // 收到字符't',持续发送
        }

        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

void sendHelloWindows(void) {
    char helloMsg[] = "hello windows!\r\n";
    uint8_t i = 0;

    while (helloMsg[i] != '\0') {
        USART_SendData(USART1, helloMsg[i]);
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        i++;
    }
}

int main(void) {
    USART_Config();

    while (1) {
        if (continueSending) {
            sendHelloWindows();
        }
    }
}

在这个代码中,使用串口中断方式实现了接收到字符"S"停止发送"hello windows!",接收到字符"T"持续发送"hello windows!"的功能。通过全局变量continueSending作为信号灯来控制是否持续发送。串口中断函数USART1_IRQHandler中判断接收到的字符并作出相应的处理。

内容2:当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”(提示:要将接收到的连续字符保存到一个字符数组里,进行判别匹配。写一个接收字符串的函数。

代码如下:

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

#define MAX_RX_BUFFER_SIZE 50

volatile uint8_t continueSending = 1; // 全局变量作为信号灯,控制是否持续发送
char rxBuffer[MAX_RX_BUFFER_SIZE];
uint8_t rxIndex = 0;

void USART_Config(void) {
    // 初始化串口通信,设置波特率等参数
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

    // 配置USART1的TX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1的RX引脚
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_Init(USART1, &USART_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能串口接收中断
    NVIC_EnableIRQ(USART1_IRQn); // 使能串口中断
    USART_Cmd(USART1, ENABLE);
}

void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        char receivedChar = USART_ReceiveData(USART1);

        rxBuffer[rxIndex++] = receivedChar; // 将接收到的字符保存到缓冲区

        if (rxIndex >= strlen("stop stm32!")) {
            if (memcmp(rxBuffer, "stop stm32!", strlen("stop stm32!")) == 0) {
                continueSending = 0; // 收到"stop stm32!",停止发送
            } else if (memcmp(rxBuffer, "go stm32!", strlen("go stm32!")) == 0) {
                continueSending = 1; // 收到"go stm32!",持续发送
            }

            rxIndex = 0; // 重置缓冲区索引
        }

        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

void sendHelloWindows(void) {
    char helloMsg[] = "hello windows!\r\n";
    uint8_t i = 0;

    while (helloMsg[i] != '\0') {
        USART_SendData(USART1, helloMsg[i]);
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        i++;
    }
}

int main(void) {
    USART_Config();

    while (1) {
        if (continueSending) {
            sendHelloWindows();
        }
    }
}

在这个代码中,使用串口中断方式实现了接收到字符"stop stm32!"停止发送"hello windows!",接收到字符"go stm32!"持续发送"hello windows!"的功能。通过接收到的字符保存到缓冲区rxBuffer,并使用memcmp函数进行匹配判断。

STM32中断编程入门 收获构成了STM32中断编程的基础,为进一步深入学习高级中断应用、优化系统性能及解决实际问题打下了坚实的基础。 阅读详情

相关推荐

无痛安装及初始配置 PHP 8.0.3 + Apache 2.4 + MySQL 8.0

PHP 8.0.3 + Apache 2.4 + MySQL 8.0MySQL 8.0.23 安装下载安装配置环境变量初始化MySQLPHP8.0.3 安装下载安装配置环境变量Apache 2.4 安装下载安装启动 MySQL 8.0.23 安装 下载 到官方网站下载:https://dev.mysql.com/downloads/mysql/ 目前的最新版本是MySQL 8.0.23 在Windows上有两种安装方式,一个是zip压缩文件解压然后配置,另一个是图像化界面安装。 这里选择第一种方法安装:

Kuang Da's Blog 6208

关于引脚复用,不得不提的GPIO_Pin_sources 和GPIO_Pin

今天在端口复用时遇到了困惑,参考:http://www.51hei.com/bbs/dpj-40992-1.html   调整前的代码GPIO_PinAFConfig(GPIOA,GPIO_Pin_9,GPIO_AF_4);GPIO_PinAFConfig(GPIOA,GPIO_Pin_10,GPIO_AF_4);调整后的代码GPIO_PinAFConfig(GPIOA,GPIO_PinSour...

weixin_34138377的博客 3323

实战解析:利用Python requests库高效抓取京东商品评论并构建结构化数据集

本文详细介绍了如何利用Python requests库高效抓取京东商品评论并构建结构化数据集。通过分析京东评论接口、处理反爬机制以及数据解析存储,帮助开发者快速获取电商数据,适用于竞品监控、用户画像构建等商业场景。

weixin_42526415的博客 837

【明解STM32】GPIO应用设计篇之API函数及配置使用技巧

详细的介绍STM32 GPIO相关的AP标准I库函数及配置使用技巧

大道至简,求同存异 3147

S32K3实战:手把手教你用eMIOS模块实现电机PWM控制(附代码)

本文详细解析了NXP S32K3系列MCU的eMIOS模块在电机PWM控制中的应用,从硬件设计到软件实现,再到调试与优化,提供了完整的实战指南。通过eMIOS模块的硬件级PWM生成能力,工程师可以实现高精度的电机控制,适用于汽车电子和工业控制领域。

weixin_42570484的博客 147

gradle报错:A problem occurred configuring root project ‘My Application‘.

即使翻译了,我开始也看不懂,到处找网上教程,但都是改环境变量。马虎的我即使看了很多遍,改了很多遍也没反应过来,今天第一次搞gradle,突然就报错了,打印出。好了我就继续看项目了。

m0_59878789的博客 4091

【物联网】详解STM32的GPIO八种输入输出模式,GPIO各种输入输出的区别、初始化的步骤详解,看这文章就行了(超详细)

推挽输出(Push-Pull Output):推挽输出模式是最常见的GPIO输出模式。在该模式下,引脚可以输出高电平或低电平,同时具有一定的驱动能力。引脚在输出低电平时形成低阻抗,输出高电平时形成高阻抗,可以驱动外部电路。// 初始化推挽输出模式的GPIO GPIO_InitTypeDef GPIO_InitStruct;// GPIO引脚号 GPIO_InitStruct . Mode = GPIO_MODE_OUTPUT_PP;

Goforyouqp的博客 2万+

全球APN信息汇总

全球APN信息,电信APN,移动APN,联通APN,台湾APN,马来西亚APN,俄罗斯APN,日本APN,泰国APN,美国APN,英国APN,法国APN,德国APN,意大利APN,葡萄牙APN,土耳其APN,荷兰APN,丹麦APN,比利时APN,爱尔兰APN,新加坡APN,越南APN,老挝APN,菲律宾APN,印尼APN,泰国APN,柬埔寨APN,巴基斯坦APN,印度APN,奥地利APN,保加利亚APN,捷克APN,立陶宛APN,罗马尼亚APN,挪威APN,希腊APN,匈牙利APN,瑞士APN,乌克兰APN

renkai721的专栏 2796

STM32 中的 GPIO_Pin_n与GPIO_Pinsource_n

STM32 中的 GPIO_Pin_n与GPIO_Pinsource_n

点点星光 5907

SAP RAP 里的 EML 全解:从语言定位到事务语义,再到真实案例的落地方式

摘要:EML(Entity Manipulation Language)是ABAP RAP模型的核心组件,作为ABAP的子集用于操作业务对象(BO)。它通过声明式语法(READ/MODIFY/EXECUTE/COMMIT)统一访问BO的行为与数据,并由RAP运行时自动处理校验、锁定、草稿管理等生命周期。EML将业务语义融入代码,确保与Fiori应用共享同一套校验逻辑,并通过FAILED/REPORTED/MAPPED管道传递错误与消息。其事务控制(IN LOCAL MODE与COMMIT ENTITIES)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 528

Android 13.0 framework默认沉浸式导航栏功能实现

​ 在13.0的系统rom定制化开发中,在实现导航栏的某些定制化开发中,在某些产品需要实现沉浸式导航栏,就是需要app 能全屏显示同样也能显示导航栏,接下来就来分析下相关的功能实现 ​

安卓兼职framework和app工程师的博客 467

[STM32]中断编程入门

本次学习使用中断点灯+发送接收数据。初学多有不足,请多指教。

weixin_50037440的博客 1045

PINNACLE:PINN自适应配点与实验点选择算法

PINNACLE算法通过引入动态权重机制,实现了PINN训练点选择的自适应优化。该算法基于对训练过程中不同区域学习需求变化的深入理解,设计了平滑过渡的权重函数,确保了模型在不同训练阶段能够优先学习最需要的区域。理论分析和实验结果均表明,PINNACLE不仅能够保证收敛性,而且能够显著提高PINN的性能。这一算法为物理信息神经网络的应用提供了重要支持,尤其适用于复杂PDE问题的求解。

VectorShift的博客 1137

【STM32】中断编程入门

中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行。中断优先级:当有多个中断源同时申请中断时,CPU会根据中断源的轻重缓急进行裁决,优先响应更加紧急的中断源。中断嵌套:当一个中断程序正在运行时,又有新的更高优先级的中断源申请中断,CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。EXTI(Extern Interrupt)外部中断。

normog的博客 848

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

第12周——中断编程入门

一、中断原理及其开发编程方法(一)中断概述STM32微控制器的中断功能异常强大,几乎每个外设都能触发中断。中断机制是其关键组成部分,使处理器能够在主程序执行的同时立即响应外部事件。中断可由硬件或软件触发,并且具有高优先级,能够在主程序执行之前执行。通过中断,系统能够异步处理事件,有效提升响应速度和并发处理能力。在STM32中,中断被广泛应用于通信、定时器、ADC、DMA等各种任务。深入理解中断机制对于充分发挥STM32的功能和性能至关重要。1、中断的基本概念和流程(1)中断基本概念。

2301_77432536的博客 1010

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

上一篇: stm32串口通信入门
下一篇: HAL库LED点灯
ooolips
博客等级 码龄4年 129粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值