ARM体系结构和接口技术(十一)定时器中断实验

news2024/12/23 13:31:04

文章目录

  • 一、实验分析
  • 二、RCC章节:找到外设基地址并使能外设控制器时钟源
      • 1. RCC
      • 2. GICC和GICD
      • 3. TIM3
  • 三、TIM3章节
    • (一)CR1寄存器
    • (二)DIER寄存器
    • (三)SR寄存器
    • (四)PSC寄存器
    • (五)ARR寄存器
  • 四、GIC章节
    • (一)查看TIM3中断的中断号
    • (二)GICD
      • 1. GICD_CTLR
      • 2. GICD_ISENABLERx
      • 3. GICD_ICPENDRx
      • 4. GICD_IPRIORITYRx
      • 5. GICD_ITARGETSRx
    • (三)GICC
      • 1. GICC_CTRL
      • 2. GICC_PMR
      • 3. GICC_IAR
      • 4. GICC_EOIR
  • 五、代码实现
  • 六、通过定时器实现按键消抖

一、实验分析

在这里插入图片描述
通过定时器TIM3的计数功能,产生一个定时器中断,将中断信号转发给GIC;
GIC控制器接收到中断信号后,将其转发给指定的CPU进行处理。
其中,RCC为TIM3提供时钟源。

  • 注:此时定时器只用于计数功能,并不需要再产生PWM方波,因此无需再配置捕获比较寄存器,仅配置自动重装载寄存器即可。
    在这里插入图片描述

二、RCC章节:找到外设基地址并使能外设控制器时钟源

1. RCC

在这里插入图片描述
RCC挂在AHB4总线,基地址0x50000000

2. GICC和GICD

在这里插入图片描述
GICC和GICD挂在Cortex-A7核内部总线,无需开发人员手动使能时钟源
GICC基地址0xA0022000
GICD基地址0xA0021000

3. TIM3

在这里插入图片描述
TIM3挂在APB1总线上,需要手动使能时钟源
TIM3基地址0x40001000

三、TIM3章节

在这里插入图片描述
当发生更新事件时会置位更新中断标志位,
因此需要设置相关的寄存器使能该标志位,在处理完中断后需要清除该标志位

(一)CR1寄存器

在这里插入图片描述
ARPE:使能自动重载寄存器的缓冲区
CMS:设置对齐模式,选择边沿对齐
DIR:计数方向,此处选择向下计数
CRN:计数器使能位

(二)DIER寄存器

在这里插入图片描述
在这里插入图片描述
此处将UIE位置1,使能更新中断

(三)SR寄存器

在这里插入图片描述
在这里插入图片描述
UIF
读1,说明中断挂起,即中断发生了。
写0,清除中断标志位。

(四)PSC寄存器

在这里插入图片描述
分频寄存器,
注意,该寄存器是16位寄存器,因此分频值可设置为0~65535,即可以设置为1~65536分频

(五)ARR寄存器

在这里插入图片描述
自动重载寄存器
此处使用TIM3为一个16位的寄存器,因此其可装载的数值范围为0~65535

四、GIC章节

(一)查看TIM3中断的中断号

在这里插入图片描述

(二)GICD

1. GICD_CTLR

在这里插入图片描述
使能GROUP0

2. GICD_ISENABLERx

在这里插入图片描述
使能中断号。
TIM3中断号是61,ISENABLER每个寄存器设置32个中断,
61/32=1…29
因此设置GICD_ISENABLER[1]的第29位为1,使能

3. GICD_ICPENDRx

在这里插入图片描述
写1,清除终端挂起标志位

4. GICD_IPRIORITYRx

在这里插入图片描述

设置中断权限
每个寄存器管理4个中断号,
61/4=15…1
因此需要设置GICD_IPRIOROTYR[15]的第8*1+3位

5. GICD_ITARGETSRx

在这里插入图片描述
设置中断分配给哪个CPU,每个寄存器管理4个中断号
61/4=15…1
因此需要设置GICD_ITAGETS[15]的第8*1位

(三)GICC

1. GICC_CTRL

在这里插入图片描述
使能GROUP0

2. GICC_PMR

在这里插入图片描述
设置权限掩码

3. GICC_IAR

在这里插入图片描述

4. GICC_EOIR

