Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
MIchael_J
PostPosted: Sep 13, 2008 - 02:02 PM
Newbie


Joined: Sep 11, 2008
Posts: 5
Location: Poland

Thanks a lot.
Thins makes it clear. You'v definitely convinced me to get used to the current stnadard notation.
 
 View user's profile Send private message  
Reply with quote Back to top
khos007
PostPosted: Sep 15, 2008 - 10:04 AM
Newbie


Joined: Sep 15, 2008
Posts: 3


I just have small query regarding syntax:

Is this syntax valid:
PORTC = (0<<PC0); eg. driving the PC0 pin low.
or are you only able to do bit shift operations with "1"
PORTC = (1<<PC0)

I have tried this out on ATMEGA8 and it seems to work but many ppl have told me that that it is not wise to use the bit shift operation with 0 as it can lead to bugs. Could someone please clarify this for me?

Thanks in Advance.
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Sep 15, 2008 - 11:05 AM
Moderator


Joined: Jan 23, 2004
Posts: 9822
Location: Trondheim, Norway

Zero shifted left or right is always zero, so your code there just clears the entire PORTC register by setting it to zero.

You should never need to shift 0 at all, other than to indicate clearly that a bit is not set.

- Dean Twisted Evil

_________________
Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Sep 15, 2008 - 11:41 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62244
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:
Could someone please clarify this for me?

You did read the whole of this thread didn't you?

Hopefully it should have been obvious to you that to achieve what you think:
Code:
PORTC = (0<<PC0);

might do (assuming the intention is only to set bit PC0 to zero) you would actually use:
Code:
PORTC &= ~(1<<PC0);

Remeber you can only set bits with | and you can only clear them with &. Though you can obviously set/clear all 8 bits in a register in one go with a simple =, but then you cannot affect just single bits.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kangtoojee
PostPosted: Oct 07, 2008 - 05:45 PM
Newbie


Joined: Oct 07, 2008
Posts: 3


Can somebody help me out pls, I just cant access the register definitions because it says undeclared after compiling. Im using atmega324p chip. Thanks.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 07, 2008 - 05:54 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62244
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Can somebody help me out pls, I just cant access the register definitions because it says undeclared after compiling. Im using atmega324p chip. Thanks

Any particular language or variant thereof ?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kaneda
PostPosted: Nov 04, 2008 - 03:26 PM
Newbie


Joined: Jun 29, 2006
Posts: 1


I'm working on a project with an external 16-bits adc using SPI. The first 5 bits are for settling of the adc and can be discarded, I am however receiving them.
I'm reading the following bytes in 3 chars (where x is either 1 or 0):
0-7
msb|0|0|0|0|0|x|x|x|
8-15
|x|x|x|x|x|x|x|x|
& 16-23
|x|x|x|x|x|0|0|0|lsb

I want to put 0-7 in a long and shift it 5+16 to the left, put 8-15 in a long and shift it 5+8 to the left and add it to 0-7, put 16-23 in a long and shift it 5 to the left and also add it. Then convert it to a double.

so:
|0|0|0|0|0|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|0|0|0|
<<5
|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|0|0|0|0|0|0|0|0|
typecast
|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
how can I shift all bits to the left in a long?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Nov 04, 2008 - 03:41 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62244
Location: (using avr-gcc in) Finchingfield, Essex, England

