still no working interrupt )-:
2007-01-08 by Thomas Keller
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