初始化,即对定时器进行清零
清零的方式有两种,一种是用定时器清零,另外一种是使用库函数,主要是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
|
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