第23节 中断系统 (NVIC) Nesting Vector Interrupt Controller

Slides:



Advertisements
Similar presentations
7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
Advertisements

高级服务器设计和实现 1 —— 基础与进阶 余锋
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
微型计算机原理及其应用 ——第8章:中断系统与中断控制器8259A
第5章 中断系统 5.1 中断的概述  5.2 AT89C51中断系统 5.3 中断系统的应用.
2017年3月5日 单片机原理与应用 背景知识调查.
第8章 中 断 8.1 概 述 为什么要用中断 中断的出现,会带来以下好处。 (1)同步操作 (2)实现实时处理 (3)故障处理.
Oracle数据库 Oracle 子程序.
第4章 ARM Cortex-M3编程模型 ARM Cortex-M3概述 ARM Cortex-M3工作状态
在PHP和MYSQL中实现完美的中文显示
陈香兰 助教:陈博、李春华 Spring 2009 嵌入式操作系统 陈香兰 助教:陈博、李春华 Spring 2009.
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
强连通分量 无向图 1、任意两顶点连通称该图为连通图 2、否则将其中的极大连通子图称为连通分量 A D C B E 有向图
Roy Wan PCI MS/s 14-bit 高速数字化仪 Roy Wan
走进编程 程序的顺序结构(二).
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
Windows网络操作系统管理 ——Windows Server 2008 R2.
Windows网络操作系统管理 ——Windows Server 2008 R2.
第五讲 四则运算计算器(一) 精品教程《C#程序设计与应用(第2版)清华大学出版社 谭恒松 主编
第4章 非线性规划 一维搜索方法 2011年11月.
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
逆向工程-汇编语言
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
CPU结构和功能.
应用实例 识别Ps & Pt ADTS 压力通道并校验 CPD8000 New MENSOR‘s ADTS: CPA8001.
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
中 断 王 静 阜阳师范学院 计算机与信息工程学院.
SOA – Experiment 2: Query Classification Web Service
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
得技通电子 问题 1.0 、选择题:本大题共15个小题,每小题1分,共15分,在每小题给出的四个选项中,只有一项符合题目要求,把所选项前的字母填在括号内。
第四章 MCS-51定时器/计数器 一、定时器结构 1.定时器结构框图
本节内容 随机读取 视频提供:昆山爱达人信息技术有限公司.
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
姚金宇 MIT SCHEME 使用说明 姚金宇
(Random Access Memory)
工业机器人知识要点解析 (ABB机器人) 主讲人:王老师
单片机原理及应用 实践部分 主讲人:刘 强 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
信号量(Semaphore).
iSIGHT 基本培训 使用 Excel的栅栏问题
长春理工大学 电工电子实验教学中心 数字电路实验 数字电路实验室.
第十章 输入输出程序设计 10.1 输入输出指令 输入输出(I/O)是指CPU与输入设备和输出设备之间进行的信息传送。CPU与外部设备之间通过输入输出接口相连接。各个设备在输入输出接口中分配了相应的端口。访问不同的设备就是访问其对应的端口。在指令系统中提供了访问输入输出端口的指令。 一、I/O端口寻址方式.
FBs系列PLC 高级应用篇高速计数/定时器
5. 1 中 断 概 述 单片机接通电源后将循环执行我们编制好的程序(一般称为主程序),当有外部设备或内部部件要求CPU为其服务时,计算机将被迫“中断”主程序的执行,并记录下暂停处程序地址(断点地址),然后转去为外部设备服务,即执行中断服务程序;在中断程序执行完毕后自动返回被迫中断主程序的地址,继续执行原主程序。
数据报分片.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
HSC高速输出例程 HORNER APG.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
《手把手教你学STM32》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司 淘宝店铺:
定时中断与LED MCU起航 QQ:
6.1 定时器/计数器的结构及工作原理 定时器/计数器的结构 定时器/计数器T0、T1的逻辑结构如图6-1所示。
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
实验目的:掌握数据的顺序存储结构及它们在计算机中的操作。 实验内容:
得技通电子 问题 三 判断题:.
单片机应用技术 (C语言版) 第6章 中断系统.
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
上节复习(11.14) 1、方式2、方式0的特点? 2、定时/计数器的编程要点? 3、实验5方案优化问题.
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
FVX1100介绍 法视特(上海)图像科技有限公司 施 俊.
上节复习(11.7) 1、定时/计数器的基本原理? 2、定时/计数器的结构组成? 3、定时/计数器的控制关系?
培训课件 AB 变频器的接线、操作及参数的备份 设备动力科.
实验六、COM类型病毒分析实验 实验开发教师: 刘乃琦 谌黔燕.
《手把手教你学STM32-STemWin》 主讲人 :正点原子团队 硬件平台:正点原子STM32开发板 版权所有:广州市星翼电子科技有限公司
DSP技术与应用 电子与信息技术系.
Presentation transcript:

