实验用的板子是黑金的,程序主要按照黑金的视屏来做的。
定时器的添加就不说了,主要总结一下定时器的操作过程吧。
1、初始化,即对定时器进行清零。
清零的方式有两种,一种是用定时器清零,另外一种是使用库函数,主要是io.h这个库里面的。
这里主要讲一下使用库函数,主要原因是使用库函数使得程序的可读性更强。
IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE,0x00);//清除timer1中断标志位
其中TIMER1_BASE是定时器1的基地址,在system.h这个头文件中。
2、设置定期的周期,同样建议使用库函数。
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER1_BASE,timer_prd[j]); IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER1_BASE,timer_prd[j]>>16);
其中XXX_PERIODL和XXX_PERIODH分别为定时器的周期的低十六位和高十六位。这里需要提醒大家的一点是,主要不要超出16位,否则会丢失高位。
3、启动定时器。
//启动timer1 IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER1_BASE,0X07);
这里0x07主要是对某一些特定的标志位进行操作,主要起启动定时器。
4、注册定时器。这里的注册需要解释一下,这个可能和os有点联系,nios后台有个操作系统,当定时器中断产生以后,后台就会响应这个中断,也就是执行这个中断对应的中断函数。
//注册timer1 alt_irq_register(TIMER1_IRQ,NULL,ISR_timer1);
这里的ISR_timer1就是定时器1对应的中断函数,ISR_timer1是这个中断函数对应的函数名称。(函数名实质就是一个指针,只不过这个指针是函数指针)。
我们可以中断函数中进行一些短时的操作,不宜进行复杂超过,主要是考虑到时间过长会引起定时器溢出。
static void ISR_timer1(void *context,alt_u32 id) {
LED->DATA=1<<i; printf("hello timer1! %d\n",i); i++; if(i==4) i=0; IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER1_BASE,0x00); }
在中断响应函数中,不要忘记在执行结束前,添加定时器清零。以便于定时器下一次响应,否则定时器就仅仅执行一次。OMG,这是我们不想看到的,千万不要忽略这个小错误。
写到这里,提前放假回家了!