当前课程知识点:ARM微控制器与嵌入式系统 >  第五章 ARM微控制器的各种外设 >  5.4.2 ARM微控制器外设:定时器的编程 >  5.4.2 ARM微控制器外设:定时器的编程

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

5.4.2 ARM微控制器外设:定时器的编程在线视频

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

下一节:E3 实验三 定时器中断编程实操

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

5.4.2 ARM微控制器外设:定时器的编程课程教案、知识点、字幕

各位同学大家好

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

欢迎大家回到

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

我们在这个单元里呢

接着进行定时器

特别是Sys Tick这样一类

在ARM微控制器里头

最最简单的定时器的编程和实现

前面讲了它的原理

和它最最简单那三四个寄存器

其实大家会已经发现这个单元

没有想象中那么难

但是难点在于

我们第二次进行一个中断程序的开发

我希望通过这样一次又一次的挑战

怎么来做中断

来加深大家对于这样一种编程思想的理解

那么回到我们的任务

我们如果把Sys Tick这个模块用起来

写一个跟它对应的定时的中断程序

来改进我们刚才那个按键

改变灯闪烁的程序

要几个步骤呢

其实从程序的改造或者程序编写的角度来讲

还是跟那个按键做中断一样是四个步骤

头两个步骤把这个中断的开关打开

把这个中断的中断源配置好

就是配置好它的条件

比如放在定时器多长时间产生一次中断

那么这件事我们在这里用一个部分来讲

接下来呢

是如何写它的中断服务程序

如果把它填到中断向量表

更重要的是

我们最后会拎出来给大家讲

经过这样一种改造我们的程序

究竟工作在了怎样一种模式和思想下

先看前两个步骤

把中断打开

也包括几件事

首先是要把中断的总开关打开

这个在上一个章节里头我们已经讲过

中断的总开关打开就是CPU内核的

一个寄存器的一个比特

PM这个比特置位

它对应的就还是那一条汇编指令

所以我们这里就不重复讲了

然后中断的子开关打开

当我们在用IO的PORTA这个中断的时候

它是一个外部的中断

也就是在IRQ 0到31

32个外部中断里

所以它的开关在NVIC内核模块当中的

那个一个寄存器32个比特当中的一个比特

而我们现在这个章节所使用的Sys Tick

是ARM公司设计的ARM内核的一个特有的中断

或者一个interception

所以它是在我们中断向量表里头

0到15那前16个

是我们称为exception的那16个内核中断

或者叫exception当中的一个

所以它的子开关不再像原来那样

在NVIC模块里

而是就在我们的Sys Tick模块的寄存器里

在哪呢

就是上一个单元我们讲的

Control status register里头那一个比特打开中断

就是它的子开关了

所以我们对于它的中断进行打开

其实呢

就只用中断总开关的汇编语言指令

和中断子开关的

Sys Tick寄存器置位enable就可以了

那么第二个问题说我们那个步骤二

如何配置好这个时钟源呢

其实在上个单元讲完简简单单三个寄存器

给了个步骤

已经用英语或者用人类的语言

告诉了我们这三件事应该怎么做

那我现在的问题是

它的寄存器的值应该赋成多少呢

是不是大家得做个简单计算

我们的时钟源用的core clock

也就是20.97兆

那如果我们希望得到一个每0.5秒

发生一次中断的时钟

我们应该如何设置

我们这三个寄存器当中的那个

reload value的值对不对

那么肯定要用20.97兆怎么着啊

乘或者除这个0.5秒

算一算寄存器的计数值

应该设成多少

也就20.97兆的频率

数数数多少个是0.5秒

而它的误差就是20.97兆分之一

那也就是那个误差差不多是50个纳秒

我不知道大家想明白这件事没有

那么另外我要提醒大家注意的一件事是

如果你算出这么一个值

想要设给我们的寄存器

请你在设置之前keep in mind脑袋当中

想一想这件事

就是我们这个寄存器

我们这个计数器是多少比特的

是24比特的

也就是它最多你能给它赋值

能够赋上去的就是24比特二进制数

多于他的就没有发生作用

数数数到24比特的时候就溢出归零

所以你算出来的你要设的这个值

你是不是应该自己把它换成二进制看看

有没有超过24个比特

换言之你要定时的这个长度

是不是这个定时器这个timer直接可以实现的

这是大家一定要注意的