第23节 中断系统 (NVIC) Nesting Vector Interrupt Controller

小结 向量表定向-向量偏移寄存器 优先级分组 优先级寄存器 抢占优先级,响应优先级 Stm32 共支持59个外部中断源,即有59个中断通道 59个通道的开启或关闭有NVIC控制器决定(CM3内核)

NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 中断通道的使能与除能 CM3 中可以有240 对使能位/除能位,每个中断拥有一对。这240 对分布在8 对32 位寄存器中(最后一对没有用完)。 使能一个中断,需要写1 到对应SETENA 的位中; 除能一个中断,需要写1 到对应的CLRENA 位中; 如果往它们中写0,不会有任何效果

中断通道的使能与除能 具体芯片根据中断通道数不同,需要数目不同的相应使能和除能寄存器 对于stm32,59个外部中断通道,所以,需要两个32位使能寄存器和两个除能寄存器

另外,因为cm3支持中断嵌套,当中断发生时,正在处理高中断或同级中断,该中断会不会被错过? NVIC寄存器组 typedef struct { vu32 ISER[2]; //使能寄存器 u32 RESERVED0[30]; vu32 ICER[2]; //除能寄存器 u32 RSERVED1[30]; vu32 ISPR[2]; //中断挂起 u32 RESERVED2[30]; vu32 ICPR[2];//中断挂起清除 u32 RESERVED3[30]; vu32 IABR[2]; u32 RESERVED4[62]; vu32 IPR[15]; //优先级寄存器 } NVIC_TypeDef; 另外,因为cm3支持中断嵌套,当中断发生时,正在处理高中断或同级中断,该中断会不会被错过?

中断的挂起 中断请求状态被保存于中断挂起寄存器 当高级中断执行完毕,根据现有中断请求中的优先级别,选择高优先级的中断设为激活状态

中断挂起解除 当不需要在响应此中断,置1响应挂起清除寄存器,不在对其响应 同样,两个寄存器写1有效,写0无效

#define SCS_BASE ((u32)0xE000E000) #define SysTick_BASE (SCS_BASE + 0x0010) #define NVIC_BASE (SCS_BASE + 0x0100) #define SCB_BASE (SCS_BASE + 0x0D00)

NVIC寄存器组 typedef struct { vu32 ISER[2]; //使能寄存器 u32 RESERVED0[30]; vu32 ICER[2]; //除能寄存器 u32 RSERVED1[30]; vu32 ISPR[2]; //中断挂起 u32 RESERVED2[30]; vu32 ICPR[2];//中断挂起清除 u32 RESERVED3[30]; vu32 IABR[2]; u32 RESERVED4[62]; vu32 IPR[15]; //优先级寄存器 } NVIC_TypeDef; #define NVIC ((NVIC_TypeDef *) NVIC_BASE)

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; NVIC->ISER[0]=0x00800000;//使能23号外部中断 NVIC->ICER[0]=0x00800000;//除能23号外部中断

外部中断共有59个,每个中断用一个字节表示,4个中断用一个字,15个32位寄存器即可 如何设置优先级 NVIC->IPR[15] 外部中断共有59个,每个中断用一个字节表示,4个中断用一个字,15个32位寄存器即可 中断号左移2位即为优先级寄存器位置 23号中断,23>>2=0101=5 ,即NVIC->IPR[5]中定义其优先级 优先级分组为1的情况下:1位抢占,3位响应,高位对齐 如设定为抢占1,响应1 则: NVIC->IPR[5]=10010000=x90;

外部中断/事件控制器由20个产生事件/中断要求的边沿检测器组成。 NVIC控制器的中断通道已经使能打开 问题:怎样将外部管脚或中断源与中断通道对应? 外部中断/事件控制器由20个产生事件/中断要求的边沿检测器组成。 PA~E 0 对应 EXTI 0 输入线 PA~E 1 对应 EXTI 1 输入线 依次类推共15个输入线

􀁺 EXTI 线16 连接到PVD 输出 􀁺 EXTI 线17 连接到RTC 闹钟事件 􀁺 EXTI 线18 连接到USB 唤醒事件 EXTI 线19连接到以太网唤醒事件(只适 用于互联型产品)

每个输入线可以独立地配置输入类型和对应的触发事件(上升沿或下降沿或者双边沿都触发)。 每个输入线都可以被独立的屏蔽。 挂起寄存器可以保持着输入线的中断要求。

响应中断中的几个概念及问题: 1、输入线是否被配置及打开?输入线 2、是否设置触发方式?触发寄存器 3、当前中断优先级如何?是否被挂起? (优先级分组寄存器,优先级寄存器,挂起寄存器) 4、该中断是否被屏蔽?(中断屏蔽寄存器) 5、NVIC是否将该中断通道使能?(NVIC使能或除能寄存器)

因此,每个IO管脚都可设置为中断源 问题:如何选择? 既然是将IO口作为中断输入,首先需要对IO口进行设置。 1、输入线是否被配置及打开?输入线

配置GPIO针脚为输入模式 (1) 选择IO针脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; (2) 配置针脚为输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; (3) 初始化针脚 GPIO_Init(GPIOB,&GPIO_InitStructure); 接下来,将管脚的接受中断功能打开,用于接受中断,确定中断源。 AFIO寄存器

输入线被配置及打开 typedef struct { vu32 EVCR; vu32 MAPR; vu32 EXTICR[4]; } AFIO_TypeDef; 配置PB9作为中断源: AFIO->EXTICR[2]=0x0000 0010 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9); AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp; AFIO->EXTICR[GPIO_PinSource >> 0x02] | = (((u32)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (u8)0x03))); 输入线被配置及打开

