当前课程知识点:ARM微控制器与嵌入式系统 >  第五章 ARM微控制器的各种外设 >  5.3.1 ARM微控制器外设:IO的中断编程(上) >  5.3.1 ARM微控制器外设:IO的中断编程(上)

返回《ARM微控制器与嵌入式系统》慕课在线视频课程列表

5.3.1 ARM微控制器外设:IO的中断编程(上)在线视频

5.3.1 ARM微控制器外设:IO的中断编程(上)

下一节:5.3.2 ARM微控制器外设:IO的中断编程(下)

返回《ARM微控制器与嵌入式系统》慕课在线视频列表

5.3.1 ARM微控制器外设:IO的中断编程(上)课程教案、知识点、字幕

各位同学大家好

我是清华大学工程物理系的曾鸣老师

欢迎大家回到我们

ARM微控制器与嵌入式系统的MOOC课堂

那么在这个单元里呢

我们将真真正正地第一次

来开始做一个中断的编程

那么一说中断可能很多同学心里就慌了

因为我们实际上在第四章

给大家讲了第一类最简单的外设IO

那么在第五章的第二个单元里给大家讲了

外设的通讯

大家刚刚摸到了点门道

说这个外设就是老师把原理讲清楚

我们理解它的电路怎么实现

然后再掌握一些寄存器

然后在main函数里把它一句话一句话写出来

程序就开发出来了

但是中断是什么呢

大家突然觉得这个词老师讲过

但是好像有点模糊

没有关系

我们在讲中断的时候就给大家说过

中断是一个难点

在之前的基础知识讲的时候

给大家更多的是梳理了一下

建立了一个初步的印象

而对它的真正的掌握

本来就应该与外设结合实际开发编程来掌握

什么事情一旦做一遍

你就会发现它简单了一百倍

那么从中断的基本概念开始梳理

在这个单元和下个单元的课里

我们用最最简单的一类外设

来进行编程

实现一个中断的程序开发

首先我们回顾一下中断是什么

那么我们首先脑袋会浮现出

当时老师讲中断这张图

说中断是以轮询相对应的一种工作模式

轮询我们实际上在做第四章

或者第一个实验的时候已经体会过

我们要检查一个键按下了没有

我们delay一段时间

去查一下寄存器这个键按了没有

这种模式就是轮询

而中断是什么

中断从本质上我们回忆它是一个

需要CPU立刻处理的内部或者外部的事件

也就是说一个事情

我们设置好条件CPU应该响应它

当它发生的时候它通知CPU必须去响应

这就成为中断

英文就是Interrupt

所以在内部可能是我们设置好的

一个定时的时间到了

可能是一次AD转化结束了

对于外部可能就是我们接下来

可能要做的一个按键按下了 这么一个动作

或者是外部来了一个通讯的数据收到了

这些都可以是中断触发的条件

而中断的工作模式

就是在这样一些事情发生的时候

它打断CPU原有程序的执行

跳转而去执行一段约定好了的与之相应的处理

而在执行完之后

又回到程序正常的流程继续往下执行

我不知道大家回忆起来没有

那么在这个过程当中从正常的程序

切换到约定好的服务程序

需要使用到堆栈来保存我们CPU的

一个局部的寄存器环境

我们称为上下文寄存器context对吧

那么当中断这个子程序执行完毕的时候

我们要把CPU内部的这些寄存器都还原

让主程序好像什么事情都没有发生过一样

继续往下执行

而大家在之前我讲中断

给大家一直强调的一个问题是

中断的这个程序执行的时间什么时候会发生

在编写程序的时候其实并不是特别明确的

因为这段程序的调用

是由中断也就是硬件来触发的

当我们设置好的条件满足的时候

它就自动的被CPU加以调用

那么说了半天这个概念以后

我们再接下来要考虑怎么样真正编程

实现这样一个流程

那么在这个单元里我会带着大家一点点的做

那么我们从哪里来切入

大家会觉得难度会比较低呢

从我们第一次实验的一个任务说起

第一次实验我们最后第五个任务是这样一个任务

说按上我们板子上的某一个键

