## Difference between OUT and SBI

14 posts / 0 new
Author
Message

I'm just beginning to learn assembly and I'm curious what the difference between the 'out' and 'sbi' instructions are.

The data sheet specifies that out "stores data from register Rr in the Register File to I/O Space"

and sbi "Sets a specified bit in an I/O register"

I see the differences but I don't really understand them.

It looks like out will set the bits from a register and sbi sets the bits from the supplied constant value. Is that the only difference or am I way off here?

Thanks :D

'out' changes all bits, 'sbi' and 'cbi' - just one.

BINGO!!

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Ahhh! Ok... well that kinda makes sense

So, forgive the newb question here but how do I know what bit it's setting? If I understand correctly any 1 register is going to contain 8 bits,.. now I'm a little confused.

look at the instruction, there are 2 parameters, first is the I/O address...the 2nd is the bit number.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

glitch wrote:
look at the instruction, there are 2 parameters, first is the I/O address...the 2nd is the bit number.

Doh - I get it.. I was still thinking in terms of passing a byte. Thanks guys!

Oh for the love and honour of God - I went to some length to explain this to you yesterday:

Presumably that was a complete waste of my time?

clawson wrote:
Presumably that was a complete waste of my time?

Not completely. I learnt a thing or two :) Thanks!

clawson wrote:
Oh for the love and honour of God - I went to some length to explain this to you yesterday:

Presumably that was a complete waste of my time?

I'm still learning! For some reason after I read about "out" I got the two mixed up.. I really do appreciate your post though - it was a great help. Thanks again :D

Which brings me to this:

```#include

.global main

main:
ldi     r16, 0xFF
out     DDRD, r16

sbi     PORTD, 0
```

I'm just trying to turn an LED on... but I'm getting

`led.S:10: Error: number must be less than 32`

For the sbi instruction... where am I going wrong here?

you need to look at the register list for the AVR you are using. Only the I/O ports that are located in the first 32 locations (I/O address 0x00-0x1f) are accessible via SBI/CBI.

You'll have to use IN/OUT for anything between 0x1f and 0x3f (IN/OUT also works on 0x00-0x1f)

If the AVR you have has extended I/O, These ports will start at a memory address of 0x60 and above. These I/O ports are only accessible via STS/LDS (or other memory access functions) IN/OUT and the other direct I/O instructions will not work on these I/O Ports.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Ahhh ok... that makes sense.

Here's what I've got now:

```#include

.global main                        ; define main as a global

main:
ldi     r16, 0xFF
out     DDRD, r16

in      r17, PD0
out     PORTD, r17
```

Does everything look ok here? Unfortunately, I'm still not having any luck (this is a 2313).

No.
Use this, if you want to set PD0 bit, keeping/setting other PORTD bits to 0:

```ldi r17, 1<<PD0
out PORTD, r17
```

Or this, if you want to set PD0 and keep other bits in state they were before:

```in r17, PORTD
ori r17, 1<<PD0
out PORTD, r17
```

Lads, I'm afraid SFR access in avr-as is not quite as simple as you seem to be attempting above. This all comes down to the 0x20 offset thing I talked about in the thread linked above. The .h files for the various AVR chips are optimised for use by the C compiler which means that if you wander into the murky world of assembler you need to use some special macros to "fix up" the SFR addresses with the right offset values. In particular _SFR_IO_ADDR(). No doubt you already read the following page in the manual but, if you didn't, you should study it in depth:

http://www.nongnu.org/avr-libc/u...