Altera_Forum
Honored Contributor
10 years agoFixed timer interrupt: Main code flips output pin twice?
Hi all,
I have a periodic fixed timer (100ms) interrupt that seems to work fine but the main code is flipping the output pin twice. I basically want to show a pattern of LED (in my BeMicro MAX10) like this every second, low means LED on, there are 8 LEDs: 11100111 one second delay and next 11011011 one second delay and next 10111101 one second delay and next 01111110 one second delay and go to first I'm using the modulus operator (%) to change the pattern but it triggers (mostly) twice. Like: 11100111 one second delay and next 11011011 no delay 10111101 no delay 01111110 one second delay and go to first The picture attached shows when the isr executes by toggling an output pin (yellow trace). The blue trace is when the code inside the if(ticks % 10==0 && flag==1) executes. I'm pretty new at FPGAs and Nios. BTW I'm using "Reduced device drivers" and "Small C library" for the BSP. What Am I missing? --- Quote Start --- //=========== Global variables ==================================== volatile unsigned int ticks=0; volatile unsigned int flag=0; volatile unsigned char port0Val=0; //=========== main() Function ====================================== int main() { char led_patern[4]={0b11100111,0b11011011,0b10111101,0b01111110}; int i=1; alt_ic_isr_register(TIMER_0_IRQ_INTERRUPT_CONTROLLER_ID, TIMER_0_IRQ, timer_isr, 0, 0); //timer registers are 16-bits wide IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE, 1); //interrupt enable // PORT0 is 5 bits wide // PORT0 bit 0 = PIN_B1, BeMicro J5-2 // PORT0 bit 1 = PIN_A2, BeMicro J5-4 // PORT0 bit 2 = PIN_A3, BeMicro J5-5 // PORT0 bit 3 = PIN_A4, BeMicro J5-6 // PORT0 bit 4 = PIN_A5, BeMicro J5-10 IOWR(PORT0_BASE,5,0b11111); //5=outclear - ALL LOW //IOWR(PORT0_BASE,4,0b11111); //4=outset - ALL HIGH while(1) { if(ticks % 10==0 && flag==1) { port0Val = IORD(PORT0_BASE,0); //toggle port0 pin 2 -----> BLUE TRACE <-------- if((port0Val & 0b00100)==0b00100) IOWR(PORT0_BASE,5,0b00100); //5=outclear else IOWR(PORT0_BASE,4,0b00100); //4=outset IOWR(LEDS_BASE,0,*(led_patern+i)); //a low value turns LED on i++; if(i>3) i=0; flag=0; } } return 0; } //============== Interrupt Service Function =========================== void timer_isr() { port0Val = IORD(PORT0_BASE,0); //toggle port0 pin 0 -----> YELLOW TRACE <-------- if((port0Val & 0b00001)==1) IOWR(PORT0_BASE,5,0b00001); //5=outclear register, 0x01=0b00001 else IOWR(PORT0_BASE,4,0b00001); //4=outset register, 0x01=0b00001 ticks++; flag=1; IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_0_BASE, 0); // clear TimeOut flag } --- Quote End ---