Yahoo Groups archive

AVR-Chat

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

Thread

*yikes*

*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
>

Re: [AVR-Chat] *yikes*

2007-01-05 by John Samperi

At 07:32 AM 6/01/2007, you wrote:
>I cannot get the timer interrupt to work.

You have NOT enabled the general interrupts as far as I can
see with a SEI instruction. This sets the general interrupt
bit. You will also need to set to the timer interrupt, don't have
time right now to go through your code :(

You will need to put a breakpoint at the appropriate place in
the interrupt service routine so that the program stops and then
you will be able to see what's happening.


Regards

John Samperi

********************************************************
Ampertronics Pty. Ltd.
11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
Tel. (02) 9674-6495       Fax (02) 9674-8745
Email: john@ampertronics.com.au
Website  http://www.ampertronics.com.au
*Electronic Design * Custom Products * Contract Assembly
********************************************************

Re: [AVR-Chat] *yikes*

2007-01-05 by Jim Wagner

It just does not update while running. I use breakpoints
when you need to trap on something.

Jim


On Fri, 05 Jan 2007 14:32:03 -0600
 Thomas Keller <tjkeller1@alltel.net> wrote:
> 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:
> 
> > .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
> >     
> 

---------------------------------------------------------------
The Think Different Store
http://www.thinkdifferentstore.com/
For All Your Mac Gear
---------------------------------------------------------------

Re: [AVR-Chat] *yikes*

2007-01-06 by Thomas Keller

John.

     I didn't use an sei instruction,no. I set the appropriate bit in a 
register, read in the current SREG vale, or'ed it together,t hen used an 
out instruction to store the result in the SREG.  While unconventional, 
it SHOULD have the same net result.

John Samperi wrote:
Show quoted textHide quoted text
>
> At 07:32 AM 6/01/2007, you wrote:
> >I cannot get the timer interrupt to work.
>
> You have NOT enabled the general interrupts as far as I can
> see with a SEI instruction. This sets the general interrupt
> bit. You will also need to set to the timer interrupt, don't have
> time right now to go through your code :(
>

Re: [AVR-Chat] *yikes*

2007-01-06 by Jim Wagner

Tom

The only bit that has anything to do with interrupts in the
SREG is Bit7:GlobalInterruptEnable.  Are you doing all that
to try to set and clear Bit7? 

It would seem like it OUGHT to execute an ISR. Do you have
the  corresponding bits set in the timer? For a Mega16, its
the TIMSK (Timer Mask Register) and, after the timer event
happens, a bit is set in the TIFR (Timer Interrupt Flag
Register). This latter bit will be cleared when the ISR
executes.

Jim


On Fri, 05 Jan 2007 19:17:14 -0600
 Thomas Keller <tjkeller1@alltel.net> wrote:
> John.
> 
>      I didn't use an sei instruction,no. I set the
> appropriate bit in a 
> register, read in the current SREG vale, or'ed it
> together,t hen used an 
> out instruction to store the result in the SREG.  While
> unconventional, 
> it SHOULD have the same net result.
> 
> John Samperi wrote:
> >
> > At 07:32 AM 6/01/2007, you wrote:
> > >I cannot get the timer interrupt to work.
> >
> > You have NOT enabled the general interrupts as far as I
> can
> > see with a SEI instruction. This sets the general
> interrupt
> > bit. You will also need to set to the timer interrupt,
> don't have
> > time right now to go through your code :(
> >
> 

---------------------------------------------------------------
The Think Different Store
http://www.thinkdifferentstore.com/
For All Your Mac Gear
---------------------------------------------------------------

Re: [AVR-Chat] *yikes*

2007-01-06 by Thomas Keller

Jim;

Yeah, I know it is a bit much, I had forgotten about the sei 
instruction, which is something that hasn't existed on processors i have 
worked with in the past.

Yes, I have the interrupts enabled (at least, if I understood the data 
sheet on how to do that, I do), and yes (again, contingent upon my 
correct understanding of the data sheet), I have the timer control bits 
set for the performance I wish.  This is why I am so confuzzled.

tom

Jim Wagner wrote:
Show quoted textHide quoted text
>
> Tom
>
> The only bit that has anything to do with interrupts in the
> SREG is Bit7:GlobalInterruptEnable. Are you doing all that
> to try to set and clear Bit7?
>
> It would seem like it OUGHT to execute an ISR. Do you have
> the corresponding bits set in the timer? For a Mega16, its
> the TIMSK (Timer Mask Register) and, after the timer event
> happens, a bit is set in the TIFR (Timer Interrupt Flag
> Register). This latter bit will be cleared when the ISR
> executes.
>
> J
>
>

Re: [AVR-Chat] *yikes*

2007-01-06 by Jim Wagner

Tom -

A technique I have used to debug timers is to temporarily
set up the timer so that the interrupt happens in a
relatively few clock cycles. This can be done by using the
minimum clock prescale, a small compare value, etc. Then, I
manually steep through the program and when it gets close
to the point where I expect the action, I view the
registers (to the left of the code window in Studio). Then
I watch exactly what happens. Usually, I find that
something fairly simple does not happen the way I expected.
Then, I read the docs to see what I overlooked.

Jim

On Sat, 06 Jan 2007 10:32:33 -0600
 Thomas Keller <tjkeller1@alltel.net> wrote:
> Jim;
> 
> Yeah, I know it is a bit much, I had forgotten about the
> sei 
> instruction, which is something that hasn't existed on
> processors i have 
> worked with in the past.
> 
> Yes, I have the interrupts enabled (at least, if I
> understood the data 
> sheet on how to do that, I do), and yes (again,
> contingent upon my 
> correct understanding of the data sheet), I have the
> timer control bits 
> set for the performance I wish.  This is why I am so
> confuzzled.
> 
> tom
> 
> Jim Wagner wrote:
> >
> > Tom
> >
> > The only bit that has anything to do with interrupts in
> the
> > SREG is Bit7:GlobalInterruptEnable. Are you doing all
> that
> > to try to set and clear Bit7?
> >
> > It would seem like it OUGHT to execute an ISR. Do you
> have
> > the corresponding bits set in the timer? For a Mega16,
> its
> > the TIMSK (Timer Mask Register) and, after the timer
> event
> > happens, a bit is set in the TIFR (Timer Interrupt Flag
> > Register). This latter bit will be cleared when the ISR
> > executes.
> >
> > J
> >
> >
> 

---------------------------------------------------------------
The Think Different Store
http://www.thinkdifferentstore.com/
For All Your Mac Gear
---------------------------------------------------------------

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.