Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

conflict when using atmega328 registers

Status
Not open for further replies.

mikewax

Member
Hello i'm writing in C with an olimexino and using the following code to load 2 registers:

"asm (
"ldi r20, 0 \n" //load register r20 with 0
"ldi r21, 16 \n" //load register r21 with 16
: : : "r20","r21" //compiler directive to reserve the two registers );"

then i use this:
"asm ( "out 0x05, r21 \n" ); //write '0' to portB
asm ( "out 0x05, r20 \n" ); //write '10000' to portB"

to write from the two registers to port B. but using the two registers r20 and r21 creates a problem. a conflict occurs if i do a division operation. for example, if any part of my program has a statement like "x = x/6" or "y=x%9" then the numbers i stored in those registers seem to change. if i do a simple division like "x/4" or "x%8" there's no problem. but any operation that's more complex than a simple shift division screws me up.

anyone know anything about this?
thanx
 
I will start by saying I know very little about "C" programming. (I find it very difficult compared with assembler.) It sounds to me like the code that "C" produces to do division must use registers r20 & r21 so it is overwriting their contents. I would hope the documentation on the compiler would tell you which registers you can use without the risk of them being overwritten.

Les.
 
Last edited:
I will start by saying I know very little about "C" programming. (I find it very difficult compared with assembler.) It sounds to me like the code that "C" produces to do division must use registers r20 & r21 so it is overwriting their contents. I would hope the documentation on the compiler would tell you which registers you can use without the risk of them being overwritten.

Les.
yeah it should be documented somewhere but according to https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Clobbers gcc is supposed to reserve those registers but clearly it's not working.
 
If you are using avr-gcc compiler, then this info can be useful: https://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage
(Arduino-IDE uses avr-gcc and avr-libc)
that was very helpful. i changed the code and used r28 & r29 and my test routine ran without losing that data. i'm gonna try that in my program and see what happens.
If you are setting only one pin on portb, you can use:
"SBI 0x05, 4 \n" Set bit in I/O register
yeah SBI works but the OUT instruction is fast. it executes in a single clock cycle. thanx, now my code might actually work. :)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top