来切换我们两个LED灯的闪烁模式

比如说本来是两个灯同亮同灭的

然后变成两个灯交替亮灭对吧

那么这样一种模式我们在实验五里头

老师是给了一个例程的

那么我们就以它为例来看看

能不能把中断给用进去

这样内容大家也熟悉

做起来大家心里有底

我是能实现的

我能不能换个方式来实现

那么当时我们给出的例程是这样的

这么一个程序非常非常简单

在这里我就不再过多的解释了

还是那几个步骤对吧

时钟打开 配置成IO用

设置这个IO模块

让它这个设置好引脚的方向

来控制灯的亮和灭

大家注意的是这个main函数里头

第一句话是delay 延时

然后接着有一个if语句

把后面执行内容都给括起来了

那么这个if语句实际上读了GPIOA的PDIR寄存器

也就是检查PORTA上的哪一个引脚的值

有没有变零或者变一

也就是键有没有按下

那么在这个键被按下的时候

我们在这个if的语句里

是切换了两个灯的亮灭关系

比如说是一亮一灭

或者变成两个都亮

然后在这个if语句之外

最后两句话是使所有的灯翻转周期地进行闪烁

所以大家要具备写这个代码

和读这个代码的能力

那么这段程序我们如果用自己大脑

来逻辑上运行一下我们会发现它是不停地延时

除掉这个if的部分

每次延时了以后

是GPIOA进行翻转

让这个灯进行交替闪烁

或者是同亮同灭的闪烁

而if语句呢

仅当键按下来的时候满足

然后每次按键会切换一下灯闪烁的模式

这是背后程序的编程思想

那么这个程序

为了引入中断我要问大家一个问题

它有什么毛病

那么大家可能会想几秒钟

或者你把这个视频停下来

大家把这个MOOC课停下来

自己想一想

最好是自己有个答案

那么我在这里给大家说

它的其中一个问题

如果大家用脑袋

去运行这个程序的流程的时候你会发现

我们每次delay

比方说花掉半秒钟或者一秒钟

实际上都是到程序执行完delay

执行if这条语句的这个瞬间

才会去检查我们的引脚有没有被按下

那么换言之每半秒钟的delay之后

也就是执行这条语句的那几十个几百个纳秒

会去查这个按键有没有被按下

那如果说

我们手按这个键的时间

在delay函数的那个半秒里我已经按下去

又松开了呢

那是不是等到delay函数执行完

来检查这个按键有没有按下的时候

我们这一次按键信息就已经丢掉了

那有的同学说

那我把这个delay改短一点

老师不是说人按一下键总得个百毫秒

几十毫秒嘛

那我让这个delay函数变成

十毫秒 五毫秒的delay

这样我查这个按键查的很频繁

能不能解决这个问题

这就是典型的轮询的方式

你轮询的频率能不丢你要的事件

但是另一个问题来了

你把delay改短了

是不是底下你会发现这个灯就闪的变快了

闪到眼睛都看不出来了

所以呢你还得再进一步的改

进这个for循环delay若干次才闪一次灯

所以当我们在一个for循环里头

要通过delay来做若干件不同的事情的时候

我给大家一点提示

你的delay的那个时间

是不是得是你所有这些时间所需要的

那个最小单元或者说是他们的最大公约数啊

所以这就是一种圆形的时间片的这种机制

大家以后慢慢的会从这个过渡到学习操作系统

那么在这个单元里我们因为存在这个问题

我们实际上这个程序跑起来是不顺畅的

会丢人的按键的

我们能不能用中断的方式来做呢

这就是这个单元我带着大家学习和掌握的内容

那么我们看看我们的电路图我们会发现

在我们现在这个电路板上

所有的八个引脚都接到了PORTA上

分别是PORTA1一直到十几的八个IO

用来接这八个按键

那么非常幸运的是

我们在Cortex M0的KL25

我们用的这个系列的MCU微控制器上

PORTA和PORTD都是具有中断功能的

也就是每个引脚都可以触发中断通知CPU

那我们现在就来尝试编程

让这个按键工作在中断方式下

