STM32嵌入式开发学习笔记(五):中断
我们过去了解了用循环实现延时,或用系统滴答计时器实现延时,但这两种方法都有一种问题:会阻塞处理器的运行。下面我们学习一种不阻塞处理器运行其他事件的功能:时钟中断。
所谓中断,就是让处理器放下手头的事情,立刻去做一件事情,做完了再做原来的事情。比如说你在写作业,但是突然来了一个人找你说话,你就停下来跟他说话,这就是中断。
要实现时钟中断,我们必须了解两种特性:通用定时器和中断控制器。
通用定时器也是通过晶体产生脉冲信号用于定时的定时器,和滴答计时器(systick)的区别是通用定时器在外设上,滴答定时器在内核里。通用定时器一共有8个,分别为TIM1~TIM8,其中TIM2~5是普通定时器,剩下的是高级定时器。
所以说,中断之所以能不阻塞处理器的运行,是因为通用定时器独立于系统内核,不占用处理器的运行时间。
中断控制器,顾名思义是用来控制各种各样种类繁多的中断的,这些中断有先有后,优先级有高有低,因此需要一个专门的控制器来控制它们。
我们尝试实现一个中断控制,选用TIM2作为控制中断的定时器,首先需要配置TIM2,我们查阅技术手册,通用定时器由TIM_TimeBaseInitTypeDef结构体来初始化,此结构体有如下成员。
typedef struct
{
u16 TIM_Period;
//重装载值
u16 TIM_Prescaler;
//预分频值
u8 TIM_ClockDivision;
//时钟分割
u16 TIM_CounterMode;
//计数模式
} TIM_TimeBaseInitTypeDef;
通用定时器的时钟频率还是72MHz,因此我们设定分频值为72方便计算。
TIM_TimeBaseInitTypeDef TIME2_INIT;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIME2_INIT.TIM_Prescaler=;
TIME2_INIT.TIM_Period=;
TIME2_INIT.TIM_CounterMode=TIM_CounterMode_Down;
TIME2_INIT.TIM_ClockDivision=TIM_CKD_DIV1;
TIME2_INIT.TIM_RepetitionCounter=;
TIM_TimeBaseInit(TIM2,&TIME2_INIT);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
如此,便将通用计时器初始化。
然后我们设置中断控制器,中断控制器由NVIC_InitTypeDef结构体来初始化,成员如下
typedef struct
{
u8 NVIC_IRQChannel;
//中断通道,接受什么信号才中断
u8 NVIC_IRQChannelPreemptionPriority;
//主优先级
u8 NVIC_IRQChannelSubPriority;
//从优先级
FunctionalState NVIC_IRQChannelCmd;
//使能
} NVIC_InitTypeDef;
另外,中断控制器还十分有意思,主优先级和从优先级的值,共同占用4位寄存器,因此还得用NVIC_PriorityGroupConfig函数分配一下,这四位寄存器哪几位代表主优先级,哪几位代表从优先级。