Code:
unsigned int result = (byte1 << 13) | (byte2 << 5) ( (byte3 >> 3);

at a rough guess.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Nov 04, 2008 - 11:37 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13820
Location: Vancouver, BC

I would use a union.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
jwcolby
PostPosted: Nov 10, 2008 - 01:33 PM
Wannabe


Joined: Sep 25, 2006
Posts: 51
Location: 28638

When I was a boy... I learned to fix "mainframes" for the Navy. Understand that was 35 years ago so my memory of the details is questionable at best but I seem to remember that a shift took X clocks per shift position. For example to shift one position left took one clock, 2 positions took 2 cycles etc.

Is that true in the Atmega processors, or does it shift any number of positions in a single clock?

_________________
JWColby
AVRNubee
www.ColbyConsulting.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Nov 10, 2008 - 01:55 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62244
Location: (using avr-gcc in) Finchingfield, Essex, England

The ROL/ROR/LSL/LSR instructions are all shown as being 1 cycle but to shift 5 places might take 5 of them and cost 5 cycles. Though an intelligent optimiser will spot that a shift of 4 can probably be achieved with a SWAP, an AND mask and one shift for the cost of 3 cycles

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
jwcolby
PostPosted: Nov 10, 2008 - 03:12 PM
Wannabe


Joined: Sep 25, 2006
Posts: 51
Location: 28638

I haven't done bit twiddling in a long time but I thought that instead of shifting a one X positions, you just used an XOR to toggle a specific bit.

_________________
JWColby
AVRNubee
www.ColbyConsulting.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Koshchi
PostPosted: Nov 10, 2008 - 03:49 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13820
Location: Vancouver, BC

That depends on what register and what AVR you are talking about. For the newer AVRs and port registers you simply write a 1 to the proper bit in the PINx register. But I think you are a bit confused. No one uses shifting to toggle a bit. You use the shifting to create the proper bit mask that will be used for toggling (or setting or clearing) a bit. In that case an expression like:
Code:
1<<PB4

takes no clock cycles at all since the shifting is done by the compiler, not the AVR.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
jwcolby
PostPosted: Nov 10, 2008 - 04:30 PM
Wannabe


Joined: Sep 25, 2006
Posts: 51
Location: 28638

Koshchi wrote:
In that case an expression like:
Code:
1<<PB4

takes no clock cycles at all since the shifting is done by the compiler, not the AVR.


Oh, shift on then. Smile

_________________
JWColby
AVRNubee
www.ColbyConsulting.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
damian_
PostPosted: Dec 22, 2008 - 11:30 AM
Newbie


Joined: Dec 12, 2008
Posts: 9


Hello
I feel stupid, because I read this and some more forums several times about bit set, clear, compare, etc. But, I still don't understand how to do sometihngs.

I'm working with a atmega32 in WinAVR.

For example:

Code:
PORTD = (PORTD ^ 0b00000001);

This code flipp bit0 of PORTD

Code:
PORTD = (PORTD & 0b11111110);

This code switch off PIND.0
Code:
PORTD = (PORTD | 0b00000001);

And this shoudl switch on PIND.0

This is an example to compare.
I use PIND.0 as input, and when PIND.0 is "H" the program show a "0" in the LCD, because I do salida+1, and salida-1, so salida keep "0".
But when I put ground in PIND.0 (externaly), the program shoudl increase de value of salida, but "0" continues in the LCD screen, why?.

Code:

#include <main.h>//main program


int salida =0;
char y=0;


//MAIN PROGRAM
int main (void)
{

   //Configure Pins / Ports as input- (0) or output (1) 
      // Port D (Interupts)
      DDRD  = 0b11111110; //La entrada es INT0 Y DATAOUT
      //activate Pull Ups (1)
      PORTD = 0b11111111; 
       
      // Port B (LED's)               
      DDRB  = 0b00001100;   
      PORTB = 0b11110011;   
      
      lcd_clrscr();   
      lcd_init(LCD_DISP_ON);   
      lcd_gotoxy(0,0); 
      lcd_puts("NUMBER");
      
      
   while(1)//bucle principal, pone en pantalla y espera interrupciones
   {
   
      
      salida++;
      if(PIND0 & 0b11111111)//I KNOW THIS LINE IS WRONG
      {
      salida--;
      }
      
      lcd_gotoxy(0,1); 
      itoa (salida,&y,10);
      lcd_puts(&y);//I put salida as an string in the LCD
      // PIN3 PORTB set -> LED off
      PORTB |= (1<<PINB2);//to see program its running
      
   delay(2000);//to decrease the speed
    
   }
}
Well, I want to do:
Compare de value of the input in PIND.0, and make something to know when is 0 or 1.

Thanks so much
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 22, 2008 - 11:51 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62244
Location: (using avr-gcc in) Finchingfield, Essex, England

Code:
     if(PIND0 & 0b11111111)//I KNOW THIS LINE IS WRONG

try:
Code:
if (PIND & (1<<PD0))

Try to get away from 0b???????? - that's the whole point of bit shifts - you don't need to know or care what the other 7 bits are doing when you access just a single bit. So it's
Code:
TARGET ^= (1<<bit_pos); // flip the bit
TARGET |= (1<<bit_pos); // set the bit
TARGET &= ~(1<<bit_pos); // clear the bit
if (TARGET & (1<<bit_pos)) // test if the bit is set

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
damian_
PostPosted: Dec 22, 2008 - 01:16 PM
Newbie


Joined: Dec 12, 2008
Posts: 9


Thanks very much, I writte this and works ok:
Code:
if (PIND & (1<<PD0))

My last question about this is:
Code:
if (PIND & ~(1<<PD0))

This code test if bit is not set?

Thanks very much.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Dec 22, 2008 - 01:54 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18536
Location: Lund, Sweden

Quote:

Code:
if (PIND & ~(1<<PD0))

This code test if bit is not set?

No, it tests if any other bit is set. Take it step by step:

1:
Code:
1<<PD0

make a bitmask 00000001.

2:
Code:
~(1<<PD0)

negates every bit in that mask so you get 11111110

3:
A bitwise and of that and PIND thus will produce a 1 in any position where the bitmask has a 1 and PIND has a 1. Or in other words, it will produce a non-zero value if any of bits 7 of PIND to 1 is non-zero.

What you want is
Code:
if ( !(PIND & (1<<PD0)))

Work through that, in a similar manner as I did above, step by step, to see why this is diferent and will do what you ask for. (Please note that the logical NOT operator (!) is used.)

An alternative way would be to
Code:
if (~(PIND) & (1<<PD0))

as BenG has pointed out in the first page of this thread.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
damian_
PostPosted: Dec 22, 2008 - 02:52 PM
Newbie


Joined: Dec 12, 2008
Posts: 9


Ok. Now I think I've got it.
Thanks very much
 
 View user's profile Send private message  
Reply with quote Back to top
Maximilian
PostPosted: Jan 08, 2009 - 02:17 PM
Wannabe


Joined: Apr 01, 2006
Posts: 84


At this time i'm working on a little project and i just can't get my head around the following

Hardware: hef4052 multiplexer with a0 and a1 tied to PC0 and PC1 of Atmega168

I'm trying to find a nice way to define the four (0/1/2/3) states of those 2 bits and what i can come up with is:

# define Sensor0 PORTC &= ~((1<<PORTC0) & (1<<PORTC1))
# define Sensor1 PORTC &= ~((1<<PORTC0)
# define Sensor2 PORTC |= (1<<PORTC0)
# define Sensor3 PORTC |= (1<<PORTC0) | (1<<PORTC1)

Is it possible to combine an & and an | operation in a define?, and what is the best way to do it?
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits