当前位置: 首页 > news >正文

Zynq开发实践(SDK之定时器)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        定时器是芯片提供的一个常见功能。尤其是在mcu里面,如果我们不想使用rtos开发固件程序,一般情况下就会选择轮询+定时器中断来处理,最多加一个状态机。当然在处理的过程中,还有可能需要处理其他的中断,这也是有可能的。今天就看看zynq上面怎么处理定时器的。

1、私有定时器和公共定时器

        由于zynq上面是双核a9 cpu,所以定时器本身就分成了两种。一种是私有定时器,每个cpu各一个。还有一个是公共定时器。我们自己写代码的时候,如果只是在一个core上面运行,可以只设置私有定时器即可。如果还有其他core需要处理,core0处理定时器的时候,发一个核间中断也可以。

2、定时器不需要外设pin脚

        本身定时器就是和clock相关,和cpu相关,不需要任何的外设pin脚。

3、如何做block design

        和第一个纯PS工程一样,添加好soc之后,去掉三个接口、添加mio14、mio15串口、添加ddr3初始化即可。

4、参考的代码

        参考的代码,就是最简单的hello world工程。

5、创建定时器、初始化中断、开始轮询

        整个流程还是比较简单的,首先就是创建定时器,设置一下定时器的相关参数,比如多长时间trigger一下等等。接下来就是初始化中断,zynq里面的中断也是一个外设接口。这些都做好了,就是开始轮询设置了。

int main()
{int Status;XScuTimer_Config *ConfigPtr;init_platform();xil_printf("SCU Private Timer Demo Start\r\n");// load configurationConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);if (ConfigPtr == NULL)return XST_FAILURE;// initialize timerStatus = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS)return XST_FAILURE;//  1s = 333000000 cyclesXScuTimer_LoadTimer(&TimerInstance, 333000000);XScuTimer_EnableAutoReload(&TimerInstance);Status = SetupInterruptSystem(&IntcInstance, &TimerInstance);if (Status != XST_SUCCESS)return XST_FAILURE;// enable interruptXScuTimer_EnableInterrupt(&TimerInstance);// enable timerXScuTimer_Start(&TimerInstance);while (1) {if (TimerExpired) {xil_printf("Timer Interrupt Triggered!\r\n");TimerExpired = 0;}}cleanup_platform();return XST_SUCCESS;
}

6、中断初始化和定时器中断注册

        定时器的触发,这里是通过中断实现的。我们有必要初始化中断,关联中断号,并且注册一下回调函数。这样中断发生的时候,这个回调函数就可以直接被引用。

// callback functionvoid TimerIntrHandler(void *CallBackRef)
{XScuTimer *Timer = (XScuTimer *)CallBackRef;XScuTimer_ClearInterruptStatus(Timer);TimerExpired = 1;xil_printf("Timer Interrupt Happened, counter = %d!\r\n", counter++);
}int SetupInterruptSystem(XScuGic *IntcInstancePtr, XScuTimer *TimerInstancePtr)
{int Status;XScuGic_Config *IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);if (NULL == IntcConfig)return XST_FAILURE;Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);if (Status != XST_SUCCESS)return XST_FAILURE;Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,IntcInstancePtr);// register callback functionStatus = XScuGic_Connect(IntcInstancePtr, TIMER_IRPT_INTR_ID,(Xil_ExceptionHandler)TimerIntrHandler,(void *)TimerInstancePtr);if (Status != XST_SUCCESS)return XST_FAILURE;XScuGic_Enable(IntcInstancePtr, TIMER_IRPT_INTR_ID);Xil_ExceptionEnable();return XST_SUCCESS;
}

        这些都准备好了之后,就可以连接jtag、连接串口,准备开始调试了,

7、为什么定时器这么重要

        定时器就像人的心脏一样,推进各个业务往前走。不同的外部接口,不同的中断,都是在定时器的舞动之下,一步一步实现状态的变更。这中间哪怕没有高级的rtos,只要有定时器+状态机,也可以开发出很多有意思的产品。

        最后给出完整的代码,有兴趣的同学可以好好参考下,

