【【FPGA 之 MicroBlaze定时器中断实验】】

FPGA 之 MicroBlaze定时器中断实验

AXI Timer 具有 AXI 总线接口,能够产生不同时间周期和占空比的时钟、脉冲产生电路、产生与时间有关的中断和用于电机控制的脉宽调制信号。
AXI Timer IP 核提供了一个 AXI4 Lite 接口用于与处理器通信;它内部有两个可编程的定时器,具有中断、事件生成和事件捕获功能,用户可根据自身需求选择 8、16、32 位定时器的计数宽度;通过对两个定时器联合操作,可以输出一个脉宽调制信号,我们可以通过该信号控制一些外设,如 LED 等;我们也可以对两个 32 位宽的定时器进行级联操作,生成一个 64 位宽的定时器;在软件调试期间冻结停止计数器的输入。
在这里插入图片描述

AXI4-Lite Interface(AXI4-Lite 接口):该 AXI4-lite 接口模块被设计成 AXI4-lite 从接口,用于访问内存映射的定时器寄存器,我们也可以通过该接口对各个寄存器模块进行配置。

Timer Registers(定时器寄存器):该模块是一组 32 位寄存器。这组寄存器包含加载寄存器(Load Register)、
定时器/计数器寄存器和控制/状态寄存器(Control/Status Registers)。加载寄存器保存用于事件生成的计数
器的初始值或捕获值。控制/状态寄存器包含定时器模块的控制位和状态位。

32-bit Counters(32 位寄存器):定时器/计数器模块有两个 32 位计数器,每个计数器可设置为递增或
递减计数,并可从加载寄存器中加载一个值。

Interrupt Control(中断控制):中断控制模块根据操作模式生成单个中断。

Pulse Width Modulation (PWM,脉宽调制):PWM 模块能够产生具有指定频率和占空比的脉冲信号
PWM0。它使用 Timer0 作为 PWM0 周期,Timer1 作为 PWM0 输出宽度。

本章的实验任务是 通过定时器产生中断,控制 LED 灯闪烁。

实验框图 如下
在这里插入图片描述

为了方便记忆 我们拿出最小系统
在这里插入图片描述

多了的就是 一个 AXI Timer 和 GPIO-LED

每次实验 我们都会介绍一下 当前使用的IP的各个选项意思及作用

在这里插入图片描述

配置完成之后 设计的总体结构布局 如图所示
在这里插入图片描述

我们修改 XDC 文件

create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
set_property PACKAGE_PIN R4 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
set_property PACKAGE_PIN U2 [get_ports sys_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports UART_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_txd]
set_property PACKAGE_PIN U5 [get_ports UART_rxd]
set_property PACKAGE_PIN T6 [get_ports UART_txd]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_tri_io[0]}]
set_property PACKAGE_PIN Y2 [get_ports {led_tri_io[3]}]
set_property PACKAGE_PIN V2 [get_ports {led_tri_io[2]}]
set_property PACKAGE_PIN R3 [get_ports {led_tri_io[1]}]
set_property PACKAGE_PIN R2 [get_ports {led_tri_io[0]}]

我们可以从 plantform 可以找到我们想要的 板级验证包 说实话 我觉得vitis 要比 SDK好用

