NIOS II 定时器的使用

初始化,即对定时器进行清零

清零的方式有两种,一种是用定时器清零,另外一种是使用库函数,主要是io.h这个库里面的。
这里主要讲一下使用库函数,因为使用库函数可以使得程序的可读性更强。

1
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE,0x00);  //清除timer1中断标志位

其中TIMER1_BASE是定时器1的基地址,在system.h头文件中。

设置定时周期

同样建议使用库函数。

1
2
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER1_BASE,timer_prd[j]);      //低16位
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER1_BASE,timer_prd[j]>>16); //高16位

其中XXX_PERIODL和XXX_PERIODH分别为定时器的周期的低十六位和高十六位。这里需要提醒大家的一点是,不要超出16位,否则会丢失高位。

启动定时器
1
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,0X07);  //启动timer1 

这里0x07主要是对某一些特定的标志位进行操作,启动定时器。

注册定时器。

这里的注册需要解释一下,这个可能和os有点联系,nios后台有个操作系统,当定时器中断产生以后,后台就会响应这个中断,也就是执行这个中断对应的中断函数。

1
alt_irq_register(TIMER1_IRQ,NULL,ISR_timer1);   //注册timer1

这里的ISR_timer1就是定时器1对应的中断函数,ISR_timer1是这个中断函数对应的函数名称。(函数名实质就是一个指针,只不过这个指针是函数指针)。
我们可在中断函数中进行一些短时的操作,不宜进行复杂长时操作,主要是考虑到时间过长会引起定时器溢出。

设置定时器中断函数
1
2
3
4
5
6
7
static void ISR_timer1(void) 
{
XXX;
XXXXX;
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE,0x00); //清除timer1中断标志位
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE,0x05); //启动定时器
}

在中断响应函数中,不要忘记在执行结束前,添加定时器清零以及启动定时器。便于定时器下一次响应,否则定时器就仅仅执行一次。

简单定时器中断示例:

用定时器控制的流水灯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <system.h>
#include <altera_avalon_pio_regs.h>
#include <altera_avalon_timer_regs.h>

static void Timer_ISR_Init(void);
static void Timer_Irq_Handler(void);
int count=0;
int main()
{
printf("Hello from Nios II!\n");
int LED_code=0x00;
Timer_ISR_Init();
while(1)
{
switch(count)
{
case 0: LED_code=0X01; break;
case 1: LED_code=0X02; break;
case 2: LED_code=0X04; break;
case 3: LED_code=0X08; break;
case 4: LED_code=0X10; break;
case 5: LED_code=0X20; break;
case 6: LED_code=0X40; break;
case 7: LED_code=0X80; break;
}
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, LED_code);
if(count == 7) count=0;
}
return 0;
}

static void Timer_ISR_Init(void)
{
printf("\n Timer Initial! \n");
// 清除定时器中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS( TIMER_BASE,0x00);
//设置定时周期
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_BASE,50000);
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_BASE,100);
//启动定时器
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE,0x05);
//注册中断
alt_irq_register(TIMER_IRQ,NULL,Timer_Irq_Handler);
}
static void Timer_Irq_Handler(void)
{
count++;
// 清除定时器中断标志寄存器
IOWR_ALTERA_AVALON_TIMER_STATUS( TIMER_BASE,0x00);
//启动定时器
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE,0x05);
}

友情链接:

1、大西瓜FPGA