比如下次我让大家把这个定时间隔设成5秒

设成10秒

你再算一算可不可以做得到

清楚了这件事

将我刚才用人类的语言所讲的这些内容

转换成我们的代码

添加到我们的main函数里头

我们来看看我们的main函数程序

在main函数的开始部分跟原来一样

仍然是把对应的引脚所用到的时钟打开

引脚指定为IO用

指定好IO的方向和高低电平

然后在上一个章节里我们教大家

把IO工作在中断模式的时候

把中断的总开关打开

把IO的中断配置好

然后配置好对应的那一个按键的引脚

在什么情况下可以产生中断

这是左下角的这个红代码给大家提示的

我们添加这样子右上角这三个

红色的这三行

是不是我们刚才所讲的

对于Sys Tick这样一种典型timer的设置

那么这件事情

我们做了刚才

英文所讲的那三个步骤

刚好是第一个步骤

我们给Reload Value register

赋了一个长长的16进制数

也就是二进制数

它对应的是按20.97兆数0.5秒

所要Reload的那个值

决定了我们定时器产生的周期

第二句话呢是给Current Value写了一次操作

这次写操作将Current Value

这个计数寄存器的值清零

同时保证了中断标志寄存器也被清零了

最后呢我们给

Sys Tick Control and status register赋了个初值

这个初值我非常容易的加以解释

就是打开Sys Tick时钟模块

打开使能这个Sys Tick的中断

把子开关打开

同时指定时钟源是CoreClock也就是20.97兆

这样就完成了这样一个Sys Tick模块的初始化

把中断打开了

把中断每多长时间发生一次也配置好

那回到我们的编程思想

我们已经完成了步骤1和步骤2

剩下什么呢

是步骤3

我们如何写一个定的这个时间

达到的中断服务函数

去做我们希望在这个中断里应该做的事

当然最后还有一个步骤是

我们把它如何填到中断向量表里

那么这个时候涉及到了我们编程思想

我们都知道中断服务函数

是在我们设置的条件每当它发生的时候

自动硬件通知CPU

由CPU自动调用的一个函数

现在我们使用的是定时器和定时中断

换言之每当0.5秒的时间

比较精确的达到的时候

就会有一个中断通知CPU

CPU应该响应它去做一件我们希望它做的事

这是它的编程思想

放回我们刚才的程序里头

我们需要写一个void的类型

void的返回值的中断服务函数

仍然在里头do something

并且清中断标志位

以便下一次中断能够发生

而体现到我们现在这个程序里头

我们每0.5秒的定时中断费这么大劲配置好了

其实要干什么

其实就是要让灯闪一下对不对

原来亮的变灭 原来灭的变亮

把这个GPIOC

PORTC寄存器的这些值翻转一下

同时保证这个开关不要动

那么最后清一下标志位

这些我说的话体现成C语言代码

就是这么一个简简单单四行的中断服务函数

每当0.5秒达到的时候请调用这个函数

让这个灯的值

引脚的值翻转一下

就这么简单

那么完成了这么一个中断服务函数

第四个步骤

最后一个步骤

在我们去看整个程序框架之前

我们先把这个步骤做完

就是要把这样一个中断函数

它的入口地址

第一条指令的地址

填入我们的中断向量表

或者说把这样一个函数

跟我们前面配置好的中断源关联起来

在它发生通知CPU的时候

CPU能够根据中断的来源

找到这个函数去加以执行

是不是就这么个意思

那么这件事情我们在

上一个章节已经做过一次

之前也讲过无数次原理

就看我们中断向量表

从上电默认的0000地址开始

我们有16个表项是对应ARM的

CPU内部的中断源或者exception

后面还有32个表项是对应ARM开放给

外设的中断源

我们上一次做IO的按键输入的中断呢

是底下32表项当中的第30项

也就是倒数第二项

那么这一次我们现在用的是Sys Tick模块

它在哪呢

它在我们这个表格里头的前16项里头

大家可以看到有个Sys Tick

所以我们仍然回到我们CodeWarrior

帮我们生成的kinetis_sysinit.c这个文件里头

我们之前看到这个数据结构

它用一系列的函数名称

或者叫指向函数第一条指令的指针

构成一个结构体

那么我们顺着这样一个结构体往下找

看它的前16个表向我们就会找到

Sys Tick_Handler这么一个函数名称

这就是CodeWarrior帮我们填写好中断向量表