NVIC_InitTypeDef NVIC_INIT;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_INIT.NVIC_IRQChannel=TIM2_IRQn;
NVIC_INIT.NVIC_IRQChannelPreemptionPriority=;
NVIC_INIT.NVIC_IRQChannelSubPriority=;
NVIC_INIT.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_INIT);
接下来,使能一下TIM2即可
TIM_Cmd(TIM2,ENABLE);
然后,中断控制器当中断条件达成时,会自动调用一下TIM2_IRQHandler函数,注意这个函数名是在库里写死的。我们需要定义一下中断时的行为。
但是,有一点需要注意,在TIM2_IRQHandler函数里面,我们要确认一下这个函数是因为中断请求而调用的,如果是意外调用的则拒绝执行,直接退出,这种编程思想叫做防御式编程,即不信任传入的参数,要在执行前检查参数的合法性。
void TIM2_IRQHandler(){
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
//中断时执行的事件
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
完整代码如下:
#include <time2.h>
#include <stm32f10x.h>
void time2_configer(){
TIM_TimeBaseInitTypeDef TIME2_INIT; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIME2_INIT.TIM_Prescaler=;
TIME2_INIT.TIM_Period=;
TIME2_INIT.TIM_CounterMode=TIM_CounterMode_Down;
TIME2_INIT.TIM_ClockDivision=TIM_CKD_DIV1;
TIME2_INIT.TIM_RepetitionCounter=;
TIM_TimeBaseInit(TIM2,&TIME2_INIT);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); NVIC_InitTypeDef NVIC_INIT; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_INIT.NVIC_IRQChannel=TIM2_IRQn;
NVIC_INIT.NVIC_IRQChannelPreemptionPriority=;
NVIC_INIT.NVIC_IRQChannelSubPriority=;
NVIC_INIT.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_INIT); TIM_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(){
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){ }
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
//time2.c
#ifndef _TIME2_H
#define _TIME2_H
void time2_configer();
void TIM2_IRQHandler();
#endif
//time2.h
STM32嵌入式开发学习笔记(五):中断的更多相关文章
- STM32嵌入式开发学习笔记(一)
本文中,笔者将介绍使用嵌入式开发工具Keil uVision5,使用C语言,对微处理器STM32F103C8进行嵌入式开发. 开发使用C语言,首先需要新建一个C语言文件,将其设为主函数的入口,因此,将 ...
- STM32嵌入式开发学习笔记(六):串口通信(上)
本文我们将了解STM32与外部设备通过串口通信的方式. 所谓串口通信,其实是一个类似于计算机网络的概念,它有物理层,比如规定用什么线通信,几伏特算高电平,几伏特算低电平.传输层,通信前要发RTS,CT ...
- STM32嵌入式开发学习笔记(七):串口通信(下)
下面我们进行几个串口通信的实际应用. 实验一:发信实验,让开发板通过串口向电脑发送信息: #include <stdio.h> #include <stm32f10x.h> # ...
- STM32嵌入式开发学习笔记(四):使用滴答计时器实现精准计时
前面我们讲过,因为在STM32上没有系统时间的接口,因此无法调用sleep函数,在本文中,笔者将利用滴答计时器实现精准延时. 查阅技术手册,滴答计时器依赖于一个SysTick_Type类型寄存器,定义 ...
- STM32嵌入式开发学习笔记(三):使用按键控制小灯
按键和小灯一样,也是通过GPIO外设与主板连接,也是通过GPIO_InitStruct类型结构体控制其工作. 查阅技术手册,按钮连接GPIOA控制下的管脚0. 但与之不同的是,按键是一种输入设备,输入 ...
- STM32嵌入式开发学习笔记(二):将功能封装为库文件
将所有的函数都堆在main.c文件里不是好的选择,庞大的代码文件会是你维护的障碍,明智的做法是,一种功能封装到一个库文件里. 库文件就是你代码开始部分写的#include<xxxx.h>里 ...
- stm32学习笔记——外部中断的使用
stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...
- stm32寄存器版学习笔记03 外部中断
stm32的每个I/O口都可以作为中断输入,要把I/O口设置为外部中断输入,必须将I/O口设置为上拉/下拉输入 或 浮空输入(但浮空的时候外部一定要带上拉或下拉电阻,否则可能导致 中断不停的触发),干 ...
随机推荐
- 【Java架构:基础技术】一篇文章搞掂:Maven
本文篇幅较长,建议合理利用右上角目录进行查看(如果没有目录请刷新). 本文基于<Maven 实战>一书进行总结和扩展,大家也可以自行研读此书. 一.Maven简介 1.1.什么是Maven ...
- 能打开电脑都看懂的系列之Windows下修改MongoDB用户密码
起因 还能怎么滴,我忘了MongoDB的密码呗. 操作 进入MongoDB的安装目录的bin目录下,(我的目录是D:\developer\MongoDB\Server\4.2\bin): 用记事本打开 ...
- 使用密码登陆Amazon EC2
用的是亚马逊推荐的系统:Amazon Linux AMI 2015.09.1 (HVM) 创建instance后,会有一个pem的key使用该密钥登陆到服务器上后,默认用户名为 ec2-user 直接 ...
- 对业务类进行构造的工厂类BLLFactory
using System; using System.Collections.Generic; using System.Text; using System.Collections; using W ...
- 【狼】unity3d 安卓播放视频替代视频纹理
http://www.cnblogs.com/zhanlang96/p/3726684.html 原创,有问题或错误的话希望大家批评指正 导出apk,是不能用电影纹理的,所以我们只能用这个办法 这个 ...
- Windows IO System
Windows IO System是由一些executive components组成,这些component可以认为是ntoskrnl.exe中相对独立的一些module. 整个IO System是 ...
- 时间同步服务器NTP
NTP服务器 NTP(Network Time Protocol)[网络时间协议],它是用来同步网络中各个计算机的时间的协议,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒, ...
- js中函数的创建和调用都发生了什么?执行环境,函数作用域链,变量对象
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/26/js%E4%B8%AD%E5%87%BD%E6%95%B0%E7%9A%84%E ...
- lg5169 xtq的异或和
题目 根据一些众所周知的结论,我们先跑一棵生成树出来,之后把所有简单环都搞出来,那么\(u\)到\(v\)的路径一定可以由树上的路径和一些简单环拼起来得到 把所有简单环都插到一个线性基里,之后dfs一 ...
- 正在从 Windows 应用商店下载... 无法从 Windows 应用商店下载。请检查网络连接。
手贱关掉了一下服务,再打开就是嘛