在这里插入图片描述

五、代码实现

实现一个5s中断

tim.c

void tim3_IT_init(void){
    //时钟源使能
    RCC_APB1->tim3_en=1;
    //PSC寄存器设置分频值为10000 未分频是209MHz,分频209000就是1000Hz
    TIM3->PSC=20900-1; //分频后时钟为1MHz
    TIM3->ARR=10000; //计数值为1000,此时就是1S
    TIM3->CR1.ARPE=1;//预加载寄存器使用缓冲区
    TIM3->CR1.DIR=1;//向下计数
    TIM3->CR1.CMS=0;//边沿
    TIM3->DIER |= 0x1<<0; //使能更新中断
    
    TIM3->CR1.CEN=1;//使能定时器
}

gic.c

void gic_tim3_init(void){
    //使能GICD中断号
    GICD->ISENABLER[1] |= (0x1<<29);      //使能GICD中断号9   61/32=1...29
    //设置优先级
    GICD->IPRIORITYR[15] &= ~(0xf<<11);
    GICD->IPRIORITYR[15] |= (0x5<<11);    //设置优先级        61/4=15...1

    //分配CPU
    GICD->ITARGETSR[15] &= ~(0x3<<8);
    GICD->ITARGETSR[15] |= (0x1<<8);  //设置中断给CPU0  61/4=15...1

    GICD->CTRL |= (0x1<<0);      //使能GICD组0
    //配置GICC
    GICC->PMR |= 0x1f<<3;         //31
    GICC->CTLR|= 0x1<<0;         //使能GICC
}

do_irq.c

static unsigned int count = 0;
void do_irq(void) 
{
    int irqnum=0;
    irqnum = GICC->IAR & 0x1ff;
    switch(irqnum){
        case 61:    //tim3中断
            count++;
            if(count==5){
                printf("interrupt 5s\n");
                count=0;
            }
            TIM3->SR &= ~(0x1<<0);//清除中断标志位
            GICD->ICPENDR[1] |=(1<<29); //61/32=1 61%32=29
        break;
    }
    GICC->EOIR = irqnum;
}

六、通过定时器实现按键消抖

tim3.c

void tim3_xiaodou_init(void){
    //时钟源使能
    RCC_APB1->tim3_en=1;
    //PSC寄存器设置分频值为10000 未分频是209MHz,分频209000就是1000Hz
    TIM3->PSC=209-1; //分频后时钟为1MHz
    TIM3->ARR=10000; //计数值为1000,此时就是1ms
    TIM3->CR1.ARPE=1;//预加载寄存器使用缓冲区
    TIM3->CR1.DIR=1;//向下计数
    TIM3->CR1.CMS=0;//边沿
    TIM3->DIER |= 0x1<<0; //使能更新中断
    
    TIM3->CR1.CEN=1;//使能定时器
}

gic.c

void gic_tim3_init(void){
    //使能GICD中断号
    GICD->ISENABLER[1] |= (0x1<<29);      //使能GICD中断号9   61/32=1...29
    //设置优先级
    GICD->IPRIORITYR[15] &= ~(0xf<<11);
    GICD->IPRIORITYR[15] |= (0x5<<11);    //设置优先级        61/4=15...1

    //分配CPU
    GICD->ITARGETSR[15] &= ~(0x3<<8);
    GICD->ITARGETSR[15] |= (0x1<<8);  //设置中断给CPU0  61/4=15...1

    GICD->CTRL |= (0x1<<0);      //使能GICD组0

    //配置GICC
    GICC->PMR |= 0x1f<<3;         //31
    GICC->CTLR|= 0x1<<0;         //使能GICC
}

do_irq.c

