MicroBlaze定时器(Timer)的使用

MicroBlaze的Timer IP比较简单易用,一个XPS_TC IP包含两个32bit定时/计数器。工作方式也比较灵活,可以设置中断、自动加载、Count UP/DOWN等模式,每当timer溢出的时候产生中断,进入中断程序后通过写1 clear中断标志位,通常的做法是csr = = XTmrCtr_mGetControlStatusReg(XPAR_MY_TIMER_BASEADDR, 0);然后再“XTmrCtr_mSetControlStatusReg(XPAR_MY_TIMER_BASEADDR, 0, timer_csr);”,这样可以在不影响别的控制位的前提下clear中断标志位。

同样值得注意的是用了XIntc模块,要将timer中断服务程序连接(注册)到XIntc模块上。

使用Timer IP的流程是:

(1)设置Load Regisiter初始值;

(2)设置控制/状态寄存器,包括中断时能、timer使能、COUNT方向、Relaod使能等;

(3)注册中断服务函数;

(4)开MB全局中断和XIntc中断;

(5)等待中断发生。

(6)在中断服务程序中clear中断标志位。

例程(100MHz下,每一秒产生一个中断)

#include "xparameters.h"
#include "xutil.h"
#include "xintc.h"
#include "xtmrctr.h"
void timer_int_handler(void);
unsigned int push_button_times, timer_cnt;
int main()
{
 timer_cnt = 0;
 
 xil_printf("--start the program test---\r\n");
 
 XTmrCtr_mSetLoadReg(XPAR_MY_TIMER_BASEADDR, 0, 100000000);
 XTmrCtr_mSetControlStatusReg(XPAR_MY_TIMER_BASEADDR, 0,
        XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK |
        XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);
 //must enable mb_enable bit
 microblaze_enable_interrupts();
 
 //must enable xgpio_interruptglobalenable bit;
 //register the isr
 XIntc_RegisterHandler(XPAR_INTC_0_BASEADDR, \
        XPAR_XPS_INTC_0_MY_TIMER_INTERRUPT_INTR,\
        (XInterruptHandler)timer_int_handler, \
        (void *)0);
        
 //must enable XIntc_mMasterEnable
 XIntc_mMasterEnable(XPAR_INTC_0_BASEADDR);
 //must enable specific interrupt(s) in the interrupt controller.
 XIntc_mEnableIntr(XPAR_INTC_0_BASEADDR, \
      XPAR_PUSH_BUTTONS_POSITION_IP2INTC_IRPT_MASK\
      |XPAR_DIP_SWITCHES_8BIT_IP2INTC_IRPT_MASK\
      |XPAR_RS232_UART_INTERRUPT_MASK\
      |XPAR_MY_TIMER_INTERRUPT_MASK);
 
 while(1);
 return 0;
}
 
void timer_int_handler(void)
{
 unsigned int timer_csr;
 timer_cnt++;
 timer_csr = XTmrCtr_mGetControlStatusReg(XPAR_MY_TIMER_BASEADDR, 0);
 if(timer_csr & XTC_CSR_INT_OCCURED_MASK)
 {
  xil_printf("--timer interrupt happened times = %d!--\r\n", timer_cnt);
  XTmrCtr_mSetControlStatusReg(XPAR_MY_TIMER_BASEADDR, 0, timer_csr);
 }
}


好的,以下是一个参考的 MicroBlaze AXI Timer IP 精确微秒级延时函数的示例代码: ```c #include "xparameters.h" #include "xtmrctr.h" #define TIMER_DEVICE_ID XPAR_AXI_TIMER_0_DEVICE_ID #define TIMER_LOAD_VALUE 9999 // 设置定时器计数器的最大值 static XTmrCtr Timer; // 定时器实例 void delay_us(u32 us) { u32 tCount = 0; // 定时器计数器 u32 tDelta = 0; // 计算微秒延时的差值 u32 tTicks = 0; // 计算微秒延时的时钟周期数 XTmrCtr_Initialize(&Timer, TIMER_DEVICE_ID); // 初始化定时器 tDelta = (us * XPAR_CPU_CORE_CLOCK_FREQ_HZ) / 1000000; // 计算微秒延时的差值 tTicks = tDelta / (TIMER_LOAD_VALUE + 1); // 计算微秒延时的时钟周期数 XTmrCtr_SetLoadReg(Timer.BaseAddress, 0, TIMER_LOAD_VALUE); // 设置定时器计数器的最大值 XTmrCtr_LoadTimerCounterReg(Timer.BaseAddress, 0); // 重置定时器计数器 while (tCount < tTicks) { // 循环等待计时器计数 if (XTmrCtr_IsExpired(Timer.BaseAddress, 0)) { // 如果计时器计数溢出 tCount++; // 增加计数器计数 XTmrCtr_LoadTimerCounterReg(Timer.BaseAddress, 0); // 重置计时器计数器 } } } ``` 该函数接受一个以微秒为单位的参数,会在给定的时间内阻塞程序执行。函数内部使用 MicroBlaze 的 AXI Timer IP 进行计时,并根据计时器的时钟频率和计时器计数器的最大值计算出微秒延时的差值和时钟周期数。然后,在一个循环中,该函数会等待计时器计数达到预设的时钟周期数,以实现精确的微秒级延时。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值