#include <stdio.h>
 #include "xparameters.h"
 #include "xintc.h"
 #include "xtmrctr.h"
 #include "xil_exception.h"
 #include "xgpio.h"
 #include "xil_printf.h"

 #define LED_DEV_ID XPAR_GPIO_0_DEVICE_ID //LED ID
 #define INTC_ID XPAR_INTC_0_DEVICE_ID //中断控制器 ID
 #define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID //定时器中断 ID

 #define TMRCTR_INTR_ID XPAR_INTC_0_TMRCTR_0_VEC_ID //定时中断 ID

 #define XIL_EXCEPTION_ID_INT 16U //中断异常 ID

 #define LED_Channel 1

 XIntc Intc; //中断控制器实例
 XGpio led_gpio; //LED 实例
 XTmrCtr Timer; //定时器实例

 void timer_intr_hander(void *InstancePtr);

 int main(){
 print ("timer interrupt test\n");
 //初始化 LED
 XGpio_Initialize(&led_gpio, LED_DEV_ID);
 //为指定的 GPIO 信道设置所有独立信号的输入/输出方向
 XGpio_SetDataDirection(&led_gpio, 1, 0);
 //设置 LED 初始值
 XGpio_DiscreteWrite(&led_gpio, 1, 0x0f);
 //定时器初始化
 XTmrCtr_Initialize(&Timer, TMRCTR_DEVICE_ID);
 //为指定的计时器启用指定的选项。
 XTmrCtr_SetOptions(&Timer, 0,XTC_INT_MODE_OPTION | //中断操作
 XTC_AUTO_RELOAD_OPTION | //自动加载
XTC_DOWN_COUNT_OPTION); //递减计数

 //设置指定计时器的重置值
 XTmrCtr_SetResetValue(&Timer, 0, 50000000);
 //设置计时器回调函数,指定的计时器满一个周期时驱动程序将调用该回调函数
 XTmrCtr_SetHandler(&Timer, timer_intr_hander,&Timer);
 //开启定时器
 XTmrCtr_Start(&Timer, 0);
 //中断控制器初始化
 XIntc_Initialize(&Intc, INTC_ID);
 //关联中断源和中断处理函数
 XIntc_Connect(&Intc, TMRCTR_INTR_ID,
 (XInterruptHandler)XTmrCtr_InterruptHandler,&Timer);
 //开启中断控制器
 XIntc_Start(&Intc, XIN_REAL_MODE);
 //使能中断控制器
 XIntc_Enable(&Intc, TMRCTR_INTR_ID);
 //设置并打开中断异常处理
 Xil_ExceptionInit();
 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
 (Xil_ExceptionHandler)XIntc_InterruptHandler,
 &Intc);
 Xil_ExceptionEnable();

 while(1);
 }

 void timer_intr_hander(void *InstancePtr) //回调函数
 {
 static int led_state = 0x00;
 //检测定时器是否满一个计数周期
 if (XTmrCtr_IsExpired(&Timer, 0)){
 led_state = ~led_state; //LED 状态翻转
 XGpio_DiscreteWrite(&led_gpio, 1, led_state); //输出 LED 值
 }
 }

我们根据之前的对于中断的理解 可以这么理解
我们很明显的发现代码其实分为3个部分

一开始是 include 包含头文件

#include <stdio.h>
 #include "xparameters.h"
 #include "xintc.h"
 #include "xtmrctr.h"
 #include "xil_exception.h"
 #include "xgpio.h"
 #include "xil_printf.h"

接下来是

#define LED_DEV_ID     XPAR_GPIO_0_DEVICE_ID //LED ID
 #define INTC_ID        XPAR_INTC_0_DEVICE_ID //中断控制器 ID
 #define TMRCTR_DEVICE_ID     XPAR_TMRCTR_0_DEVICE_ID //定时器中断 ID

 #define TMRCTR_INTR_ID     XPAR_INTC_0_TMRCTR_0_VEC_ID //定时中断 ID

 #define XIL_EXCEPTION_ID_INT   16U //中断异常 ID

 #define LED_Channel 1

都是前面介绍过的

接下来的 19到 23行

XIntc Intc; //中断控制器实例
XGpio led_gpio; //LED 实例
XTmrCtr Timer; //定时器实例
void timer_intr_hander(void *InstancePtr);
是我们结构体介绍 还有声明 中断处理函数 

接下来2832//初始化 LED
XGpio_Initialize(&led_gpio, LED_DEV_ID);
//为指定的 GPIO 信道设置所有独立信号的输入/输出方向
XGpio_SetDataDirection(&led_gpio, 1, 0);
//设置 LED 初始值
XGpio_DiscreteWrite(&led_gpio, 1, 0x0f);

