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

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:

formatting link
oscillations.asm

Thanks!

-Michael Noone

Reply to
Michael Noone
Loading thread data ...

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.

Reply to
Gary Kato

snipped-for-privacy@aol.com (Gary Kato) wrote in news: snipped-for-privacy@mb-m12.aol.com:

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

Reply to
Michael Noone

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).

Reply to
Gary Kato

snipped-for-privacy@aol.com (Gary Kato) wrote in news: snipped-for-privacy@mb-m14.aol.com:

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

formatting link
has any problems? Thanks again,

-Michael

Reply to
Michael Noone

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.