Atmega timers, ... nirvana of headheck ?

Hello,

My problem is very very very simple:

I run on a Atmega8 the compare match interruption on timer1.

Each time I run it I want to rerun it x timer impulsions later.

Thus, I want to do a kind of: {OCR1A += x;}

Of course it doesn’t work… :frowning:

The only thing that work is {TCNT1=0;OCR1A=x;}

BUT I do not want to reset timer1.

Maybe OCR1A cannot be read ?

Thus I create a unsigned short u16_OCR1A and I use it as:

{u16_OCR1A += x; OCR1A = u16_OCR1A;}

Doesn’t work. :frowning:

Maybe I HAVE to perform a timer1 reset.

{TCNT1=0; TCNT1=u16_OCR1A; u16_OCR1A+=x; OCR1A = u16_OCR1A;}

Doesn’t work. :frowning:

Of course I tried to disable and enable interruptions before and after running these lines. Guess the result: Doesn’t work. :frowning:

Whatever I try, I get burned by the Atmel. I should say ****** Atmel :frowning: .

What can I do ?

Here is my timer configuration (the ONLY one that behaves as expected):

On TCCR1B, only bits for prescaler

TCCR1A = 0;

ICR1 = 0xFFFF;

Thank you VERY much.

Guillaume

If it’s any consolation - I’ve worked with microprocessors for decades. The AVR is one of the best. If you want frustration due to a goofy architecture and paged memory banks, go fight with a PIC processor.

I’ll be glad to help you - if you could help me understand your goals…

Here’s a tid-bit from the mega8 data sheet. See if it says that you must write both the high and low bytes in a particular order…

The TCNT1, OCR1A/B, and ICR1 are 16-bit registers that can be accessed by the AVR

CPU via the 8-bit data bus. The 16-bit register must be byte accessed using two read or

write operations. The 16-bit timer has a single 8-bit register for temporary storing of the

High byte of the 16-bit access. The same temporary register is shared between all 16-bit

registers within the 16-bit timer. Accessing the Low byte triggers the 16-bit read or write

operation. When the Low byte of a 16-bit register is written by the CPU, the High byte

stored in the temporary register, and the Low byte written are both copied into the 16-bit

register in the same clock cycle. When the Low byte of a 16-bit register is read by the

CPU, the High byte of the 16-bit register is copied into the temporary register in the

same clock cycle as the Low byte is read.

Not all 16-bit accesses uses the temporary register for the High byte. Reading the

OCR1A/B 16-bit registers does not involve using the temporary register.

To do a 16-bit write, the High byte must be written before the Low byte. For a 16-bit

read, the Low byte must be read before the High byte.

The following code examples show how to access the 16-bit Timer Registers assuming

that no interrupts updates the temporary register. The same principle can be used

directly for accessing the OCR1A/B and ICR1 Registers. Note that when using “Câ€

Thank you very much for answering so quickly !

You are right, the problem might come from the way AVR compiler manages 16 bits registers in C code. Is there a way to view the assembly code generation by the compiler ?

I did assembly for ti89 long time ago on a 32 bits processor, 32 bits architectures are so confortable :wink: !

Who said I wanted to turn to PIC ? :lol: (ok ok, I did though about it :roll: )

Actually my goal is to generate PPM signals, made of short pulses. The information is in the time between each pulse.

||||___||_ etc

OutputUp(300 µs);

OutputDown(t1 µs);

OutputUp(300 µs);

OutputDown(t2 µs);

OutputUp(300 µs);

OutputDown(t3 µs);

etc…

But I need to keep CPU for other calculations.

Thus, I am using the comparision math interruption A on timer 1. Each time I run the interruption, I set the output to 0 or 1 and then I postpone the OCR1A to several µs later.

This should theorically work even if I do not reset timer1.

Thank you again :slight_smile:

Hey!

Go to avrfreaks.net this site is really good and specific for AVRs.

http://www.avrfreaks.net

to look at the assembly look at the .lst files

They should be easy to find if you are compiling with avr-gcc I think.