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 > > > >
Message
Re: [AVR-Chat] still no working interrupt )-:
2007-01-08 by dlc@frii.com
Attachments
- No local attachments were found for this message.