Bit definition in AVR Assembly

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all. I'm newbie on AVR. I have lots of experience about 8051 assembly. 

 

My issue about bit definition.

 

For example, to define LCD pins in 8051 assembly, we use BIT directive like these:

 

RS            BIT     P0.5
EN            BIT     P0.6

 

What is equivalent in AVR Assembly this bit definition directive? For example how can i define portc 6 pin as EN pin of LCD ? 

My controller is ATMEGA32

 

Thanks in advance..

 

This topic has a solution.
Last Edited: Sun. Feb 14, 2021 - 03:16 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can simply say something like

  

.equ PA_motor_fwd = PA3

Some newer tools use different naming instead (you will get an error to  help you decide!)

.equ PA_motor_fwd = PORTA3  

 

I like to prefix PA, PB, etc in front, so I don't mix up the name with the wrong port set  (wrong:  cbi PORTC,  PA_motor_fwd)

If a mixup happens, things can get very strange, very quick (since that won't usually generate a build error).

 

then

sbi PORTA, PA_motor_fwd  ;set pin level hi

cbi PORTA, PA_motor_fwd  ;set pin level lo

 

You must first set the port pin directions (or use default of all input), say, config outputs of several pins

ldi temp, (1<<PA_motor_fwd)|| (others)||(others)   ;defines outputs

out DDRA, temp

 

likewise you can use out to config mutiple pin states (hi/lo) at the same time

ldi temp, (1 << PC_mydog)  || (1 << PC_myfrog) || (0 << PC_freddy )  

out PORTC, temp   ;dog & frog hi, freddy (optional) is lo

 

if wanting to change directions one pin at a time (the slow way for config all)

sbi DDRA, PA_motor_fwd ;config that pin as an output

cbi DDRA, PA_motor_fwd ;config that pin as an input

 

to read a port as an input, use PIN

 

in mytemp, PINA  ;read all the pins of porta into mytemp

 

PINx always reads the physical pin state, regardless of whether it is defined as an input or output

PORTx can also be read (in mytemp, PORTA) to determine the desired output state (can mismatch PINx if pin is shorted hi or lo)

 

or to check/test one input pin, you can use:

sbic PINA, PA_motor_fwd

rjmp alarm   ;sound alarm if pin is set

blah blah  ;skip above & continue with blah blah otherwise

 

sbis is the opposite conditional

 

Go wander around here:

http://www.avrbeginners.net/

 

You joined 11 years ago..that is a rare newbie.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Feb 13, 2021 - 07:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't forget that in AVR assembler some of the bit-wise instructions refer to a single bit's position (7 though 0) while other bit instructions have arguments that refer to multiple bits as an binary value with the range (0-255).

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't forget that in AVR assembler some of the bit-wise instructions refer to a single bit's position (7 though 0) while other bit instructions have arguments that refer to multiple bits as an binary value with the range (0-255).

A good example is  sbi/cbi  versus  sbr/cbr   the "i"/o version adjusts one bit (value:0-7), the  "r"egister version adjusts any/all of the 8 bits (value:0-255)  

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry it's very clear don't use sbr and cbr, the AVR don't have those instructions, its andi and ori instructions. and when you disassemble the code that is the way they show up anyway, it's the same as it don't have a clr instruction.  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Sorry it's very clear don't use sbr and cbr, the AVR don't have those instructions, its andi and ori instructions. and when you disassemble the code that is the way they show up anyway, it's the same as it don't have a clr instruction.  

Sparrow is on the money! What is meant by that is the cbr, sbr are very commonly used and listed as AVR commands, but are actually burned into the chip as andi & ori commands.   One advantage of using cbr (say:  cbr r22, 0b00000010)  is that the build process automatically flips the bits for you, so it ends up putting andi r22, 0b11111101  into the chip, as required.

 

As hinted, clr r5 is actually created & burned in using:  eor r5, r5

 

Atmel probably laughs at us:

 

   

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Feb 13, 2021 - 05:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

Well, As far as i understand , there is no so easy way as 8051 assembly in AVR bit definition. 

 

Thanks a lot all for your answers. I appreciate all you !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. the 8051 is super-duper when it comes to bit manipulation.  Seems like it is maybe a step ahead of the AVR..but the avr isn't too much a slouch either. 

You can easily assign a name for an avr pin ( .def my_led = PA6)   & make easy use  of it (sbi PORTA, myled)     --did you run into a specific hardship?

It can' t and/or io bits directly with other registers,  which is slightly sad---you must do a transfer.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

You can simply say something like

  

.equ PA_motor_fwd = PA3

 

then

 

sbi PORTA, PA_motor_fwd  ;set pin level hi

 

It's even easier. In AVR-Studio Asm-programs a define like in C possible.

 

#define   motor_fwd   PORTA,3

 

then just

 

sbi motor_fwd

 

without the need to specify the port name.

Last Edited: Sun. Feb 14, 2021 - 11:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's even easier. In AVR-Studio Asm-programs a define like in C possible.

#define   motor_fwd   PORTA,3

That's an excellent point, however there is then no possibility to combine when trying work with several bits at once like setting the DDR, or performing an and :  andi temp, (1<switch_a) || (1<<switch_b) 

...always a tradeoff.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First yes the 8051 is really good in bit handling (Carry is like a bit accumulator, the only real pain is that it don't have a pointer to a bit like other small chips).

 

It can' t and/or io bits directly with other registers

No but the code can often be rewritten to skip if bit set/clr with the instructions SBIS SBIC SBRS SBRC

 

so like:

skip io/reg bit set/clr

skip io/reg bit set/clr

rjmp     will jump all 3 false conditions

we are here for the true.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skip io/reg bit set/clr

skip io/reg bit set/clr

rjmp     will jump all 3 false conditions

we are here for the true.

I'm afraid that has an issue ...you can't have two  sbis in a row.

We often need to use multiple bits at once, but not possible if the name has "port" as part of it.   

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm afraid that has an issue ...you can't have two  sbis in a row.

I'm not sure I have ever tried it because if I need more than 1 bit from a port I would IN and then AND/OR/EOR to check.

But I have never seen anywhere that you can't have two SBIS in a row, where is that written? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure I have ever tried it because if I need more than 1 bit from a port I would IN and then AND/OR/EOR to check.

I'm sayin exactly that, and that you can't combine the names together if they include "port" as part of their name 

  andi temp, (1<switch_a) || (1<<switch_b)    is good only if they  don't include "port"

.equ  switch_a=PA3 ....works here

#define switch_a  PORTA, 3  ...will not work here

I'm afraid that has an issue ...you can't have two  sbis in a row.

Your wording was misconstrued (by me). What I was getting at is that if you want to have 3 checks to arrive at jump  (will jump all 3 false conditions) you can't merely use two stacked sbix to make 3 different checks.   I see now you meant 3 out of 4 combinations

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sun. Feb 14, 2021 - 04:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK I was not clear (it's really had to check 3 bit with 2 1 bit check instructions) but I still want to hear where you have this from:

I'm afraid that has an issue ...you can't have two  sbis in a row.

 

because for me that is wrong, and if not I really really want to know.

 

Last Edited: Sun. Feb 14, 2021 - 04:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Having them together is allowed, but not for making 3 different checks...I'm saying you can't have two sbis in a row to do that (you would need something different).

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now when it's clear that my code in #11 is correct for any two inputs (either port or register).

 

Then the next step is that you want to see if they are the same, and here you will hate that the AVR don't have a EORI instruction :(

 

For the compare of two bits one way is this:

eor r16,r16   ; clr r16

skip io/reg bit set

inc r16

skip io/reg bit set

inc r16

now bit 0 in r16 is 0 if they are the same.

 

for AVR's with a HW mul it's sometimes use full to use it as a barrel shifter to align bits. 

 

Add:

rare but sometimes it make sense to use the T status flag, but it's only for registers.

 

And then I also will say that because the AVR registers almost is like ACC (at least [r16..31]) it's a small cost just to load the hole port into a register.

 

Last Edited: Sun. Feb 14, 2021 - 05:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you can't have two  sbis in a row.

Ah.  Where "sbis" is the "skiip if bit in IO is set" instruction, not "two sbi instructions" in a row.

 

The 8051 Architecture makes a big deal about having a "complete Boolean (single-bit) processor", so it's not surprising there is assembler support for single bit variables as well.

The AVR has fewer bit-oriented features, and puts less emphasis on them.