从思想上来讲就是键设置好能够响应这个中断

于是无论任何时候 这个键被按下

就自动通知CPU 键被按了

然后同时再进行相应的处理

我们切换到这样一种编程思想

尝试在这个单元里

学会把程序实现出来

那么它有几个步骤呢

比原来多一个步骤

四个步骤

其实原来讲中断的时候给大家讲过

第一个步骤配置好中断的这个开关

把中断打开

第二个步骤呢

配置好对应的中断源

然后第三个步骤呢

把这个中断的服务子程写好

最后一个步骤

把这个中断服务子程填进中断向量表

确定它是跟我们设置的中断源一一对应的

而让CPU在中断发生的时候

知道该执行这个函数

那么在这个单元里我只讲步骤一

在下个单元

我会给大家讲后面三个步骤编程实现

如何把中断打开

一句话就是在我们的微控制器里头

对于一个中断要发生

除了标志位置位这个中断事情发生之外

我们需要打开一个总开关

Global的enable

还要打开一个子开关

也就是我们这个中断源对应的Dedicated的enable

那么总开关在哪

在讲基本概念的时候给大家讲过

我们现在再来回顾一下 其实就是一句话

那么在我们CPU内部的寄存器

注意CPU内部的寄存器跟R0到R15

这些数据寄存器在一起的

CPU的状态寄存器里头

是不是有一个寄存器是PRIMASK

中断和优先级的这个掩码寄存器

它里头的最后一个比特PM这个比特

为0为1是控制这个微控制器是否响应中断

那么它会是一个总开关

而对它进行操作

这是CPU内部的寄存器

大家一定概念清楚

它不是映射在地址上的

它是CPU内部的

直接通过两条指令分别对它可以置0和置1

相应的打开或者关闭中断的总开关

那么这两条指令

一条是CPSIE i 一条是CPSID i

D对应Disable

分别是打开全局中断开关和关闭全局中断开关

好 一条汇编指令呢

我们就搞定了这个中断的总开关

那么这个中断源对应的子开关怎么打开呢

大家不要急

我来一点点的带着大家把它弄清楚

如果我们回忆一下之前讲过的内容

或者翻我们KL25这个芯片手册的

第53页去看一看

回忆一下我们中断向量表

我们CPU除了总开关能够响应

各种各样的中断源

当然我前面举过的例子

定时 按键

那么一共有多少个中断源可以响应呢

如果我们回头看一看这个中断的

这个地址分配表或者向量表

我们会发现从序号0到序号47

一共有48个vector也就是向量可以响应

那么在这48个里头并不是全部都是

我们所说的外部中断

那么在这个CPU设计的时候

由谁设计

由ARM公司设计的时候呢

定义了前16个也就是0到15

被预留给了CPU的内部作为异常处理

包括我们学过的复位

包括我们学过的系统时钟

非法指令的复位等等这些响应

称为异常处理

占用了前16个

那么我们所说的外部中断

48减16

还剩下32个呢

从vector这个向量表的编号上

就是从第16号到47号

但是从中断号上来讲

就是从第0号到第31号一共32个

是我们的外设中断

那么他们这些外设中断每一个都在芯片

最终设计成我们买到芯片型号的时候

必须由芯片的最终设计厂商

来指定给哪个外设用

比如有的给AD用

有的给定时器用

有的给我们现在用的按键来用

那么这些信息呢

是在我们的这个KL25芯片手册上可以查到的

那么归而简之就是我们向量表里一共有48个项

那么这个向量表的前16项

是由ARM公司设计的

那么指定了内部CPU的一些异常处理

后面的32项是由像NXP

或者是Freescale这样的

芯片的实际设计厂商设计的

指定给了不同的外设使用

我们看芯片手册能够看到它们分别是什么功能

如果我们想设置这每一个单独功能的

中断的子开关

回到我们的正题

我们需要对一个叫做NVIC这样的

模块的寄存器进行编程

那么稍微有点特殊的是

NVIC这个模块它的英文全称呢

是Nested Vector Interrupt Controller Module

这样一个缩写

那么换言之就是可嵌套的外部的

