-
Notifications
You must be signed in to change notification settings - Fork 4
Software example frequency counter
JEFF LIEU edited this page Jul 29, 2017
·
1 revision
We use GCC to compile programs for NIOS2 from C/C codes. A standard C/C program has an entry point which is the main() function. To make it similar to other microcontroller platform, we are using: - setup() function - loop() function These 2 programs are called in the main as following:
int main()
{
setup(); // called once
while(1) {
loop(); // repeatedly called
}
}
Frequency counter program setup:
void setup()
{
/* Put your setup code here */
/////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize variables
freqCntr = 0;
timerUp = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////
// Bind Serial Object to UART_0 component by assigning the base address
Serial.bind(UART_0_BASE);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Setup serial object with baudrate 115200
Serial.begin(115200);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Setup mode of Pins, we have INPUT, OUTPUT and OUTPWM modes
pinMode(0,OUTPUT);
pinMode(PWM_PIN,OUTPWM);
setPWMPeriod(1000);
analogWrite(PWM_PIN, 200);
//Note that we always have internal loopback at the pin
//The pin input path is always available even if we set the pin as OUTPUT or OUTPWM
//When the pin is set to INPUT mode, it will then turn off the driving buffer
pinInterrupt(PWM_PIN,RISING_EDGE);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Setup Timer interrupt interval = 1000 ms (write 1000-1)
recon_timer_irq_interval(999);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Enable timer, count down mode and continuous, i.e timer restarts after reaching the interval
recon_timer_irq_mode(RECON_TIMER_MODE_COUNT_DOWN|RECON_TIMER_MODE_CONTINUOUS);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Register Interrupts Service Routines (ISR)
alt_irq_register(RECON_IO_0_IRQ, &freqCntr, (alt_isr_func) io_isr);
alt_irq_register(RECON_TIMER_0_IRQ, &freqCntr, (alt_isr_func) timer_isr);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Print out a message
Serial.print("Setup done\r\n");
}
In the loop function:
void loop()
{
/* Put your code that will be repeatedly call here */
/* timerUp is a variable set by interrupt service routines and cleared after we've get the frequency */
if (timerUp==1)
{
Serial.print("Frequency is ");
Serial.println(frequency);
timerUp = 0;
digitalWrite(0, TOGGLE); // Just toggle the pin
}
}
We need 2 interrupt service routines: one increments frequency counter every time the signal rising, the other tells us the interval of measurement (1 second)
/*
* ISR that handles IO IRQ
*/
void io_isr(void* freqCntr)
{
///////////////////////////////////////////////
//Read back which pin is interrupted
u32 pin = recon_io_rd32(IRQ_STATUS);
///////////////////////////////////////////////
//Clear Interrupt
recon_io_wr32(IRQ_STATUS,pin);
///////////////////////////////////////////////
// On each interrupt, we increment the counter
(*((u32*)freqCntr))++;
}
/**
* ISR that handles Timer Interrupt
*/
void timer_isr(void *context)
{
//////////////////////////////////////////
// Clear Interrupt
RECON_TIMER_STAT = RECON_TIMER_IRQ_BIT;
timerUp = 1;
//////////////////////////////////////////
// On each interrupt, we latch the current value of frequency counter
// and reset the count
frequency = freqCntr;
freqCntr = 0;
}