完成对基本的GPIO设置
(我们发现窍门没有 都是先初始化GPIO , 再设置一下 GPIO的 信号到底是输入还是输出 ,再确定

接下来轮到我们新使用的AXI Timer

//定时器初始化
XTmrCtr_Initialize(&Timer, TMRCTR_DEVICE_ID);
//为指定的计时器启用指定的选项。
XTmrCtr_SetOptions(&Timer, 0,XTC_INT_MODE_OPTION | //中断操作
XTC_AUTO_RELOAD_OPTION | //自动加载
XTC_DOWN_COUNT_OPTION); //递减计数
//设置指定计时器的重置值
XTmrCtr_SetResetValue(&Timer, 0, 50000000);
//设置计时器回调函数,指定的计时器满一个周期时驱动程序将调用该回调函数
XTmrCtr_SetHandler(&Timer, timer_intr_hander,&Timer);
//开启定时器
XTmrCtr_Start(&Timer, 0);

我们掐头去尾 仔细分析 头尾 是 这个block 中 其他的 关于中断也有的东西 拿到一个新的东西 先用来 初始化 最后 开启定时器 或者最后 使能中断控制器
我们现在来看中间的配置

//为指定的计时器启用指定的选项。
XTmrCtr_SetOptions(&Timer, 0,XTC_INT_MODE_OPTION | //中断操作
XTC_AUTO_RELOAD_OPTION | //自动加载
XTC_DOWN_COUNT_OPTION); //递减计数
//设置指定计时器的重置值
XTmrCtr_SetResetValue(&Timer, 0, 50000000);
//设置计时器回调函数,指定的计时器满一个周期时驱动程序将调用该回调函数
XTmrCtr_SetHandler(&Timer, timer_intr_hander,&Timer);
其实是一个 从现实来讲 很连贯的问题  我们初始化定时器了 那么要定时器执行什么功能
XTmrCtr_SetOptions(&Timer, 0,XTC_INT_MODE_OPTION | //中断操作
XTC_AUTO_RELOAD_OPTION | //自动加载
XTC_DOWN_COUNT_OPTION); //递减计数

ok 既然如此 那么至少设定一个初始值 让它到哪里停止 和从哪里开始 既然是递减 那么到最后了我们需要的干什么 执行回调函数代码第 41行设置生成值,这里我们设为 50000000,即 0.5 秒(由于处理器时钟频率为 100M)。代码第 43 行设置回调函数,当指定的定时器满一个周期时驱动程序将调用该回调函数。代码第 45 行启动指定的定时器。

在下面就是中断异常 启动等等 设计了

//中断控制器初始化
 XIntc_Initialize(&Intc, INTC_ID);
 //关联中断源和中断处理函数
 XIntc_Connect(&Intc, TMRCTR_INTR_ID,
 (XInterruptHandler)XTmrCtr_InterruptHandler,&Timer);
 //开启中断控制器
 XIntc_Start(&Intc, XIN_REAL_MODE);
 //使能中断控制器
 XIntc_Enable(&Intc, TMRCTR_INTR_ID);
 
 
 //设置并打开中断异常处理
 Xil_ExceptionInit();
 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
 (Xil_ExceptionHandler)XIntc_InterruptHandler,
 &Intc);
 Xil_ExceptionEnable();

然后 再下面 就是while 循环的 主要工作了

while(1) 

没了

最后一个是 回调函数的定义

void timer_intr_hander(void *InstancePtr) //回调函数
{
static int led_state = 0x00;
//检测定时器是否满一个计数周期
if (XTmrCtr_IsExpired(&Timer, 0)){
led_state = ~led_state; //LED 状态翻转
XGpio_DiscreteWrite(&led_gpio, 1, led_state); //输出 LED 值
}
}

在这里插入图片描述

整个调试窗口

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV-Python:计算机视觉框架

1.背景 俗话说“工欲善其事必先利其器”&#xff0c;想要学好计算机视觉&#xff0c;需要借助于相关的计算机视觉库&#xff0c;这样在进行学习的时候可以达到事半功倍的效果。 2.早期计算机视觉框架概述 Matlab的最早历史可以追溯到1970年&#xff0c;开始是作为数据处理工…

VL53-400激光测距传感器

一、产品简介 先由激光二极管对准目标发射激光脉冲。经目标反射后激光向各方向散射。部分散射光返回到传感器接收器&#xff0c;被光学系统接收后成像到雪崩光电二极管上。雪崩光电二极管是一种内部具有放大功能的光学传感器&#xff0c;因此它能检测极其微弱的光信号。记录并…

数据库设计实践:粒度的理解与应用示例

粒度是描述数据存储和表示的详细程度。在数据库设计中&#xff0c;理解和正确选择粒度是非常重要的&#xff0c;因为它直接影响到数据的存储效率、查询性能和数据分析的灵活性。 文章目录 粒度的类型&#xff1a;案例粒度选择的考虑因素实际应用 粒度的类型&#xff1a; 细粒度…

UI自动化Selenium find_elements和find_element的区别

# 如果获取的element是list&#xff0c;那么需要用find_elements方法&#xff1b;此方法会返回list&#xff0c;然后使用len() 方法&#xff0c;计算对象的个数&#xff1b; # find_element方法返回的不是list对象&#xff0c;所以导致没办法计算对象个数 # 1.返回值类型不同…

智慧工地一体化解决方案(里程碑管理)源码

智慧工地为管理人员提供及时、高效、优质的远程管理服务&#xff0c;提升安全管理水平&#xff0c;确保施工安全提高施工质量。实现对人、机、料、法、环的全方位实时监控&#xff0c;变被动“监督”为主动“监控”。 一、建设背景 施工现场有数量多、分布广&#xff0c;总部统…

2023.11.30 关于 MyBatis 动态 SQL 的使用

目录 引言 if 标签 trim 标签 where 标签 set 标签 foreach 标签 引言 动态 sql 是 MyBatis 的强大特性之一允许你根据输入的参数动态地构建 sql 语句从而在运行时根据不同的条件生成不同的 sql 核心思想 基于提供的数据和条件&#xff0c;能够修改、增加、删除 sql…

极智芯 | 解读国产AI算力 昆仑芯产品矩阵

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文分享一下 解读国产AI算力 昆仑芯产品矩阵。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码和资源下载,链接:https://t.zsxq.com/0aiNxERDq 昆仑芯来源于百度,2018 年…