void do_irq(void) 
{
    int irqnum=0;
    irqnum = GICC->IAR & 0x1ff;
    switch(irqnum){
        case 61:    //tim3中断
            if(!gpio_read(GPIOF,KEY1_PORT)){
                printf("key1 down!\n");
            }
            if(!gpio_read(GPIOF,KEY2_PORT)){
                printf("key2 down!\n");
            }
            if(!gpio_read(GPIOF,KEY3_PORT)){
                printf("key3 down!\n");
            }
            TIM3->SR &= ~(0x1<<0);//清除中断标志位
            GICD->ICPENDR[1] |=(1<<29); //61/32=1 61%32=29
            TIM3->CR1.CEN=0;//关闭定时器
        break;
        case 97:  //KEY2
            tim3_xiaodou_init();
            EXTI->FPR1.event7=1; //清除EXTI中断
            GICD->ICPENDR[3] |= (1<<1);//清除GICD中断
        break;
        case 98:
            tim3_xiaodou_init();
            EXTI->FPR1.event8=1; //清除EXTI中断
            GICD->ICPENDR[3] |= (1<<2);//清除GICD中断
        break;
        case 99: //KEY1
            tim3_xiaodou_init();
            EXTI->FPR1.event9=1; //清除EXTI中断
            GICD->ICPENDR[3] |= (1<<3);//清除GICD中断
        break;
    }
    GICC->EOIR = irqnum;
}

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

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

相关文章

JS中this的指向问题、JS的执行机制、offset、client、scroll

JS中this的指向问题 1. 在全局环境下 在全局环境中&#xff08;在浏览器中是 window 对象&#xff0c;在Node.js中是 global 对象&#xff09;&#xff0c;this 指向全局对象。 console.log(this window); // 在浏览器中为 true console.log(this.document ! undefined); //…

基于ssm+vue+uniapp的农业电商服务系统小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

代码随想录算法训练营第四十一天 | 121. 买卖股票的最佳时机 , 122.买卖股票的最佳时机II , 123.买卖股票的最佳时机III

目录 121. 买卖股票的最佳时机 思路 暴力 贪心 动态规划 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 2.确定递推公式 3.dp数组如何初始化 4.确定遍历顺序 5.举例推导dp数组 方法一&#xff1a; 贪心 方法二&#xff1a;动态规划1 方法三&#xf…

使用rqt_console和roslaunch

1.使用rqt_console和rqt_logger_level rosrun rqt_console rqt_console 执行完该命令后有如下界面: 继续执行如下命令: rosrun rqt_logger_level rqt_logger_level 此时有如下新界面: 接下来继续运行如下命令: rosrun turtlesim turtlesim_node 上面第一…

慢sql问题解决,sql优化,数据库(mysql)

文章目录 1、count效率比较2、作者遇到的慢sql问题2.1、使用排序导致变慢问题2.2、使用LEFT JOIN 导致索引失效的问题2.3、子查询导致索引失效 3、explain命令介绍4、阿里云rds数据库&#xff08;mysql的一种&#xff09;主键索引查询很慢问题参考文档 1、count效率比较 所以结…

初识C++(8.27)

用C实现: 提示并输入一个字符串&#xff0c;统计该字符串中字母个数、数字个数、空格个数、其他字符的个数. #include <iostream> #include <string>using namespace std;int main() {string str;cout << "请输入一个字符串: ";getline(cin, str…

uni-app - - - - - 使用uview-plus详细步骤

uni-app - - - - - 使用uview-plus详细步骤 1. 使用HbuilderX创建空白项目2. 安装插件3. uview-plus配置使用3.1 main.js配置3.2 uni.scss配置3.3 App.vue配置3.4 pages.json 4. 重启Hbuilderx 1. 使用HbuilderX创建空白项目 2. 安装插件 工具 > 插件安装 > 前往插件市场…

用Python探究两组变量的相关性_典型相关分析(CCA)模板

典型相关分析&#xff08;Canonical Correlation Analysis, CCA&#xff09;是一种多变量统计分析方法&#xff0c;用于研究两组变量之间的整体相关性。它的基本原理是在两组变量中分别提取有代表性的两个综合变量&#xff08;即两组变量的线性组合&#xff09;&#xff0c;通过…

Java设计模式之工厂模式详细讲解和案例示范

在Java的设计模式中&#xff0c;工厂模式&#xff08;Factory Pattern&#xff09;是最常见和最有用的一种创建型模式。工厂模式的核心思想是将对象的创建与使用分离&#xff0c;从而提供了一种灵活的方式来创建不同类型的对象。这种模式尤其适用于复杂对象的创建过程&#xff…

HTTrack镜像网站实践