中断向量的控制模块

NVIC模块不是我们之前所学的

由Freescale或者NXP

这个生产厂商所设计的外设

它是各家各户的ARM统一的标准的

由ARM公司设计的一个外设模块

所以如果我们回到

地址向量表的时候我们会发现

这样一个模块

它的地址并不在我们之前学过的

IO啊 串行通讯那个地址段

而是在我们整个地址表的最底端

也就是以前所讲的Private Peripherals

这个地址段里头

E000开头的这样一个地址段

是NVIC这样一个ARM公司定义的

Private外设的地址所在

那么除了地址放的地方不一样

编程使用跟前面讲的都一样

就是找到每个寄存器的功能

找到对应的地址对它进行编程就可以了

那么相应的NVIC这个模块

这个寄存器的定义我们在两个地方都可以找到

一个呢是看我们NXP Freescale提供的

芯片手册KL25芯片手册的138页这个位置

另外呢

就是看我们的ARM的芯片手册的第57页

它也会详细的讲这些NVIC模块里的定义

那么我们仔细打开看一看就会发现

NVIC这个模块跟以前学过的一样

跟IO跟串口一样包含了若干个寄存器

那么这些寄存器的起始地址是E000E100这个地址段

那么我们进入这个模块

看看这样一个模块里头究竟有几个寄存器呢

我们会发现跟IO模块

跟这个UART串行通讯模块一样 不多

一共只有5个寄存器可以使用

而在这门课的范畴里头

我们其实只要大致知道三个寄存器

而在编程范畴里头我们其实只用到了其中一个

那么这是哪几个寄存器我们展开看一看

这五个寄存器当中的有用的

或者我们会涉及到寄存器的第一个

是NVIC_ISER寄存器

其次呢是NVIC_ICER寄存器

这两个寄存器一个是对0到31

那32个外部中断源一一对应的

置位打开中断子开关

一个呢是一一对应的置位关闭中断子开关

那么这五个寄存器的最后一个寄存器

还有一个我们可能以后会用到的是NVIC_IPR

是设置中断的优先级用的

那么在这个单元里头

我们学会最简单的一个编程

就是打开中断子开关 非常简单

那么NVIC_ISER这个寄存器是一个32位的寄存器

那么它的地址

我们从这个寄存器定义上就直接能看到

是E000开头的这样一个地址

那么它的内容是0到31位

32位的寄存器

换言之你可以给它设置32个0或者1

那么这32个0或者1

每一个就对应刚才说的外部中断

从0号到31号一个中断源的子开关

所以我们要在中断向量表里

把哪一个功能的中断子开关打开

我们就在这个寄存器里

把它对应的那个比特至1就可以了

而如果回头我们想把这样一个中断子开关关闭

注意我们不是把这个寄存器的这个位清零

而是把它隔壁的那个寄存器

NVIC_ICER寄存器的对应位写一个1

这样就关闭了这样一个中断源的子开关

那么优先级的设置呢

大家在芯片手册里

自己还可以进一步去进行看和学习

所以回过头来我们想一想

中断的总开关用一句汇编语言就能打开

中断子开关就要看我们要用的是哪一个中断源

我们要用的是哪个中断源

大家不要跟着我讲讲讲

忘了我们的目的

我们回忆电路图我们有八个按键

这八个按键都接到了PORTA的

8个不同的IO引脚上

我们希望PORTA是能够当中断源使用的

那么我们就应该把PORTA或者GPIOA

所对应的中断子开关打开

我们查看中断向量表

我们会发现中断向量表的第30号

也就是0到31的倒数第二项

是对应的PORTA的中断源

那么它的中断子开关也就是我们的

NVIC_ISER这个寄存器的比特30

也就从最高位数起来的第二位

那大家这个操作怎么写呢

很简单

要打开这个中断子开关

我们只用写NVIC_ISER寄存器

或等于0X400...00这么一个串对吧

这么一或是不是这个第二位就置1了

回头如果我们要关闭

这样一个中断源的子开关

也很简单

就是NVIC_ICER寄存器

或等于0X400...0这么一个串

