Timer interrupts ATMega32

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

Let's say I want to toggle LEDs 0-3 on and off every second. I also want to toggle LEDs 4-7 on and off every second. But I want to switch between LEDs 0-3 and LEDs 4-7 every 5 seconds. While one half of the LEDs is toggling on and off every second the other half is off. It just keeps switching every 5 seconds.

I first thought I might need to use two timers. One that toggles the LEDs on and off every second and another that switches which LEDs are being toggled every 5 seconds. But timer1 is the only one that can count to 1 second and 5 seconds. Now I'm confused as to what mode to use and how to set the timer to do something every second and to do something else every 5 seconds. I'm trying to use CTC mode with OCR1A as TOP, which would hold the 5 second count value. I'm trying to use OCR1B as a trigger for the 1 second count.

Below is my stab at it. LEDs 0-3 stay on for five seconds. Then LEDs 4-7 turn on and stay on for five seconds. So, the LEDs don't toggle every second. They just turn on and stay on for 5 seconds and then switch. Even the transition period is incorrect. For some reason after five seconds all the LEDs stay on for about a second and then switch. I want the 4 LEDs to switch immediately after 5 seconds.

.def tmp=r16
.def tmp1=r17

.cseg
rjmp reset

.org 0x00c ;OCR1A compare match vector
rjmp toggle_0to3

.org 0x00e ;OCR1B compare match vector
rjmp toggle_4to7

reset:

ldi tmp, 0b10000000 ;Globally enable interrupts
out sreg, tmp 

ldi tmp, low(ramend) ;initialize stack
out spl, tmp
ldi tmp, high(ramend)
out sph, tmp

ldi tmp, 0xff
out ddra, tmp ;ddra as output
out porta, tmp ;turn off all leds on porta

ldi tmp, 0b00001101; CTC mode, prescaler 1024
out tccr1b, tmp

ldi tmp, 0b00011000;enable output compare match interrupts for OCR1A and OCR1B
out timsk, tmp


ldi tmp, high(39062) ;Using a prescaler of 1024 and an 8MHz oscillator 39062 yields 5 seconds
out ocr1ah, tmp
ldi tmp, low(39062)
out ocr1al, tmp

ldi tmp, high(7812) ;Using a prescaler of 1024 and an 8MHz oscillator 7812 yields 1 second
out ocr1bh, tmp
ldi tmp, low(7812)
out ocr1bl, tmp

main:
rjmp main

toggle_0to3:
in r16, porta
ldi r17, 0xf0 
eor r16, r17
out porta, r16
reti

toggle_4to7:
in r16, porta
ldi r17, 0x0f 
eor r16, r17
out porta, r16
reti

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

You can't

Quote:
set the timer to do something every second and to do something else every 5 seconds

You don't need several timers.

The usually used technique is to set the timer up to generate a "time-base tick", perhaps every 1 ms. In the main program you use that tick to count in one or several variables and based on those you do your actions.

I was aabout to post some sketchy C code when I realized you're programming in assembler. Here's the sketchy-sketchy version:

ISR:
   milliseconds = milliseconds + 1

   IF milliseconds >= 1000
      milliseconds = 0
      seconds = seconds + 1
   ; Set up timer here

mainloop:

   IF seconds >= 1
      seconds = 0

      blink_seconds = blink_seconds + 1

      IF blink_seconds < 5
         ; Handle blinking low nibble blinking here
         ; On every other time, off every other time
      ELSE
         ; Handle blinking high nibble blinking here
         ; On every other time, off every other time
      
      IF blink_seconds >= 9
         blink_seconds = 0

   GOTO main_loop

Something like that. This way you can have many things depend on just one timer. Or if you like "multiple software timers all based on one hardware timer".

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Read my tutorial on multitasking ( in the tutorial section). Whilst the code is in C, it was originally adapted from assembler. The technique is the same regardless of what language is used.

As your programs get more complex, you'll need to have some rules with the allocation of registers. If you don't, your code will become a horrible mess. You'll also need to know how to access ram. Looking at the code generated by a C compiler can give some hints.