2、是否设置触发方式?触发寄存器 3、该中断是否被屏蔽?(中断屏蔽寄存器)

2、是否设置触发方式?触发寄存器 3、该中断是否被屏蔽?(中断屏蔽寄存器) typedef struct { vu32 IMR; //中断屏蔽寄存器 vu32 EMR; //事件屏蔽寄存器 vu32 RTSR; //上升沿触发 vu32 FTSR; //下降沿触发 vu32 SWIER; //软件中断事件寄存器 vu32 PR; //挂起寄存器 } EXTI_TypeDef; 硬件中断选择 通过下面的过程来配置20个线路做为中断源: ● 配置20个中断线的屏蔽位(EXTI_IMR) ● 配置所选中断线的触发选择位(EXTI_RTSR和EXTI_FTSR); ● 配置对应到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽 位,使得20个中断线中的请求可以被正确地响应。 中断发生条件,不仅需要中断通道打开,而且需要中断源不被屏蔽。

2、是否设置触发方式?触发寄存器 3、该中断是否被屏蔽?(中断屏蔽寄存器) 硬件中断选择 通过下面的过程来配置20个线路做为中断源: ● 配置20个中断线的屏蔽位(EXTI_IMR) ● 配置所选中断线的触发选择位(EXTI_RTSR和EXTI_FTSR); ● 配置对应到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽 位,使得20个中断线中的请求可以被正确地响应。        /*配置EXTI线9上出现下降沿,则产生中断*/        EXTI_InitStructure.EXTI_Line = EXTI_Line9;        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发        EXTI_InitStructure.EXTI_LineCmd = ENABLE;     //中断线使能        EXTI_Init(&EXTI_InitStructure);                 //初始化中断

到此中断配置完成,可以写中断处理函数,存在9_5中断请求,向中断向量表取中断函数地址,执行此函数 void EXTI9_5_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_LINE_KEY_BUTTON) != RESET) /* Toggle GPIO_LED pin 6 */ GPIO_WriteBit(GPIO_LED, GPIO_Pin_6, (BitAction)((1-GPIO_ReadOutputDataBit(GPIO_LED, GPIO_Pin_6)))); /* Clear the Key Button EXTI line pending bit */ EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON); 清除挂起 }