把这个关中断的寄存器的对应位置写一个1

就关中断了

那么这些信息如我们所说

在手册上大家都可以找到

希望大家一定认真的对应

把老师刚才讲的内容加以理解

如果真正理解了

你会发现讲了半天

我们的第一个步骤实现起来非常简单

在我们原来main函数的开时钟

配置给引脚的IO用

这些都不变的情况下

只多了这么两句话

一句话是ASM汇编语言括起来的汇编指令

什么呀

开中断总开关

一句话是NVIC_ISER寄存器

或等于0X400...00把我们要用的

PORTA这样一个中断源的子开关

在NVIC模块里找到对应的比特给打开

这样我们就把我们中断的开关配置好了

换言之对于CPU来讲

已经允许了这样一类中断的发生

接下来呢我们要做什么

就剩下三个步骤

配置好什么情况下这个中断会发生

以及中断发生了应该做什么事

从而给我们点灯这个任务有机的整合起来

换一种思路把中断的函数程序写出来

在下个单元接着给大家讲

ARM微控制器与嵌入式系统课程列表:

第一章 概览

-1.1 课程概览

--1.1 课程概览

-1.2 如何学好嵌入式系统

--1.2 如何学好嵌入式系统

第二章 绪论

-2.1 计算机的基本概念、发展历史

--2.1 计算机的基本概念、发展历史

-2.2 从晶体管到CPU

--2.2 从晶体管到CPU

-2.3 概念CPU、微控制器MCU和嵌入式系统

--2.3 概念CPU、微控制器MCU和嵌入式系统

-2.4 八卦计算机史

--2.4 八卦计算机史与创新

-2.5 不同领域、不同系列的嵌入式系统

--2.5 不同领域、不同系列的嵌入式系统

-2.6 ARM历史与MKL25Z128 MCU

--2.6 ARM历史与MKL25Z128 MCU

--2.6 ARM历史与MKL25Z128 MCU【习题】

--2.6 ARM历史与MKL25Z128 MCU【讨论】

第三章 MCU基础

-3.1 CPU的基本结构和运行机制

--3.1 CPU的基本结构和运行机制

-3.2.1 堆栈的概念

--3.2.1 堆栈的概念

--3.2.1 堆栈的概念【习题】

-3.2.2 堆栈的概念-头脑体操

--3.2.2 头脑体操

-3.3.1 ARM的体系结构

--3.3.1 ARM的体系结构

--3.3.1 ARM的体系结构【习题】

-3.3.2 ARM的体系结构-头脑体操

--3.3.2 ARM的体系结构-头脑体操

-3.4.1 中断的概念和机制

--3.4.1 中断的概念和机制

-3.4.2 中断子程的概念和编程

--3.4.2 中断子程的概念和编程

-3.5 复位、时钟、存储器和总线

--3.5 复位、时钟、存储器和总线

--3.5 复位、时钟、存储器和总线【习题】

-3.6 小结:MCU的总体结构和程序运行机制

--3.6 小结:MCU的总体结构和程序运行机制

--3.6 小结:MCU的总体结构和程序运行机制【习题】

第四章 ARM微控制器的开发

-4.1 第一种外设:IO

--4.1 第一种外设:IO

-4.2 IO外设的编程实操-点亮LED

--4.2 IO外设的编程实操-点亮LED

-4.3 IO外设的进阶知识

--4.3 IO外设的进阶知识

-4.4 嵌入式开发的基本概念与工具链

--4.4 嵌入式开发的基本概念与工具链

-4.5 嵌入式开发的进阶知识

--4.5 嵌入式开发的进阶知识

-4.6 嵌入式开发中的C语言(上)

--4.6 嵌入式开发中的C语言(上)

--4.6 嵌入式开发中的C语言(上)【习题】

-4.7 嵌入式开发中的C语言(下)

--4.7 嵌入式开发中的C语言(下)

--4.7 嵌入式开发中的C语言(下)【习题】

-E0.1 实验零 开发板的初步认识与工具链的安装

--E0.1 实验零 开发板的初步认识与工具链的安装