#include "xscutimer.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xparameters.h"
#include "xil_printf.h"#include "platform.h"#define TIMER_DEVICE_ID      XPAR_XSCUTIMER_0_DEVICE_ID
#define INTC_DEVICE_ID       XPAR_SCUGIC_SINGLE_DEVICE_ID
#define TIMER_IRPT_INTR_ID   XPAR_SCUTIMER_INTRstatic XScuTimer TimerInstance;
static XScuGic IntcInstance;volatile int TimerExpired = 0;
static int counter = 0;// callback functionvoid TimerIntrHandler(void *CallBackRef)
{XScuTimer *Timer = (XScuTimer *)CallBackRef;XScuTimer_ClearInterruptStatus(Timer);TimerExpired = 1;xil_printf("Timer Interrupt Happened, counter = %d!\r\n", counter++);
}int SetupInterruptSystem(XScuGic *IntcInstancePtr, XScuTimer *TimerInstancePtr)
{int Status;XScuGic_Config *IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);if (NULL == IntcConfig)return XST_FAILURE;Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);if (Status != XST_SUCCESS)return XST_FAILURE;Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,IntcInstancePtr);// register callback functionStatus = XScuGic_Connect(IntcInstancePtr, TIMER_IRPT_INTR_ID,(Xil_ExceptionHandler)TimerIntrHandler,(void *)TimerInstancePtr);if (Status != XST_SUCCESS)return XST_FAILURE;XScuGic_Enable(IntcInstancePtr, TIMER_IRPT_INTR_ID);Xil_ExceptionEnable();return XST_SUCCESS;
}int main()
{int Status;XScuTimer_Config *ConfigPtr;init_platform();xil_printf("SCU Private Timer Demo Start\r\n");// load configurationConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);if (ConfigPtr == NULL)return XST_FAILURE;// initialize timerStatus = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS)return XST_FAILURE;//  1s = 333000000 cyclesXScuTimer_LoadTimer(&TimerInstance, 333000000);XScuTimer_EnableAutoReload(&TimerInstance);Status = SetupInterruptSystem(&IntcInstance, &TimerInstance);if (Status != XST_SUCCESS)return XST_FAILURE;// enable interruptXScuTimer_EnableInterrupt(&TimerInstance);// enable timerXScuTimer_Start(&TimerInstance);while (1) {if (TimerExpired) {xil_printf("Timer Interrupt Triggered!\r\n");TimerExpired = 0;}}cleanup_platform();return XST_SUCCESS;
}

http://www.dtcms.com/a/390220.html

相关文章:

  • Java IO核心知识提问点
  • 微前端--前端架构的模块化革命
  • SQL分析-基础
  • V821---4M高集成无线视频芯片
  • count down 92 days
  • 学习日记-JS+DOM-day58-9.18
  • 【Python】基于界面库PyQt5+QTLinguist的多语言切换功能实现
  • Flutter 组件介绍:TickerMode
  • SQL 聚合函数总结:COUNT、SUM、AVG、MAX、MIN 详解
  • 资深专业新媒体营销数字营销培训老师商学院教授课程老师培训讲师唐兴通讲授10大经典社群私域案例:Lululemon的热汗式信仰社群运营社群活动
  • 玉米病虫害数据集检测识别数据集:近4k图像,7类,yolo标注
  • Batch Size与预热导致深度学习模型推理时间忽快忽慢
  • 过滤器(Filter)与拦截器(Interceptor)知识点总结
  • 深度学习与机器学习
  • Linux服务器从零开始-mysql安装
  • Emacs 折腾日记(三十)——打造C++ IDE 续
  • 解密DNS:互联网的隐形导航系统
  • Mysql修改用户密码,修改MySQL密码如何安全的步骤是什么
  • PS练习2:将图片贴入实际环境中
  • cocos shader 流光环绕
  • kali nethunter 开启ssh
  • vue3滚动到顶部钩子函数+组件简单示例
  • Linux 开发工具(3)
  • Hive 运行
  • PPT中为图片添加透明渐变的蒙版
  • 数字签名过程中的消息摘要和加密的作用
  • Unity物理系统笔记
  • 区分同步(Synchronous)和异步(Asynchronous)
  • 隐语开源隐私计算SecretFlow,实测性能提升10倍,纵向联邦SecureBoost算法(已开源)
  • 云南食品安全管理员考试都考哪些知识点