16-bit Timer/Counter on Atmega644

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I have been working on this for about a week now, and at this point I am kind of stuck. This is my first AVR project and I am not a SW person (although I do find it to be rather fun), so if you have any advice please feel free to assume that I know nothing, aside from reading the datasheet.

I am working on a project that involves calculating the speed of a rotating wheel using a hall effect sensor, comparing that speed to a user-defined set point, and attempting to match the set point by sending a PWM signal to a motor that spins the wheel.

So far I got the serial communication worked out and the PWM signal. The main thing that have been tripping me out is the interrupt I am using to time the rising edges of the hall effect sensor output:

I have initialized a 16 bit timer with a prescale of 256 in normal mode with an interrupt on Input Capture Pin. I have also initialized an overflow interrupt, that increments an overflow counter. When the ICP interrupt happens I am reading the 16 bit Input capture register, and then adding to it the overflow counter multiplied by 0xFFFF. At this point one of the following two things go wrong:

1. If I attempt to printf through serial within the interrupt my micro gets stuck, and based on the LEDs it refuses to do anything, as well as printing through the serial (it prints one charachter, which I assume is exactly 8 bits).

2. If I printf from my main() the timer value I get does not make any sense: it is sometimes negative, and sometimes positive (which i thought to be impossible with an unsigned 32 bit integer)

At this point I tried the following:
a.) not adding overflow
b.) printing a HEX value (maybe %d in printf uses some bits for signs?)
c.) subtracting the previous timer value from the current one (in case the counter never resets)

Any ideas you might have at this point will be greatly appreciated...... HELP!!! :shock:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1. never try to printf() from inside an ISR.

2. copy the timer value to another variable. Then you ca do the printf() from the main code.

3. If you want to use an overflow counter, there is no need to multiply and definitely not by 0xFFFF. Just say:

uint32_t timer32 = ((uint32_t)overflow16 << 16) | timer16;

HTH David.