Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: [AVR-Chat] still no working interrupt )-:

2007-01-08 by dlc@frii.com

I don't have time to pore over your code looking for the smoking gun,
but there are two comments I will make that can affect what you are
doing and how the missing interrupt could be going awry.

1) You don't save status in your ISR.  You should save it and retrieve it
before exiting the ISR.  Without doing that you will munge the workings of
the non-ISR code that is running.  Save any register that you might be
fiddling with in the ISR as well if you need to.

2) Since you are having problems getting the ISR to work, putting "RETI"
instructions in the interrupt vector table is not wise.  I would rjmp all
unused interrupt vectors to a single routine, set an LED and save a value
telling which ISR got hit, if you sorted that thing out.  Then I'd RETI
from there.  This might help you to find a rogue interrupt or a mistake in
your interrupt coding.

DLC


> I don't get it.  My stand alone interrupt routine works, but I cannot
> seem to get interrupts to work in this program.  here is the code (with
> comments which reveal proprietary information redacted out):
>
> ;
> ;==============================================================================
> ;
> ;    NAME:        beacon.asm
> ;
> ;    PROJECT:    *** REDACTED ***
> ;
> ;    VERSION:    v0.1a
> ;
> ;    DATE:        01/03/2007
> ;
> ;    AUTHOR:        Thomas J Keller
> ;
> ;    COPYRIGHT:    Copyright 2007, All Rights Reserved
> ;
> ;    DESCRIPTION:    *** REDACTED***
> ;
> ;    HISTORY:
> ;    +===+=======+======================================================+
> ;     | who |   date       |   description
>                                                                          |
> ;
> +-----+----------+---------------------------------------------------------------------------------+
> ;     |  tjk   | 07/01/03 |  intialize program file
>                                                                        |
> ;
> +-----+----------+---------------------------------------------------------------------------------+
> ;    |  tjk   | 07/01/08  |  add symbolic names for registers and
> constants, for clarity                                  |
> ;
> +-----+----------+---------------------------------------------------------------------------------+
> ;    +==================================================================+
>
>
> .include "tn25def.inc"
>
> ;
> ; Define the variables
> ;
>
> ;
> ;    .defines
> ;
>
> .def    TEMP        =    r16
> .def    HICOUNT        =    r21            ; HIGHBYTE byte value for timer
> 0
> .def    LOCOUNT     =    r22            ; LOWBYTE byte value for timer
> .def    HILOFLAG    =    r23            ; HIGHBYTE/LOWBYTE byte flag
> .def    PWMSET        =    r18            ; value to be passed to PWM
> control register
> .def    TABLEADDR     =    r19            ; EEPROM table address register
> .def    DIRFLAG        =    r17            ; table traversal direction
> control flag
>
> ;
> ;    .equates
> ;
>
> .equ    TRUE        =    0xff        ; true value
> .equ    FALSE        =    0x00        ; false value
> .equ    DOWN        =    0xff        ; up count flag value
> .equ    UP            =    0x00        ; down count flag vlaue
> .equ    HIGHBYTE    =    0xff        ; HIGHBYTE byte flag value
> .equ    LOWBYTE        =    0x00        ; LOWBYTE byte flag value
>
>
> ; Define Reset and interrupt vectors, if any
> ;
> RESET:
>    rjmp BEGIN
>    reti                          ; Addr $01
>    reti                          ; Addr $02
>    reti                          ; Addr $03
>    reti                          ; Addr $04
>    rjmp    TIMER0                  ; timer/counter 0 overfLOWBYTE
> interrupt
>    reti                          ; Addr $06
>    reti                          ; Addr $07
>    reti                          ; Addr $08
>    reti                          ; Addr $09
>    reti                          ; Addr $0A
>    rjmp    TIMER0                     ; timer/counter 0 compare match A
> interrupt
>    reti                          ; Addr $0C
>    reti                          ; Addr $0D
>    reti                          ; Addr $0E
>    reti                         ; Addr $0F
>    reti                         ; Addr $10
>
>
>
>
> ;    this table provides the data for the intensity curve needed for
> ;    xxxxxxxxxxxxxxx.  the data represent the value sin^3 * 255 for
> ;    each angle from 0 through 90  at .9 degree increments
>
>     .eseg
>
> TABLE:
>     .db    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 5, 6, 6
>     .db    8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 36
>     .db    39, 44, 48, 52, 55, 59, 62, 66, 70, 74, 78, 82, 86, 90, 94, 99
>     .db    103, 108, 112, 117, 121, 126, 130, 135, 140, 144, 149, 153
>     .db    158, 163, 167, 172, 176, 180, 185, 189, 193, 197, 201, 205
>     .db    209, 212, 216, 219, 223, 226, 229, 232, 234, 237, 239, 242
>     .db    244, 246, 247, 249, 250, 252, 253, 254, 255, 255, 255
>
> ;
>      .cseg
>
> ;
> ; Program starts here after Reset
> ;
>
> BEGIN:
>
>     ldi    TEMP,    RAMEND                    ; initialize stack pointer
>     out    SPL,    TEMP
>
> ;
> ;    set timer controsl and interrupts
> ;
>
>     ldi    TEMP,    0x02                    ; set WGM1:0 to 0x02
>     out    TCCR0A,    TEMP                    ; and store in TCCR0A
>     ldi    TEMP,    0x04                    ; set wgm2 and CS2:0
>     out TCCR0B,    TEMP                    ; store in TCCR0B
>
>     ldi    TEMP,    0x40;                    ; enable timer/counter 0
> compare match A interrupt
>     out    TIMSK,    TEMP                    ; store to timer/counter 0
> Interrupt mask register
>
>     sei                                    ; enable global interrupts
>
> ;
> ;    set up timer delay for ~~.01 second
> ;
> ;    counter clock will be prescaled by 256 to make the .01 second count
> easier
> ;
>
>     ldi    LOCOUNT,    0x38                ;  load LOWBYTE byte of delay
> count
>     ldi    HICOUNT,    0xff                ; load HIGHBYTE byte value
> for delay count
>     out    OCR1A,    HICOUNT                    ; store in timer/counter
> register
>
>     ldi    TEMP,    0xe5                    ; load the control value for
> TCCR1
>                                         ; CTC1 set, PWMa set, COM1A set to
>                                         ; toggle on match, timer clock set
>                                         ; for system clock divided by 256
> `    out    TCCR1,    TEMP                    ; store in TCCR1
>
>
>     ldi    HILOFLAG,    HIGHBYTE                ; HIGHBYTE/LOWBYTE byte
> flag for timer
>                                         ; control (see interrupt handler
> for more)
>
> ;
> ;    this code sets the default initial table adress at 0
> ;
>
>     ldi    TABLEADDR,    0x00                ; first addresss in EEPROM
> table data
>     ldi DIRFLAG,    UP                    ; direction control byte, 0 = up
>
>     rjmp    MAIN                        ; go to the main loop in the code
>
> NEXT:
>
>     ldi    TEMP,    UP                        ; compare value
>     cp    TEMP,    DIRFLAG                    ; check direction bit for
> value
>     breq    UPCNT                        ; it's set for an up count
>
>     ldi    TEMP,    UP                        ; compare value
>     dec    TABLEADDR                        ; count the table pointer
> down one
>     cp    TABLEADDR,    TEMP                ; at the bottom yet?
>     breq    CONT0                        ; nope. continue
>     RJMP    QUIT0                        ; all done, depart
>
> UPCNT:
>     ldi    TEMP,    0x63                    ; compare value
>     inc    TABLEADDR                        ; increment table pointer
>     cp    TABLEADDR,     TEMP                ; 99 decimal, end of table
>     breq    FIXIT0                        ; deal with table overfLOWBYTE
>     rjmp    QUIT0                        ; all done, depart
>
> CONT0:
>
>     ldi    DIRFLAG,    UP                    ; set to count up again
>     rjmp    QUIT0
>
> FIXIT0:
>
>     ldi    DIRFLAG,    DOWN                ; reset direction flag for
> down count
>
> QUIT0:
>
>     ret                                    ; return from subrouttine
> call
>
> ;
> ;    read a value from the EEPROM table
> ;
>
> TABLEDATA:
>
>     out    EEARL,     TABLEADDR                        ; move table
> value address to EEPROM
>                                         ; address register LOWBYTE byte
>
>     rcall    NEXT                        ; go grab next tabel address
>
>     sbi EECR,EERE
>     in    PWMSET,        EEDR                ; read data from EEPROM
> data register
>     out    OCR1A,    PWMSET                    ; output to PWM control
> register
>
>     ret                                    ; all done, go home
>
> ;
> ;    timer interrupt handler
> ;
>
> TIMER0:
>
>     ldi    TEMP,    HIGHBYTE
>     cp    HILOFLAG,    TEMP                ; LOWBYTE byte or HIGHBYTE/
>     breq    HIGHBYTEFIX                    ; this is the LOWBYTE bytem
> go fix it for the HIGHBYTE byte
>
> LOOP1:
>     ldi    HILOFLAG,    LOWBYTE                ; reset for next LOWBYTE
> byte count
>     out    OCR0A,     LOCOUNT                    ; reload the timer for
> the countdown, LOWBYTE byte
>
>     rcall    TABLEDATA                    ; go do the output needed
>
>     reti                                ; go to sleep until next timer
> interrupt
>
> HIGHBYTEFIX:
>
>     ldi    HILOFLAG,    HIGHBYTE                ; set flag to HIGHBYTE
> byte indicator
>     out    TCNT1,    HICOUNT                    ; set the timer for the
> HIGHBYTE byte countdown
>     rjmp    LOOP1                        ; now go finish interrupt handler
>
> ;
> ;    this is the main control loop, an infinite loop
> ;
>
> MAIN:
>
> ;    rcall    TABLEDATA
>     sleep
>     rjmp    MAIN                        ; go back to sleep until next
> interrupt
>                                         ; in other words, loop forever
>
>     .exit
>
>
>
>
>
> Yahoo! Groups Links
>
>
>
>

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.