2、设置中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 􀁺 EXTI 线16 连接到PVD 输出 􀁺 EXTI 线17 连接到RTC 闹钟事件 􀁺 EXTI 线18 连接到USB 唤醒事件 EXTI 线19连接到以太网唤醒事件 小结:外部中断配置 20条中断线,即20个中断通道 1、分配中断向量表 2、设置中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 3、 初始化外部中断(即选择并打开中断通道和优先级) NVIC_Init(&NVIC_InitStructure); 4、配置GPIO针脚作为外部中断(配置管脚为接收中断状态) GPIO_Init(GPIOD,&GPIO_InitStructure); 5、配置EXTI线(使中断线和IO针脚线连接上, 且不屏蔽中断源) EXTI_Init(&EXTI_InitStructure);    

实验五 EXTI外部中断 实验目的及内容: 分析实验程序,学习使用ARM开发实验箱 STM32的中断向量 外部中断线相关原理及配置方法 理解中断的过程 在此基础上,编写中断配置及处理函数代码

中断相关库函数声明 NVIC寄存器组包括两个主要模块: 中断控制 NVIC 系统控制 SCB typedef struct { vuc32 CPUID; vu32 ICSR; vu32 VTOR; vu32 AIRCR; vu32 SCR; vu32 CCR; vu32 SHPR[3]; vu32 SHCSR; vu32 CFSR; vu32 HFSR; vu32 DFSR; vu32 MMFAR; vu32 BFAR; vu32 AFSR; } SCB_TypeDef; typedef struct { vu32 ISER[2]; //中断设置使能 u32 RESERVED0[30]; vu32 ICER[2];//中断除能 u32 RSERVED1[30]; vu32 ISPR[2];//中断挂起寄存器 u32 RESERVED2[30]; vu32 ICPR[2];//清除中断挂起 u32 RESERVED3[30]; vu32 IABR[2];//中断活跃位 u32 RESERVED4[62]; vu32 IPR[15];//中断优先级 } NVIC_TypeDef;

NVIC外设声明于文件“stm32f10x_map.h”: ... #define SCS_BASE ((u32)0xE000E000) #define NVIC_BASE (SCS_BASE + 0x0100) #define SCB_BASE (SCS_BASE + 0x0D00) #ifndef DEBUG #ifdef _NVIC #define NVIC ((NVIC_TypeDef *) NVIC_BASE) #define SCB ((SCB_TypeDef *) SCB_BASE) #endif /*_NVIC */ #else /* DEBUG */ EXT NVIC_TypeDef *NVIC; EXT SCB_TypeDef *SCB;

NVIC库函数 NVIC_PriorityGroupConfig 函数名 NVIC_PriorityGroupConfig 函数原形 void NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup) 功能描述 设置优先级分组:抢占优先级和从优先级 输入参数 NVIC_PriorityGroup:优先级分组位长度 先决条件 优先级分组只能设置一次 NVIC_PriorityGroup 描述 NVIC_PriorityGroup_0 先占优先级0位 从优先级4位 NVIC_PriorityGroup_1 先占优先级1位 从优先级3位 NVIC_PriorityGroup_2 先占优先级2位 从优先级2位 NVIC_PriorityGroup_3 先占优先级3位 从优先级1位 NVIC_PriorityGroup_4 先占优先级4位 从优先级0位

