| Author |
Message |
|
|
Posted: Feb 22, 2012 - 07:43 PM |
|

Joined: Jan 31, 2012
Posts: 129
Location: Vancouver, BC, Canada
|
|
Hi all,
I am still getting my feet a little wet with programming and I learn a lot by examining other sample code. In the sample program AT45DBX_EXAMPLE1 in the A3BU Kit section that comes with AVR Studio 5.1, there is the following code which confuses me:
Code:
//! Sector size in bytes.
#define AT45DBX_SECTOR_SIZE (1 << 9)
I hope this displays properly. The part that confuses me is the #define ... (1 << 9). I thought '<<' meant bit shifting? I don't understand what that really means when it comes to definitions.
I have looked over my C and C++ books, as well as numerous forums but I can't seem to get a decent answer beyond 'That is bitshifting', which doesn't really explain anything.
Can anyone help me out on this one? I appreciate the help  |
_________________ ATMega644a
XMEGA-A3BU
JTAGICE3 Programmer
AVR Studio 5.1.148
FLIP 3.4.5 Build 106
Last edited by tmwoods on Feb 22, 2012 - 09:02 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: Feb 22, 2012 - 08:30 PM |
|


Joined: Mar 28, 2001
Posts: 20363
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
| A 1<< 9 times would be 512 I guess (0x0100 or 0000 0001 0000 0000) |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
|
| |
|
|
|
|
|
Posted: Feb 22, 2012 - 08:48 PM |
|

Joined: Jan 31, 2012
Posts: 129
Location: Vancouver, BC, Canada
|
|
That does make sense but I don't understand why anyone would ever code that; to me it is much more efficient to just use the hex definition. I am especially confused because the original code is:
Code:
//! Number of bits for addresses within sectors.
#define AT45DBX_SECTOR_BITS 9
//! Sector size in bytes.
#define AT45DBX_SECTOR_SIZE (1 << AT45DBX_SECTOR_BITS)
I see this all over the ASF and sample code from AVR studio. I am far from being an expert, and maybe there is a good reason for doing this so I hope I don't sound like a naive idiot but why on earth would anyone do that? It just seems wildly inefficient.
That being said, thank you for the explanation, what you wrote does make good sense. |
_________________ ATMega644a
XMEGA-A3BU
JTAGICE3 Programmer
AVR Studio 5.1.148
FLIP 3.4.5 Build 106
|
| |
|
|
|
|
|
Posted: Feb 22, 2012 - 08:51 PM |
|

Joined: Sep 04, 2005
Posts: 193
|
|
The syntax is widely used, so you should become used to it.
You can read (1 << x) in several ways:
A numeric value which is 2^x, eg. (1 << 9) is 512
Bit number x in a register.
Say you wish to set pin 3 and 7 of PORTD, you write PORTD.OUTSET = (1 << 3) | (1 << 7) which is more intuitive than say PORTD.OUTSET = 0x88
defines are used because using constants all over the place in your code is hard to read and maintain.
For instance you could have connected pin 4 on PORTD to an enable pin on another ic.
so instead of writing PORTD.OUTSET = (1 << 4), you could have written a couple of defines to make your intent clear in the code
Code:
#define IC_PORT PORTD
#define IC_PINENABLE (1 << 4)
now you could write
Code:
IC_PORT.OUTSET = IC_PINENABLE;
you could go even further and create a function that does it. If the function is declared as static inline, it will perform exactly the same as
Code:
static inline void enableIc()
{
IC_PORT.OUTSET = IC_PINENABLE;
}
It's all about readability, because after the compiler has done it's work, the resulting binary would end up the same. |
|
|
| |
|
|
|
|
|
Posted: Feb 22, 2012 - 08:55 PM |
|


Joined: Mar 28, 2001
Posts: 20363
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)
|
|
|
Quote:
I see this all over the ASF
Good to know, another reason to stay away from the ASF.  |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
|
| |
|
|
|
|
|
Posted: Feb 22, 2012 - 09:02 PM |
|

Joined: Jan 31, 2012
Posts: 129
Location: Vancouver, BC, Canada
|
|
Thanks guys; I appreciate the explanations. As per usual, it seems like the best thing to do is to just write my own header and initialization files. I guess I learn more this way anyway  |
_________________ ATMega644a
XMEGA-A3BU
JTAGICE3 Programmer
AVR Studio 5.1.148
FLIP 3.4.5 Build 106
|
| |
|
|
|
|
|
Posted: Feb 23, 2012 - 01:28 AM |
|

Joined: Nov 28, 2004
Posts: 3552
Location: San Diego, Ca
|
|
| Maybe they did it that way to make it easy to use different size Flash chips, for various apps. they wrote... ? |
_________________ 1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
|
| |
|
|
|
|
|
Posted: Feb 23, 2012 - 09:06 AM |
|

Joined: Jun 19, 2002
Posts: 955
Location: SF Bay area
|
|
The (1<<bitnum) syntax is widely used because the documentation and the Atmel-defined symbols (and parts of the instruction set) are all based on "bit numbers" rather than masks. So "sbr r16, 1<<SPIENA" is correct, and so is "SPICR |= 1<<SPIENA;"
It's not inefficient, because it all happens at compile or assembly time.
I don't know why it would be used for a size, though. Except to make it obvious that the size is dependent on the size of a bit field... |
|
|
| |
|
|
|
|
|
Posted: Feb 23, 2012 - 09:14 AM |
|


Joined: Mar 27, 2002
Posts: 18549
Location: Lund, Sweden
|
|
|
Quote:
That does make sense but I don't understand why anyone would ever code that; to me it is much more efficient to just use the hex definition.
Two separate discussions going on here: One is about symbolic names for things, the other is about the shifting op.
Using symbolic names for bit numbers makes it obvious instantly which bits are manipulated. Using hex makes it necessary to back-reference the data sheet more often to reveal what the code actually does.
Other good reasons also exists.
The use of shifting is merely a matter of the bit definitions being bit numbers rather than bit masks. This I believe is a consequence of AVR machine instructions for bit manipulation is using bit numbers rather than bit masks. |
|
|
| |
|
|
|
|
|
Posted: Feb 26, 2012 - 05:55 PM |
|

Joined: Apr 01, 2003
Posts: 186
|
|
| Take a look at app note AVR1000, "Getting Started Writing C Code for Xmega." (http://www.atmel.com/Images/doc8075.pdf). It will explain the unique notation used with Xmegas that's so confusing for the uninitiated. It takes some practice, but will make your code much more readable and maintainable. |
|
|
| |
|
|
|
|
|