-E0.2 实验零 体验一个例程的编译与下载

--E0.2 实验零 体验一个例程的编译与下载

-E0.3 实验零 编写第一个程序:点亮核心板LED

--E0.3 实验零 编写第一个程序:点亮核心板LED

-E1 实验一 点灯秘籍

--E1 实验一 点灯秘籍

第五章 ARM微控制器的各种外设

-5.1 ARM微控制器外设学习概述

--5.1 ARM微控制器外设学习概述

-5.2.1 ARM微控制器外设:通讯

--5.2.1 ARM微控制器外设:通讯

-5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)

--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)

--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)【习题】

-5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)

--5.2.3 ARM微控制器的外设:异步串行通讯UART的原理(下)

--5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)【习题】

-5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口

--5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口

-5.2.5 ARM微控制器外设:UART的寄存器编程(上)

--5.2.5 ARM微控制器外设:UART的寄存器编程(上)

-5.2.6 ARM微控制器外设:UART的寄存器编程(下)

--5.2.6 ARM微控制器外设:UART的寄存器编程(下)

--5.2.6 ARM微控制器外设:UART的寄存器编程(下)【习题】

-E2 实验二 UART编程实操

--E2 实验二 UART编程实操

-5.3.1 ARM微控制器外设:IO的中断编程(上)

--5.3.1 ARM微控制器外设:IO的中断编程(上)

-5.3.2 ARM微控制器外设:IO的中断编程(下)

--5.3.2 ARM微控制器外设:IO的中断编程(下)

-5.4.1 ARM微控制器外设:定时器的原理

--5.4.1 ARM微控制器外设:定时器的原理

-5.4.2 ARM微控制器外设:定时器的编程

--5.4.2 ARM微控制器外设:定时器的编程

--5.4.2 ARM微控制器外设:定时器的编程【习题】

-E3 实验三 定时器中断编程实操

--E3 实验三 定时器中断编程实操

-5.5.1 ARM微控制器外设:PWM的原理

--5.5.1 ARM微控制器外设:PWM的原理

-5.5.2 ARM微控制器外设:PWM寄存器与编程

--5.5.2 ARM微控制器外设:PWM寄存器与编程

-5.5.3 ARM微控制器外设:PWM编程实例—电子音乐

--5.5.3 ARM微控制器外设:PWM编程实例—电子音乐

-E4 实验四 数码管显示编程实操

--E4 实验四 数码管显示编程实操

-5.6.1 ARM微控制器外设:SPI通讯简介

-- 5.6.1 ARM微控制器外设:SPI通讯简介

--5.6.1 ARM微控制器外设:SPI通讯简介【习题】

-5.6.2 ARM微控制器外设:SPI寄存器与编程

-- 5.6.2 ARM微控制器外设:SPI寄存器与编程

-5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动

--5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动

-5.7.1 ARM微控制器外设:I2C通讯简介

--5.7.1 ARM微控制器外设:I2C通讯简介

-5.7.2 ARM微控制器外设:I2C的通讯协议

--5.7.2 ARM微控制器外设:I2C的通讯协议

-5.7.3 ARM微控制器外设:I2C寄存器与编程

--5.7.3 ARM微控制器外设:I2C寄存器与编程

--5.7.3 ARM微控制器外设:I2C寄存器与编程【习题】

-5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器

--5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器

-5.8.1 ARM微控制器外设:ADC简介

--5.8.1 ARM微控制器外设:ADC简介

-5.8.2 ARM微控制器外设:ADC基础

--5.8.2 ARM微控制器外设:ADC基础

-5.8.3 ARM微控制器外设:ADC寄存器与编程

--5.8.3 ARM微控制器外设:ADC寄存器与编程

-E5 实验五 ADC编程实操

--E5 实验五 ADC编程实操

-E6 挑战实验

--E6 挑战实验

第六章 嵌入式系统设计

-6.1 嵌入式系统的接口与设计

--6.1 嵌入式系统的接口与设计

-6.2 嵌入式系统的实例

--6.2 嵌入式系统的实例

5.3.1 ARM微控制器外设:IO的中断编程(上)笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。