STM32震动感应控制继电器(使用循环VS使用外部中断EXTI和中断控制器NVIC)

参考:stm32的外部中断 震动感应 控制 继电器
作者:点灯小哥
发布时间: 2021-03-05 22:37:01
网址:https://blog.csdn.net/weixin_46016743/article/details/114417161

参考:STM32震动感应灯
作者:一只小阿大:)
发布时间: 2021-07-09 20:10:02
网址:https://blog.csdn.net/qq_44610809/article/details/118613689

目录

  • EXTI外部中断和NVIC中断控制器
    • EXTI外部中断简介
    • 中断触发方式(上升沿和下降沿)
    • EXTI外部中断结构体(19根中断线、触发方式、使能)
    • NVIC中断控制结构体(中断通道/源 -- EXTI外部中断/串口中断、中断分组、抢占优先级、子优先级)
    • 中断服务函数名(在启动头文件里)
    • 中断函数配置步骤
  • 硬件接线及开发环境
  • 代码编写(使用循环VS使用外部中断)
    • 继电器模块relay.c(PA3)
    • 震动感应模块shake.c(PA1)
    • EXTI外部中断配置exti.c(PA1为中断源)
    • 主函数(main.c)

EXTI外部中断和NVIC中断控制器

EXTI外部中断简介

在这里插入图片描述

在这里插入图片描述

STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器NVIC支持19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发屏蔽设置。STM32F103 的19 个外部中断为:

线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件

从上面可以看出,STM32 供 IO 口使用的中断线只有 16 个,但是 STM32 的 IO 口却远远不止 16 个,那么 STM32是怎么把 16 个中断线和 IO 口一一对应起来的呢?
STM32 这样设计的,GPIO 的管脚GPIOx.0-GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0~15。这样每个中断线对应了最多 7 个 IO 口,以线0为例:它对应了GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,而中断线每次只能连接到 1个 IO 口上,这样就需要通过配置EXTI0[3:0]来决定对应的中断线配置到哪一个GPIO上了

下面我们看看 GPIO 跟中断线的映射关系图(第二张图片右侧):
在这里插入图片描述
在这里插入图片描述

中断触发方式(上升沿和下降沿)

  • 上升沿触发:数字电平从低电平(数字“0”)变为高电平(数字“1”)的那一瞬间叫作上升沿。 上升沿触发是当信号有上升沿时的开关动作,当电位由低变高而触发输出变化的就叫上升沿触发。也就是当测到的信号电位是从低到高也就是上升时就触发,叫做上升沿触发。
  • 下降沿触发:数字电路中,数字电平从高电平(数字“1”)变为低电平(数字“0”)的那一瞬间叫作下降沿。 [1] 下降沿触发是当信号有下降沿时的开关动作,当电位由高变低而触发输出变化的就叫下降沿触发。也就是当测到的信号电位是从高到低也就是下降时就触发,叫做下降沿触发。
  • 边沿触发:既可以上升触发也可以下降触发

上升沿触发 就是当电压从低变高时触发中断
下降沿触发 就是当电压从高变低时触发中断

EXTI外部中断结构体(19根中断线、触发方式、使能)

在这里插入图片描述

  • EXTI_Line:EXTI中断/事件线选择,可选EXTI0至EXTI19这20个中断线
    在这里插入图片描述

  • EXTI_Mode:EXTI模式选择,可选为产生中断模式/产生事件

  • EXTI_Trigger:上升沿/下降沿/双沿触发
    在这里插入图片描述

  • EXTI_LineCmd:使能OR失能

NVIC中断控制结构体(中断通道/源 – EXTI外部中断/串口中断、中断分组、抢占优先级、子优先级)

在misc.h文件中,属于内核寄存器
在这里插入图片描述

在这里插入图片描述
中断通道/中断源(EXTI外部中断源、串口中断源等,注意串口中断不属于EXTI外部中断):
在这里插入图片描述
NVIC中断分组、抢占优先级和子优先级:

在这里插入图片描述

在这里插入图片描述

STM32 将中断分为5 个组,组 0 ~ 4。该分组的设置是由 SCB->AIRCR 寄存器的 bit10 ~ 8 来定义的。NVIC中断分组使用如下的固件库函数:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC中断分组  配置成第二组

在这里插入图片描述

通过这个表,我们就可以清楚的看到组 0~4 对应的配置关系,例如组设置为 3,那么此时所有的 60 个中断,每个中断的中断优先寄存器的高四位中的最高 3 位是抢占优先级,低 1 位是响应优先级。每个中断,你可以设置抢占优先级为 0 ~ 7,响应优先级为 1 或 0。抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。

优先级原则:第一,如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;第二,高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。