用CHAT 写一份销售人员激励方案

问CHAT &#xff1a;写一份销售人员早会激励方案 CHAT回复&#xff1a; 标题&#xff1a;鼓舞斗志&#xff0c;迎接新的一天 -- 销售人员早会激励方案 一、会议的氛围设定&#xff1a; 深呼吸&#xff0c;准备开始一天的事业&#xff1a;清晨的阳光&#xff0c;温暖而明亮&…

redis------在java中操作redis

Redis&#xff08;非关系型数据库&#xff09;简介 redis下载 点击即可进入redis中文网进行下载 百度网盘windows版本 提取码 DMH6 redis主要特点 基于内存存储&#xff0c;读写性能高 适合存储热点数据&#xff08;热点商品、资讯、新闻&#xff09; 企业应用广泛 redis不同…

【代码】CNN-GRU-Attention基于卷积神经网络和门控循环单元网络结合注意力机制的多变量回归预测

程序名称&#xff1a;CNN-GRU-Attention基于卷积神经网络和门控循环单元网络结合注意力机制的多变量回归预测 实现平台&#xff1a;matlab 代码简介&#xff1a;为更准确地预测&#xff0c;提出基于注意力机制的CNN-G&#xff32;U预测模型。该模型主要借助一维卷积单元提取数…

Filebeat使用指南

Filebeat介绍主要优势主要功能配置日志的解析Kibana中设置日志解析安装步骤安装Filebeat安装监控通过prometheus监控 Filebeat和Logstash的主要区别 Filebeat介绍 Filebeat是使用Golang实现的轻量型日志采集器&#xff0c;也是Elasticsearch stack的一员。它可以作为一个agent…

全网关键词采集,免费关键词采集软件使用方法

网站的SEO优化已经成为企业提升在线可见性的不二选择。而关键词的选择和使用则是SEO优化的核心。本文将专心分享关键词采集的正确用法&#xff0c;助您在SEO的道路上掌握正确的方向。 关键词采集&#xff1a;SEO的基础 让我们明确关键词采集的重要性。在搜索引擎的世界里&…

计算机组成学习-数据的表示和运算总结

1、进制与编码 1.1 进位计数法 常用的进位计数法有十进制、二进制、八进制、十六进制等。十六进制每个 数位可取0〜9、A、B、C、D、E、F中的任意一个&#xff0c;其中A、B、C、D、E、F分别表示 10〜15。 八进制数字通常以前缀 "0"&#xff08;零&#xff09;加上数…

【openssl】Window系统如何编译openssl

本文主要记录如何编译出windows版本的openss的lib库 1.下载openssl&#xff0c;获得openssl-master.zip。 a.可以通过github&#xff08;网址在下方&#xff09;上下载最新的代码、今天是2023.12.1我用的master版本&#xff0c;下载之后恭喜大侠获得《openssl-master.zip》 …

Redis高可用集群架构

高可用集群架构 哨兵模式缺点 主从切换阶段&#xff0c; redis服务不可用&#xff0c;高可用不太友好只有单个主节点对外服务&#xff0c;不能支持高并发单节点如果设置内存过大&#xff0c;导致持久化文件很大&#xff0c;影响数据恢复&#xff0c;主从同步性能 高可用集群…

【开源】基于JAVA语言的考研专业课程管理系统

项目编号&#xff1a; S 035 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S035&#xff0c;文末获取源码。} 项目编号&#xff1a;S035&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高…

Python练习题(一)

&#x1f4d1;前言 本文主要是【Python】——Python练习题的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

vscode 里怎么自动提示 webpack 配置项?

webpack 的配置项非常多&#xff0c;容易忘记&#xff0c;能自动提示很有用&#xff0c;就是在配置文件里面添加下面代码 // 下面这行用于 vscode 中智能化自动提示 webpack 配置项 /** type {import(webpack).Configuration} */

从认知到实现,一文读懂实现分布式锁的五种方案。

文章目录 01. 什么是分布式锁&#xff1f; 02. 分布式锁的优缺点有哪些&#xff1f; 03. 五种分布式锁的区别&#xff1f; 04. 分布式锁的使用场景有哪些&#xff1f; 05. 为什么需要分布式锁&#xff1f; 06. 分布式锁有哪些特点&#xff1f; 07. 基于MySQL数据库实现的分布式…

nextjs入门

创建项目 npx create-next-app 项目名 体验文件路由 nextjs提供了文件路由的功能, 根据文件系统的目录结构, 可以识别为对应的页面路由 创建页面 首先, 在src下创建pages目录, 然后创建一个about文件(对应about页面)和main/index.js文件(对应首页) pages/main/index con…