0

I am new to microcontroller. The following code measures the period of a square wave. I have marked some lines which I haven't understood. The code is as follows:

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_CAPT_vect)
{
    int counter_value = ICR1; //16 bit value
    PORTB = (counter_value >> 7); // What has been done here?
    TCNT1 = 0; // why this line?

}

int main(void)
{
DDRB = 0xFF;
TCCR1A = 0x00;
TCCR1B = 0b11000010;
TIMSK = 0b00100000;
sei();
while(1);
cli();
}

What has actually been done in those lines?

user4650623
  • 17
  • 2
  • 11
  • 1
    The answers you seek can easily be found in documentation and on other sites on the net. If you don't know what those lines mean then it is clear you did not write the code and in such case you cannot expect the guys on Stackoverflow to help if you have not put in the effort to research properly. SO is not a classroom. It is a place where people voluntarily help others who got stuck in/with their own efforts. Please read what SO is about. There are info pages about it. – Blurry Sterk Jan 29 '16 at 10:55
  • I agree with Blurry Sterk. I suggest you read through the documentation of the interrupts. Then start with simple examples generating your own signals with timer interrupt as [described] here(http://www.protostack.com/blog/2010/09/timer-interrupts-on-an-atmega168/). Also this code uses timer interrupt to measure the period of the signal. Timer interrupt is useful for creating one. For measuring GPIO interrupt is more suitable. You enter interrupt routine when voltage on a pin goes high, start the timer and exit the interrupt. Next time read the timer value and restart the timer. – ursusd8 Jan 29 '16 at 13:23
  • 1
    My preferred method for period measurement is to read a free run timer counter and subtract the previous value. That removes the need to make any adjustments. – Weather Vane Jan 29 '16 at 19:20
  • @BlurrySterk, I'd be cautious to call learning things from e.g. the peripheral sections of MCU datasheets "easy". ;) (I know you said "documentation" etc...) – Sz. Jan 30 '16 at 00:09

1 Answers1

0
ISR(TIMER1_CAPT_vect)
{
    int counter_value = ICR1; //16 bit value
    PORTB = (counter_value >> 7); // What has been done here?

PORTB is a set of 8 output lines. Presumably, they are connected by a bus to some device you haven't mentioned. Maybe even a set of LEDS to display a binary number.

The result from the counter is 16 bits. To get the most significant bits, shift the result to the right to discard the less significant bits. (This operation loses precision, but you only have 8 bits of output, not 16.) As to why the shift is only 7 instead of 8, or why the unsigned value of the counter is saved as a signed int first, I don't know. I suspect it is a mistake. I would have done PORTB = (ICR1 >> 8); instead.

    TCNT1 = 0; // why this line?

Since we have recorded the time of the capture and sent it out PORTB, we now want to reset the timer for the next capture.

}
UncleO
  • 8,299
  • 21
  • 29