| Author |
Message |
|
|
Posted: Sep 13, 2008 - 02:02 PM |
|

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. |
|
|
| |
|
|
|
|
|
Posted: Sep 15, 2008 - 10:04 AM |
|

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. |
|
|
| |
|
|
|
|
|
Posted: Sep 15, 2008 - 11:05 AM |
|


Joined: Jan 23, 2004
Posts: 9888
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  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Sep 15, 2008 - 11:41 AM |
|


Joined: Jul 18, 2005
Posts: 62944
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 |
_________________
|
| |
|
|
|
|
|
Posted: Oct 07, 2008 - 05:45 PM |
|

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. |
|
|
| |
|
|
|
|
|
Posted: Oct 07, 2008 - 05:54 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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 ? |
_________________
|
| |
|
|
|
|
|
Posted: Nov 04, 2008 - 03:26 PM |
|

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? |
|
|
| |
|
|
|
|
|
Posted: Nov 04, 2008 - 03:41 PM |
|


Joined: Jul 18, 2005
Posts: 62944
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Code:
unsigned int result = (byte1 << 13) | (byte2 << 5) ( (byte3 >> 3);
at a rough guess. |
_________________
|
| |
|
|
|
|
|
Posted: Nov 04, 2008 - 11:37 PM |
|

Joined: Nov 17, 2004
Posts: 13960
Location: Vancouver, BC
|
|
| I would use a union. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Nov 10, 2008 - 01:33 PM |
|

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
|
| |
|
|
|
|
|
Posted: Nov 10, 2008 - 01:55 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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 |
_________________
|
| |
|
|
|
|
|
Posted: Nov 10, 2008 - 03:12 PM |
|

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
|
| |
|
|
|
|
|
Posted: Nov 10, 2008 - 03:49 PM |
|

Joined: Nov 17, 2004
Posts: 13960
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.
|
| |
|
|
|
|
|
Posted: Nov 10, 2008 - 04:30 PM |
|

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.  |
_________________ JWColby
AVRNubee
www.ColbyConsulting.com
|
| |
|
|
|
|
|
Posted: Dec 22, 2008 - 11:30 AM |
|

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 |
|
|
| |
|
|
|
|
|
Posted: Dec 22, 2008 - 11:51 AM |
|


Joined: Jul 18, 2005
Posts: 62944
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
|
_________________
|
| |
|
|
|
|
|
Posted: Dec 22, 2008 - 01:16 PM |
|

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. |
|
|
| |
|
|
|
|
|
Posted: Dec 22, 2008 - 01:54 PM |
|


Joined: Mar 27, 2002
Posts: 18757
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. |
|
|
| |
|
|
|
|
|
Posted: Dec 22, 2008 - 02:52 PM |
|

Joined: Dec 12, 2008
Posts: 9
|
|
Ok. Now I think I've got it.
Thanks very much |
|
|
| |
|
|
|
|
|
Posted: Jan 08, 2009 - 02:17 PM |
|

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? |
|
|
| |
|
|
|
|
|