已经写好的空函数的函数名

所以我们可以把我们刚才的

ISR中断服务函数的名称就命名为这个名称

编译的时候让他们自动链接在一起

也可以自己另外起个名称

用我们自己所用的函数名填充在这个位置

让我们CodeWarrior来自己进行编译和链接

这两者操作是一样的

所以如果我们完成了这样一个步骤

我们Sys Tick_Handler这样一个中断服务函数

这样一个让灯翻转这个函数

就已经填到了中断向量表

那么在接下来看完整代码之前

我们必须脑袋很清楚

我们究竟做了一件什么事

我们完成了把Sys Tick这样一个模块用起来

设置了让它每0.5秒钟发生一次中断

允许了这个中断可以通知CPU

告诉了CPU每当这个中断发生的时候

应该根据中断向量表

调用我们所写的这个函数

在这个函数里面

我们每次会让外面的灯完成一次翻转

接着中断函数返回

CPU接着执行自己的流程

那么回过头来看

经过我们这样的改造

我们程序变成什么样的

我们会发现我们的main函数变的非常的简洁

完成了一系列刚才所说的初始化

和两个不同中断源的配置

这个时候我们的for函数已经变空了

待会再讨论它变空的问题

我们想想原来在for函数里头做了哪些事

一件事情是检查键按了没有

一件事情是在delay下

不管键按了没有

我们要去让这个灯定期翻转

那么这件事情现在已经完全被拎出来

体现为了接下来这两个中断函数来完成

每当键被按下的时候

进按键的中断

改变两个灯的当前值

使他们变成互相不一样

或者互相一样

这是改变这个灯闪烁的模式

每当定时中断0.5秒钟发生一次的时候

进定时中断

去让当前引脚上的值翻转一下

也就是说让灯闪烁一下

那么回到我们的主程序我们会发现

我们其实在for循环

在最后一直是在那儿空转

每当按键的时候去改变灯的模式

每当定时0.5秒的时候

不管for循环里头现在是空的

还是以后再会写一些代码做一些别的任务

我们都会在0.5秒的时候

CPU准时收到一个中断进入函数

去执行让一个灯翻转的任务

于是在这样一种思想下

我们之前main函数做的两个

特别要求时间响应

比如人输入了一定要响应

我们定时时间到了灯一定要闪

都拆分成了两个独立的中断

在外面加以执行

这个时候我们会发现我们程序

整个编程思想发生了一个根本的变化

所以在这种情况下

我们的主程序的main函数

变得空空如也

我们可以在里头仍然象征性的放个delay

也可以什么都不做

当然日后编程的时候

我们也可以把一些不需要立即响应的

不那么着急的任务

放在main函数里头慢慢的做

既不用担心它们的执行

使我们无法响应人的按键

也不用担心它们的执行

使我们灯闪烁的时间间隔不再准确

然而在这个程序里头

我们其实也可以选择在main函数

最后这个for循环里头

放入一个让系统进入低功耗的休眠的函数

大家想一想我们可能每半秒钟

才需要做一次操作

人甚至很长时间才做一次按键

而每当进入我们这两个中断函数的时候

人的按键只用6到7条C语言语句

十几条指令就返回退出

而对于点灯的这个定时中断

只用一到两条C语言语句

也就是5、6个汇编指令就返回

所以这两个函数的执行时间

都在微秒以下或者微秒量级

而如果我们每半秒钟才进行一次这个操作

也就是我们CPU真正做有用操作的时间

只有几十万分之一

而剩下的时间如果我们在main函数里头

放一个不影响中断的低功耗函数

我们的主程序将在绝大多数时间里

都是低功耗的

于是我们整个系统如果用一个电池供电

它的待机时间可能会扩充几千倍

乃至几万倍

这就是中断给我们带来从编程思想上

乃至从功耗和性能上的根本的改变

希望大家通过这个章节的学习

尝试写代码实现它

并且理解这背后的东西

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.4.2 ARM微控制器外设:定时器的编程笔记与讨论

收藏文章
表情删除后不可恢复,是否删除
取消
确定
图片正在上传,请稍后...
  • 评分:
评论内容为空!
还没有评论,快来抢沙发吧!

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。
欢迎学习『5.4.2 ARM微控制器外设:定时器的编程慕课视频播放-ARM微控制器与嵌入式系统-MOOC慕课视频教程-柠檬大学』