举例: 假定设置中断优先级组为 2,然后设置中断 3(RTC 中断)的抢占优先级为 2,响应优先级为 1。中断 6(外部中断> 0)的抢占优先级为 3,响应优先级为 0。中断 7(外部中断 1)的抢占优先级为 2,响应优先级为 0。那么这 3> 个中断的优先级顺序为:中断 7>中断 3>中断 6。 上面例子中的中断 3 和中断 7 都可以打断中断 6 的中断。而中断 7 和中断 3> 却不可以相互打断!

中断服务函数名(在启动头文件里)

在这里插入图片描述

中断函数配置步骤

IO 口外部中断的一般步骤:

  • 1、初始化 IO 口为输入。
  • 2、开启 AFIO(GPIO复用为中断)时钟 - - rcc.h
  • 3、设置 IO 口与中断线的映射关系(配置GPIOA1为中断源) - - gpio.h。
  • 4、初始化线上中断,设置触发条件等 - - exti.h。
  • 5、配置中断分组(NVIC),并使能中断 - - misc.h。
  • 6、编写中断服务函数 - - 启动头文件。
  • 7、判断中断标志位(上升沿/下降沿硬件自动更改标志位)。
  • 8、清除中断标志位(手动)。

通过以上几个步骤的设置,我们就可以正常使用外部中断了。

具体函数:

1、初始化IO的输入

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

2、开启IO口复用时钟

RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

3、设置IO口与中断线的映射关系

GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

4、初始化中断线、触发方式等

EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

5、配置中断分组(NVIC),并使能中断

NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

6、编写中断服务函数

EXTI4_IRQHandler()

7、判断中断线中断状态,是否发生

EXTI_GetITStatus(uint32_t EXTI_Line);

8、清除中断标志位

EXTI_ClearITPendingBit(uint32_t EXTI_Line);

硬件接线及开发环境

硬件平台

stm32最小系统
在这里插入图片描述
软件平台

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。

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

代码编写(使用循环VS使用外部中断)

继电器模块relay.c(PA3)

relay.c

