*yikes*
2007-01-05 by Thomas Keller
I feel like such a dummy. I have my program doing everything I want and need it to do, with one exception (a major exception, to be sure). I cannot get the timer interrupt to work. if I step through the program manually, it does what I need of it, but when I try to get the timer to interrupt and step it through, it does nothing at qll (so far as I can tell). Which brings up a secondary question, as well: when using the F5 "Run" feature in the debugger, apparently the watch windows do not work, until you hit an Ctrl-F and halt the run. Once I get the interrupt thing working, will that change? Will the fact of the interrupt trigger an update to the watch windows? If not, how do I determine if the program is doing what is supposed to be doing while running under the F5 feature? tom here is my code, as it stands so far:
Show quoted textHide quoted text
> .include "tn25def.inc" > > ; Define here the variables > ; > .def temp =r16 > > ; Define here 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 > overflow interrupt > reti ; Addr > $06 Use 'rjmp myVector' > reti ; Addr > $07 to define a interrupt vector > reti ; Addr $08 > reti ; Addr $09 > reti ; Addr $0A > rjmp TIMER0 ; timer/counter 0 > compare match A interrupt > reti ; Addr > $0C Not all MCUs have the same > reti ; Addr > $0D number of interrupt vectors > reti ; Addr $0E > reti ; Addr $0F > reti ; Addr $10 > > > ; Program starts here after Reset > ; > START: > > ; this table povides the data for the intensity curve needed for > ; xxxxxxxxxxxxxxx. the data represent the value sin3 * 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 344, 346, 247, 249, 250, 252, 253, 254, 255, 255, 255 > ; > .cseg > > > BEGIN: > > ldi r30, RAMEND ; initialize stack > pointer > out SPL, r30 > ldi r31, 0x00 ; set up > upper WGM bytes > out WGM01, r31 ; and once again > ldi r31, 0x03 ; set upo to > set waveform configuration > out WGM00, r31 ; output to > appropriate control register > > ldi r30, 0x04; ; enable > timer/counter 0 compare match A interrupt > out TIMSK, r30 ; store to > timer/counter 0 Interrupt mask register > > ldi r30, 0x80 ; enable > gloabel interrupts in SREG > in r29, SREG ; grab current > SREG value > or r30, r29 ; or in > existing bits > out SREG, r30 ; store in SREG > register > > ; > ; set up timer delay for ~~.01 second > ; > ; counter clock will be prescaled by 1024 to make the .01 second > count easier > ; > > ldi r21, 0x38 ; load low > byte of delay count > ldi r22, 0xff ; load high > byte value for delay count > out TCNT1, r2 ; store in > timer/counter register > ldi r31, 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, r31 ` ; store in register > > ldi r31, 0x75 ; load value > for TCCR1A > out TCCR1, r31 ; and store to TCCR1A > ldi r31, 0x38 ; load > compre output macth value > out OCR1A, r31 ; store in output > compare register 1A > > ldi r23, 0xff ; use r3 > as high/low byte flag for timer > ; > control (see interrupt handler for more) > > ; > ; this code sets the default initial table adress at 0 > ; > > ldi r16, 0x00 ; first > addresss in EEPROM table data > ldi r17, 0x00 ; direction > control byte, 0 = up > > rjmp MAIN ; go to the main > loop in the code > \ > NEXT: > > ldi r31, 0x00 ; compare value > cp r17, r31 ; check > direction bit for value > breq UP ; it's set for > an up count > ldi r31, 0x00 ; compare > value > dec r16 ; count the > table pointer down one > cp r16, r31 ; at the bottom > yet? > breq CONT0 ; nope. continue > RJMP QUIT0 ; all done, depart > > UP: > ldi r31, 0x63 ; compare value > inc r16 ; increment > table pointer > cp r16, r31 ; 99 decimal, > end of table > breq FIXIT0 ; deal with > table overflow > rjmp QUIT0 ; all done, depart > > CONT0: > > ldi r17, 0x00 ; set to count > up again > rjmp QUIT0 > > FIXIT0: > > ldi r17, 0xff ; reset > direction flag for down count > QUIT0: > > ret ; return > from subrouttine call > ; > ; read a value from the EEPROM table > ; > > TABLEDATA: > > out EEARL, r16 ; move table value > address to EEPROM > ; address > register low byte > > rcall NEXT ; go grab next > tabel address sbi EECR,EERE > in r18, EEDR ; read data from > EEPROM data register > out OCR0A, r18 ; output to PWM > control register > > ret ; all > done, go home > TIMER0: > > ldi r31, 0xff > cp r23, r31 ; low byte or > high/ > breq HIGHFIX ; this is the low > bytem go fix it for the high byte > > LOOP1: > ldi r23, 0xff ; reset for > next low byte count > out TCNT1, r21 ; reload the > timer for the countdown, low byte > > rcall TABLEDATA ; go do the output > needed > > reti ; go > to sleep until next timer interrupt > > HIGHFIX: > > ldi r23, 0x00 ; set flag > to high byte indicator > out TCNT1, r22 ; set the timer > for the high byte countdown > rjmp LOOP1 ; now go finish > interrupt handler > > ; > ; this is the main control loop, an infinite loop > ; > > MAIN: > > rcall TABLEDATA ; go do the first > call to table data > LOOP2: > > ; rcall TABLEDATA > sleep > rjmp LOOP2 ; go back to > sleep until next interrupt > ; in > other words, loop forever > > .exit >