库函数 函数NVIC_Init 函数名 NVIC_Init 函数原形 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 功能描述 根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 输入参数 NVIC_InitStruct:指向结构NVIC_InitTypeDef的指针,包含了外设GPIO的配置信息 typedef struct { u8 NVIC_IRQChannel; u8 NVIC_IRQChannelPreemptionPriority; u8 NVIC_IRQChannelSubPriority; FunctionalState NVIC_IRQChannelCmd; } NVIC_InitTypeDef;

使用方法: NVIC_InitStructure.NVIC_IRQChannel = 43个通道; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);

函数NVIC_SetVectorTable 函数名 NVIC_SetVectorTable 函数原形 void NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset) 功能描述 设置向量表的位置和偏移 输入参数1 NVIC_VectTab:指定向量表位置在RAM还是在程序存储器 参阅Section:NVIC_VectTab查阅更多该参数允许取值范围 输入参数2 Offset:向量表基地址的偏移量对FLASH,该参数值必须高于0x08000100;对RAM必须高于0x100。它同时必须是256(64×4)的整数倍

指定系统异常的优先级

外部中断EXTI寄存器结构,EXTI_TypeDef,在文件“stm32f10x_map.h”中定义如下: typedef struct { vu32 IMR; //中断屏蔽寄存器 vu32 EMR; //事件屏蔽寄存器 vu32 RTSR; //上升沿触发寄存器 vu32 FTSR; //下降沿触发寄存器 vu32 SWIER; //软中断 vu32 PR; //挂起寄存器 } EXTI_TypeDef; #define PERIPH_BASE ((u32)0x40000000) #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define EXTI_BASE (APB2PERIPH_BASE + 0x0400)

EXTI_InitStructure.EXTI_Line = EXTI_Line9; typedef struct { u32 EXTI_Line; EXTIMode_TypeDef EXTI_Mode; EXTIrigger_TypeDef EXTI_Trigger; FunctionalState EXTI_LineCmd; } EXTI_InitTypeDef; EXTI_InitStructure.EXTI_Line = EXTI_Line9; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);

几个概念: 1、关于嵌套的中断 a、 NVIC和CM3处理器排出优先级的顺序。因此,在某个异常正在响应时,所有优先级不高于它的异常都不能抢占之,而且它自己也不能抢占自己。 b、 支持自动入栈和出栈,就不用担心在中断发生嵌套时,会使寄存器的数据损毁,从而可以放心地执行服务例程。 注意:选择堆栈的大小

起因:所有服务例程都只使用主堆栈。所以当中断嵌套加深时,对主堆栈的压力会增大:每嵌套一级,就至少再需要8个字,即32字节的堆栈空间 因此:stm32最多16级中断,16*8=128个字ram.icf选择堆栈大小为0x400=256个字,以完全满足需求

2、咬尾中断 针对问题:紧接着处理悬起中断时,堆栈里的数据如何处理? Cm3处理方法,不pop数据,直接继续执行新的中断

3、晚到(的高优先级)异常 针对问题:当CM3对某异常的响应还处在入栈的阶段,尚未执行其服务例程时,如果此时收到了高优先级异常的请求,如何处理? Cm3:本次入栈就成了为高优先级中断所做的了——入栈后,将执行高优先级异常的服务例程。 在ISR #2执行完毕后,则以刚刚讲过的“咬尾中断”方式,来启动ISR #1的执行。 如果异常#2来得太晚,以至于已经执行了ISR #1的指令,则按普通的抢占处理。则需将#1号push堆栈,多增加32字节的堆栈空间