#include "relay.h"
#include "stm32f10x.h"                  // Device headervoid Relay_Init(void)
{GPIO_InitTypeDef Relay_init ;//结构体定义放到开时钟前面//1.使能GPIOA时钟    接入PA3口RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,  ENABLE);//2.GPIOA3结构体配置Relay_init.GPIO_Mode  = GPIO_Mode_Out_PP;//推挽输出Relay_init.GPIO_Pin   = GPIO_Pin_3;Relay_init.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init( GPIOA , &Relay_init);}

单独新建立relay文件夹,里面新建relay.c和relay.h两个文件,先将relay.c文件添加到USER里面,写完第一句代码#include "relay.h"直接编译,relay.h会自动包含到relay.c的子目录下。
若头文件和.c文件不在同一个文件目录下编译将提示找不到头文件,需要手动添加头文件路径。

relay.h

#include "stm32f10x.h"void Relay_Init(void);//先声明,再定义,再调用

震动感应模块shake.c(PA1)

shake.c

#include "shake.h"
#include "stm32f10x.h"                  // Device headervoid Shake_Init(void)
{GPIO_InitTypeDef Shake_init;//1.打开我们的GPIOA时钟      连接PA1引脚RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//2.配置GPIOA1的配置Shake_init.GPIO_Mode  = GPIO_Mode_IPD;  //震动传感器初始为高电平(无振动),有振动就为低电平 检测从高电平到低电平的变化  所以用下拉模式(这个表述不是很懂)Shake_init.GPIO_Pin   = GPIO_Pin_1;Shake_init.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init( GPIOA, &Shake_init);}

shake.h

#include "stm32f10x.h"void Shake_Init(void);

EXTI外部中断配置exti.c(PA1为中断源)

在这里插入图片描述

exti.h

#include "stm32f10x.h"  void Exti_Init(void);

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

exti.c

#include "exti.h"
#include "stm32f10x.h"  // Device header 固件库头文件void Exti_Init(void)
{//1.配置GPIO A1GPIO_InitTypeDef Shake_init;//gpio.h  和shake.c一样的EXTI_InitTypeDef Exti_init;	//exti.hNVIC_InitTypeDef Nvic_init;	//misc.h//使能GPIO和GPIOA复用的时钟  如上图所示RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);  //使能GPIOA的复用时钟//设置GPIOA1为中断源 如上图所示GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,  GPIO_PinSource1); //gpio.h  配置的外部中断源是GPIOA1  是shake震动传感器(GPIOA pin1的复用)//配置NVIC中断组 选第2组(随便选)NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Shake_init.GPIO_Mode  = GPIO_Mode_IPD;  //震动传感器初始为高电平  所以用下拉模式 拉到低电平(不是很懂)Shake_init.GPIO_Pin   = GPIO_Pin_1;Shake_init.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init( GPIOA, &Shake_init);// 2、配置EXTI外部中断 Exti_init.EXTI_Line    = EXTI_Line1; //中断线     因为我们用到的中断源是GPIOA1 所以中断线选择Line1  Exti_init.EXTI_Mode    = EXTI_Mode_Interrupt;//中断模式  还一种是事件模式Exti_init.EXTI_Trigger = EXTI_Trigger_Falling;//振动传感器有振动源————>高电平到底电平 所以选择下降沿触发Exti_init.EXTI_LineCmd = ENABLE; //选使能  还一种是静止模式EXTI_Init(&Exti_init);//头文件最下面的函数///3、配置中断控制器(NVIC)Nvic_init.NVIC_IRQChannel = EXTI1_IRQn; //中断通道 因为我们用到的中断源是GPIOA1所以选择中断通道1Nvic_init.NVIC_IRQChannelCmd = ENABLE;  //使能  找到FunctionalState字眼 右键gotoNvic_init.NVIC_IRQChannelPreemptionPriority = 1;//因为只配置了一个中断 抢占优先级、子优先级随便都设为1NVIC_Init(&Nvic_init);//中断初始化函数//4.编写中断服务函数  写在main函数里
}

主函数(main.c)

main.c

#include "stm32f10x.h" // Device header
#include "relay.h"//这个会找不到头文件,需要手动添加头文件路径  点击魔术棒——选择C/C++——include path
#include "shake.h"//下同
#include "exti.h"void delay(uint16_t time)//ms延时函数
{uint16_t i = 0;while(time--){i=12000;while(i--);}
}
int main(void)
{LED_Init();Relay_Init();Shake_Init();Exti_Init();GPIO_SetBits(GPIOA , GPIO_Pin_3); //初始化继电器为关闭状态下面这部分没有使用外部中断,直接While()死循环检测振动模块电平,从而控制灯的亮灭(继电器)		
//		while(1)
//		{
//              //if内部判断是否发生电平变化
//				if(GPIO_ReadInputDataBit( GPIOA,  GPIO_Pin_1) == 0) //如果发生震动
//				{
//						GPIO_ResetBits(GPIOA , GPIO_Pin_3);//拉低开灯
//						delay(1000);//延迟1秒											 //持续一秒
//						GPIO_SetBits(GPIOA , GPIO_Pin_3);//拉高关灯
//				}else{
//						GPIO_SetBits(GPIOA , GPIO_Pin_3);
//				} 			
//		}}//4.中断服务函数   中断的好处:不用一直while()死循环,一直占用CPU
void EXTI1_IRQHandler(void)//在启动文件里 函数名不能变
{	if (EXTI_GetITStatus( EXTI_Line1 )  != RESET) //判断是否发生了中断  右键 EXTI_GetITStatus goto 在exit.h定义 exit.c实现{GPIO_ResetBits(GPIOA , GPIO_Pin_3);  //打开继电器,开灯delay(1000);GPIO_SetBits(GPIOA , GPIO_Pin_3);	//关闭继电器,关灯}		EXTI_ClearFlag( EXTI_Line1);//清除中断标志 不然标志位一直都存在  在exit.h			
}

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

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

相关文章

结构体与共用体(联合体)

参考:结构体与共用体 作者:一只青木呀 发布时间: 2020-08-09 08:29:22 网址:https://blog.csdn.net/weixin_45309916/article/details/107889394 参考:联合体(union)的使用方法及其本质 作者&am…

STM32串口原理、结构体、库函数、串口发送字符(串)、重定向printf串口发送、串口中断接收控制灯、接收不定长数据

参考:串口的结构体 重定向printf串口发送stm32等博文 作者:点灯小哥 发布时间: 2021-03-06 21:46:33 网址:https://blog.csdn.net/weixin_46016743/article/details/114458698 目录串口相关知识定义通信概念1.通讯结构2.电平标准3…

STM32通用定时器(原理、结构体、库函数、定时器中断每秒闪烁一次灯) —— 时钟源、分频值、重装载值

参考:stm32定时器与定时器中断 作者:打酱油的 发布时间: 2021-04-11 01:04:09 网址:https://blog.csdn.net/weixin_46098612/article/details/115493737 参考:stm32通用定时器结构体函数定时器实现led闪烁 作者&#x…

关于错误error C4430 error C2365 error C2078 error C2440 error C2143的处理。

关于错误error C4430 error C2365 error C2078 error C2440 error C2143的处理。 楼主在公司接手了一段代码。编译的时候发现一个很奇怪的问题,就是获取最新代码的时候能编译通过,然后下次就编译不通过了,提示如下错误。 后来发现问题出在std…

STM32端口复用和端口重映射

参考:stm32 端口复用和重映射 作者:点灯小哥 发布时间: 2021-03-09 13:49:19 网址:https://blog.csdn.net/weixin_46016743/article/details/114581032 目录端口复用1.什么是端口复用2. 如何配置端口复用(以PA9、PA10串口为例)端口…

Scala学习:Curry化的函数

2019独角兽企业重金招聘Python工程师标准>>> 在第1章,我们说过Scala允许你创建新的“感觉像是原生语言支持”的控制抽象。尽管到目前你已经看到的例子都的确是控制抽象,不过任何人都不会 误以为它们是原生语言支持的。为了搞明白如何让控制抽…

js 获取session_Python实战案例:这是你见过的最详细的JS加密登录某博

0x00 抓包分析简单的搜索之后发现,很多参数都是登陆上面这个请求返回的值,这个请求在输入完账号光标到达密码框时就会生成!0x01 加密逻辑分析搜索su可以很快找到加密的位置,上图看到e.su和e.sp都是由sinaSSOEncoder这个函数生成的&#xff0c…

STM32通用定时器输出PWM控制舵机 —— 重装载值、比较值、当前值

参考:stm32 定时器输出PWM原理及工作原理控制舵机 作者:点灯小哥 发布时间: 2021-03-09 23:17:52 网址:https://blog.csdn.net/weixin_46016743/article/details/114606662 参考:stm32之pwm输出 作者:打酱油…

STM32系统定时器SysTick(只能向下递减)延时闪烁灯

参考:stm32 系统定时器 SysTick 作者:点灯小哥 发布时间: 2021-03-10 13:46:00 网址:https://blog.csdn.net/weixin_46016743/article/details/114633245 参考:stm32之系统定时器 作者:打酱油的&#xff1b…

WMS学习笔记:1.尝试加载WMS

1.首先找一个可用的WMS栅格地图服务:http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi 获取GetCapabilities: http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?serviceWMS&requestGetCapabilities 2.在ArcGIS中添加GIS空间服务 2.在ArcC…

mysqli 扩展_MySQLi的优势

1. 功能增加了2,效率大大增加(以后的PHP项目改成mysqli)3,更稳定mysqli使用面向对象技术,但也支持过程化的使用方式mysqli扩展中给我提供了三个类:1. mysqli和连接有关的类2. mysqli_result表达了对数据库的查询所返回的结果集。 …

STM32F4开发板硬件简介

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程刷题面经求职讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进…

演示:EIGRP非等价负载均衡(故障分析与解决篇)

演示:EIGRP非等价负载均衡的故障分析与排除故障背景:在如下图14.20所示的网络环境,工程师完成了环境中所有路由器的接口地址配置有EIGRP动态路由协议的启动,目前每台EIGRP路由器邻居关系正常,路由学习正常,…

STM32超声波模块测距串口输出/通用定时器中断并输出PWM控制舵机/系统定时器延时

参考:stm32 超声波模块 原理 实现测距 舵机使用 作者:点灯小哥 发布时间: 2021-03-10 19:37:16 网址:https://blog.csdn.net/weixin_46016743/article/details/114643703 目录效果展示超声波传感器原理超声波测距编程步骤代码编写…

STM32F103五分钟入门系列(二)GPIO的七大寄存器+GPIOx_LCKR作用和配置

摘自:STM32F103五分钟入门系列(二)GPIO的七大寄存器GPIOx_LCKR作用和配置 作者:自信且爱笑‘ 发布时间: 2021-05-01 12:08:32 网址:https://blog.csdn.net/Curnane0_0/article/details/116276876?spm1001.…

STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、图像(硬件IIC)

参考:基于STM32-Oled(IIC)的使用 作者:奋斗的小殷 发布时间: 2021-05-07 13:09:26 网址:https://blog.csdn.net/boybs/article/details/116465668 目录IIC总线简介IIC协议简介IIC总线系统结构IIC总线物理层…

推送公司今日菜单内容到手机

此文已由作者张耕源授权网易云社区发布。欢迎访问网易云社区,了解更多网易技术产品运营经验。自从公司的易信公众服务号有了查询今日菜单的功能,自己慢慢养成了每次去吃饭前查一 下各个窗口的菜谱,再决定去哪吃饭的习惯。不过这个功能使用的越…

Android开发中如何创建自定义对话框

背景: 无论是Android,还是其他什么平台,对话框的主要形式都是弹出,或者我们可以说是一个在当前活动中打开的提示,来执行一些操作或实现一些功能。 你可以用一个对话框来问用户以确认一个行动,向用户通告一个…

树莓派接入公网(花生壳)

参考:树莓派接入公网 作者:图触靓 发布时间: 2020-12-22 17:28:19 网址:https://blog.csdn.net/bhbhhyg/article/details/107994829 目录为什么要接入公网接入公网的方法(花生壳)1、下载工具huashenke2、安…

cant find module express

安装express成功,测试一个应用如下:但是,运行却报错,如下图:说是express找不到,不应该啊!命令都能用啊!表面的原因是因为我install express用的是-g。参考链接如下:http:…