目录 前言 Windows下使用HTTrack HTTrack安装 HTTrack使用 Kali linux下使用HTTrack HTTrack安装 HTTrack使用 前言 在特殊时期&#xff0c;不想把真实的网站页面展示给用户&#xff0c;但又不能关停。此刻&#xff0c;可以用镜像网站替换真实网站&#xff0c;降低安全风…

Golang | Leetcode Golang题解之第378题有序矩阵中第K小的元素

题目&#xff1a; 题解&#xff1a; func kthSmallest(matrix [][]int, k int) int {n : len(matrix)left, right : matrix[0][0], matrix[n-1][n-1]for left < right {mid : left (right - left) / 2if check(matrix, mid, k, n) {right mid} else {left mid 1}}retur…

52.给定一个整数 n,实现一个算法返回 n 皇后不同的解决方案的数量

52. N-Queens II 题目 n皇后问题是指将n个皇后放置在一个nn的棋盘上,使得任意两个皇后不在同一行、同一列或同一对角线上。 给定一个整数 n,返回 n 皇后问题不同的解法数量。 示例: 输入: 4 输出: 2 解释: 4皇后问题有如下两个不同的解法: [ [“.Q…”, // 解法 1 “……

LabVIEW反编译与源程序加密破解

最近&#xff0c;不少粉丝咨询如何将生成的 LabVIEW 可执行程序反编译&#xff0c;所以写了这篇文章来详细探讨这个话题。反编译问题引起了广泛的关注&#xff0c;许多开发者希望能够从现有的可执行文件中提取源代码&#xff0c;以便进行修改或重新利用。然而&#xff0c;反编译…

Java基础:什么是多态

什么是多态 多态是面向对象的三大特性之一&#xff08;另外两个是封装和继承&#xff09;&#xff0c;指的是同一个方法能执行不同的行为&#xff0c;在代码上的体现是&#xff1a;声明为父类的对象&#xff0c;可以被不同的实现类赋值&#xff0c;其中实现类必须继承或者实现…

OpenCV图像拼接多频段融合源码重构

OpenCV图像拼接多频段融合源码重构 图像拼接是计算机视觉中的一个常见问题&#xff0c;OpenCV提供了十分完善的算法类库。作者使用OpenCV4.6.0进行图像拼接&#xff0c;其提供了包括曝光补偿、最佳缝合线检测以及多频段融合等图像拼接常用算法&#xff0c;测试发现多频段融合算…

uni-app - - - - - 自定义tabbar

uni-app - - - - - 自定义tabbar 1. 创建页面2. pages.json3. 自定义tabbar4. 隐藏原生tabbar5. 全局注册组件6. 页面使用7. 效果图展示 1. 创建页面 2. pages.json 配置tabbar {"tabBar": {"list": [{"pagePath": "pages/ballroom/ballr…

认知杂谈25

今天分享 有人说的一段争议性的话 I I 《拖延症&#xff0c;谁都有过》 嘿&#xff0c;朋友们&#xff01;咱都来说说&#xff0c;拖延症这玩意儿&#xff0c;好多人都被它给缠上啦。你看哈&#xff0c;本来计划得好好的&#xff0c;今天要把房间收拾得干干净净&#xff0c;可…

SSH弱口令爆破服务器

一、实验背景 1、概述 使用kali的hydra进行ssh弱口令爆破&#xff0c;获得服务器的用户名和口令&#xff0c;通过 ssh远程登录服务器。 2、实验环境 kali攻击机&#xff1a;192.168.1.107 centos服务器&#xff1a;192.168.1.105 二、前置知识 1、centos设置用户并设置弱…

软件设计原则之接口隔离原则

接口隔离原则&#xff08;Interface Segregation Principle, ISP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它属于SOLID原则之一。这个原则强调客户端&#xff08;即接口的调用者&#xff09;不应该被迫依赖于它们不使用的方法。换句话说&#xff0c;一个类对另一…

【区块链 + 司法存证】数据存证区块链服务开放平台 | FISCO BCOS应用案例

大数据时代&#xff0c;数据参与社会生产过程&#xff0c;实现价值增值&#xff0c;是一种新型生产要素。数据产品具有易复制、易修改等特点&#xff0c; 因而数据产品在使用、流通过程中面临被非法复制、非法传播、非法篡改和知识产权窃取等安全风险。在存证数 据上链过程中&a…