very new to embedded programming - can you look at my code for an AVR?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi - I'm attempting to program an AVR so that through a computer
(through the serial port) one can easily control how fast it turns on
and turns off a single pin. This actually has a use (it will be used by
a grad student doing some research in nano EDM [electro discharge
machining]). I haven't been able to test it, so I don't have the
slightest clue if it works or not.

Essentially the entire design of it is that when you first turn on the
AVR, it initializes a couple basic things (enables timers, sets portc as
an output, initializes the stack, etc.) and then it waits for a command
from the serial port, analyzes it, and uses it to set the parameters of
the timer and to enable/disable all interrupts (thus enabling/disabling
the timer ISRs). The computer attached can also request certain
parameters if needs be.

It's written in lovely AVR assembler by yours truly. The only thing I
was able to test was the timer part of the code, as I could simulate
that with AVR Studio. (though strangely enough I think I found a couple
bugs with AVR Studio 4, as sometimes it would behave differently than
other times - even though I hadn't changed anything...)

The code between the computer and the AVR is fairly simple. Each message
is one byte long. If it's a command, the first set of 4 bits is the
command, the second set of 4 bits is the parameter (or 0x0 if it doesn't
need a parameter). Before a second byte can be sent (say when sending
the high and then low byte of one of the timer compares) the receiver
(AVR/computer) must give the transmitter (computer/AVR) permission. This
was done as the UART on the AT90S8515 can only hold one byte at a time.
I may move this code to a different avr eventually - but the AT90S8515
is the only AVR I've ever worked with, so I decided to go with it, even
though it's discontinued.

Anyways - the serial communication part of the code is 100% untested so
I'm not even sure if any of it works. All I know is that it compiles ok
:)

Most of the code is commented. The stuff that isn't is mostly redundant
stuff that I thought was fairly self explanatory.

Sorry for writing so much - I gotta work on that! Here's the assembler
file, let me know if you have trouble downloading it:

https://netfiles.uiuc.edu/mnoone/www/AT90S8515-serial-controlled -
oscillations.asm


Thanks!


-Michael Noone

Re: very new to embedded programming - can you look at my code for an AVR?
Quoted text here. Click to load it

What bugs were these that you saw? They might provide a clue to something wrong
with your code. The only bug I know of (though I haven't played with AVR that
much) was a problem with using I/O Stimulus files to simulate I/O input. The
"Step Into" debugger command seems to ignore I/O stiumulus files.

One comment I have right now is to use the DEF directive to give names to your
registers. This way you can divorce the function from a particular register
number is all of your code. If you need to change the register number, you just
change it in one spot instead of hunting through your code to change all
occurences. You'll also avoid having old register numbers in comments.


Re: very new to embedded programming - can you look at my code for an AVR?
snipped-for-privacy@aol.com (Gary Kato) wrote in

Quoted text here. Click to load it

So when I noticed a bug I was using a much simpler program. The problem
was that the DDRB would change after I set it, with different bits
changing different times. For example, I'd run it one time and the LSB
would change, then I'd run it again and nothing at all would change.
About the DEF directive - yeah I've been meaning to do that. I just
havebn't gotten around to it just yet :) I believe this is the code that
was behaving oddly:

.device    AT90S8515
.include "8515def.inc"

;length of period = PERIODH00 + 00PERIODL
.EQU PERIODH = 0x00
.EQU PERIODL = 0x50

;length of timeon = TIMEONH00 + 00TIMEONL
.EQU TIMEONH = 0x00
.EQU TIMEONL = 0x14

;prescaler:
    ;clear timer on CompareA match, timer clock = system clock:
0b00001001
    ;clear timer on CompareA match, timer clock = system clock/8:
0b00001010
    ;clear timer on CompareA match, timer clock = system clock/64:
0b00001011
    ;clear timer on CompareA match, timer clock = system clock/256:
0b00001100
    ;clear timer on CompareA match, timer clock = system clock/1024:
0b00001101
.EQU PRESCALER = 0b00001001


.ORG 0x0000
    RJMP reset
.ORG 0x0004 ;timer 1 compare match to OCR1A
    RJMP turnon
.ORG 0x0005 ;timer 1 compare match to OCR1B
    RJMP turnoff

reset:
;Initialize stack
    LDI R16,low(RAMEND)
    OUT    SPL,R16
    LDI R16,high(RAMEND)
    OUT SPH, R16

;Sets TCCR1B to PRESCALER, as defined above code
    LDI R16, PRESCALER
    OUT TCCR1B, R16

;sets OCR1A to PERIODH00 + 00PERIODL
    LDI R16, PERIODH
    OUT OCR1AH,R16
    LDI R16, PERIODL
    OUT OCR1AL,R16

;sets OCR1B to TIMEONH00 + 00TIMEONL
    LDI R16, TIMEONH
    OUT OCR1BH,R16
    LDI R16, TIMEONL
    OUT OCR1BL,R16

;Sets portb to outputs and sets all portb pins high
    LDI R16, 0xFF
    OUT DDRB, R17
    LDI R17, 0xFF
    OUT PORTB, R17

;enables timer 1a and 1b compare match interrupts
    LDI R16, 0b01100000
    OUT TIMSK, R16
    SEI

loop:
    RJMP loop ;wait for timer interrupt

turnon:
    IN R18, SREG ;backup SREG to R18
    CBR R17, 0x01 ;Clears bit 0 of R17
    OUT PORTB, R17 ;write contents of R17 to PORTB
    OUT SREG, R18 ;Copy backup of SREG to SREG, in case ISR modified
it
    RETI ;return to loop

turnoff:
    IN R18, SREG ;backup SREG to R18
    SBR R17, 0x01 ;Sets bit 0 of R17
    OUT PORTB, R17 ;write contents of R17 to PORTB
    OUT SREG, R18 ;Copy backup of SREG to SREG, in case ISR modified
it
    RETI ;return to loop

Re: very new to embedded programming - can you look at my code for an AVR?
Quoted text here. Click to load it
   <snip>
Quoted text here. Click to load it

This should explain it. If I were you, I'd start using .DEF now. One of the
toughest things about writing in assembly language is remembering what
registers are used for which purposes. Mistakes like this are so easy to make
(as you've found out).




Re: very new to embedded programming - can you look at my code for an AVR?
snipped-for-privacy@aol.com (Gary Kato) wrote in

Quoted text here. Click to load it

Son of a... I can't believe I did that. Anyways that program was just a
trial of the code for the serial controlled code - so no worries. And as
far as I can tell, that problem doesn't exist in that code. So can you tell
if the code I first posted (https://netfiles.uiuc.edu/mnoone/www/AT90S8515 -
serial-controlled-oscillations.asm) has any problems? Thanks again,

-Michael

Site Timeline