定义是:从检测到某中断请求,到执行了其服务例程的第一条指令,消耗的时间。 4、中断延迟 定义是:从检测到某中断请求,到执行了其服务例程的第一条指令,消耗的时间。 Cm3理想情况:12个周期。 若存储器系统够快,且总线系统允许入栈与取指同时进行,同时该中断可以立即响应 在此12个周期内,处理器进行入栈、取向量、更新寄存器以及服务例程取指的一系列操作 当处理咬尾中断时,省去了堆栈操作,因此切入新异常服务例程的耗时可以短至6周期。

5、Systick定时器 Cortex‐M3处理器内部包含了一个简单的定时器。 作用:定时产生一个systick中断(中断号:15 ) 大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。 例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 Cortex‐M3处理器内部包含了一个简单的定时器。 作用:定时产生一个systick中断(中断号:15 )

SysTick定时器被捆绑在NVIC中,用于产生SysTick异常

系统时钟节拍(SysTick)控制与状态寄存器 使用系统时钟节拍(SysTick)控制与状态寄存器来使能SysTick 功能。

系统时钟节拍(SysTick)重装值寄存器 初始值可以是1 到0x00FFFFFF 之间的任何值。 所以,systick是一个递减的24位定时器

系统时钟节拍(SysTick)校准值寄存器 使用系统时钟节拍(SysTick)校准值寄存器通过乘法和除法运算可以将寄存器调节成 任意所需的时钟速率。 系统时钟节拍(SysTick)校准值寄存器 使用系统时钟节拍(SysTick)校准值寄存器通过乘法和除法运算可以将寄存器调节成任意所需的时钟速率。

SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等 2、配置系统滴答定时器 (1)计数器当前值初始化为0; (2)根据时钟速度和定时需要初始化重装值 假如系统时钟为20M Hz, SYSTICK_RELOAD=20000;定时为1ms; 假如系统时钟为72MHz,需定时1ms,则 SYSTICK_RELOAD=72000; 假如系统时钟为72MHz,最长定时为? (3)选择时钟源并使能中断 对于stm32而言,时钟源可以为系统时钟(1),也可是外部时钟(此时为系统时钟的8分频) SYSTICK_CSR|=0x06; (4)在使用systick时,将其打开 SYSTICK_CSR|=0x01;

实现流程代码: 配置部分: /* AHB时钟作为systick时钟源 */ SysTick->CTRL |= 0x04; /* 系统抢占优先级为 1 */ NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 1, 0); /* SysTick interrupt each 1ms with HCLK equal to 72MHz */ SysTick->LOAD=72000; /* Enable the SysTick Interrupt */ SysTick->CTRL |= 0x02;

调用部分 while (1) { GPIO_Write(GPIOC, (u16)~GPIO_ReadOutputData(GPIOC)); Delay(3000); } void Delay(vu32 nTime) { /* 使能 SysTick 定时器 */ SysTick->CTRL |=0x01; TimingDelay = nTime;//每1ms进入一次中断 while(TimingDelay != 0) ;//直到进入了3000次中断 才停止 /* 禁止 SysTick 定时器 */ SysTick->CTRL &=0xFFFFFFFE; /* 清除当前计数寄存器值 */ SysTick->VAL = 0x0; void SysTickHandler(void) { TimingDelay--; }

实验六 优先级抢占实验 实验目的: 观察不同优先级之间的抢占 掌握外部中断和系统中断的配置方法 实验涉及3个中断: 外部中断0; 中断9_5; 系统滴答中断

初始状态: EXTI9_5: 抢占优先级0,响应优先级1 EXTI0: 抢占优先级1,响应优先级0 Systick: 抢占优先级2,响应优先级0 现象: 1、若不触发两个外部中断,6灯不断闪烁 2、若在执行systick中断程序时,按下wakeup,即EXTI0,则抢占systick 3、若按下EXTI9_5,则不论以上两个中断谁正执行,都将抢占,且改变两个中断的优先级别

NVIC_SetSystemHandlerPendingBit(SystemHandler_SysTick); 没有真正产生systick定时,只是设置其挂起位,让NVIC响应一个假中断 并没有打开systick