| Author |
Message |
|
|
Posted: Dec 30, 2009 - 02:37 PM |
|

Joined: Dec 30, 2009
Posts: 10
|
|
Hello everyone. I am used to working with PIC chips, but now I have been given a project using the Atmel ATMEGA48, and I have a simple question that I can't seem to get around.
I want to just write to a single port pin, and not the entire register. For example:
PORTB = 0x00 will make all the port B pins low (assuming they are outputs)
Now, I want to just do something like this:
#define output_led = PORTB3
...
output_led = 0;
...
I am sure there should be a way to do this, but I just can't seem to figure it out. I am using the WinAVR gcc compiler. Thanks for the help. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 02:48 PM |
|


Joined: Oct 25, 2007
Posts: 159
Location: Rochester, NY
|
|
| There is alot of information regarding this and other programming specifics in the Stickies on this page and also in the Tutorials forum. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 02:51 PM |
|


Joined: May 01, 2002
Posts: 750
Location: Texas
|
|
From CodevisionAVR Help...
The bit level access to the I/O registers is accomplished using bit selectors appended after the name of the I/O register.
Because bit level access to I/O registers is done using the CBI, SBI, SBIC and SBIS instructions, the register address must be in the 0 to 1Fh range for sfrb and in the 0 to 1Eh range for sfrw.
Example:
sfrb PORTA=0x1b;
sfrb DDRA=0x18;
sfrb PINA=0x19;
void main(void) {
/* set bit 0 of Port A as output */
DDRA.0=1;
/* set bit 1 of Port A as input */
DDRA.1=0;
/* set bit 0 of Port A output */
PORTA.0=1;
/* test bit 1 input of Port A */
if (PINA.1) { /* place some code here */ };
/* ....... */
}
To improve the readability of the program you may wish to #define symbolic names to the bits in I/O registers:
sfrb PINA=0x19;
#define alarm_input PINA.2
void main(void)
{
/* test bit 2 input of Port A */
if (alarm_input) { /* place some code here */ };
/* ....... */
}
It is important to note that bit selector access to I/O registers located in internal SRAM above address 5Fh (like PORTF for the ATmega128 for example) will not work, because the CBI, SBI, SBIC and SBIS instructions can’t be used for SRAM access. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 02:59 PM |
|


Joined: Mar 27, 2002
Posts: 9689
Location: Lund, Sweden
|
|
|
Quote:
From CodevisionAVR Help...
which is fine for that compiler only. But OP said
Quote:
I am using the WinAVR gcc compiler.
BMan, the first thing to read is the "bit manipulation tutorial" in the tutorials forum. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 03:13 PM |
|

Joined: Feb 12, 2005
Posts: 7730
Location: Cratfield, England
|
|
|
Quote:
Now, I want to just do something like this:
Code:
#define output_led = PORTB3
...
output_led = 0;
...
Most PIC compilers would allow you to write:
Code:
PORTB.3 = 0;
Unfortunately most AVR compilers require you to use standard C.
Code:
PORTB &= ~(1<<3); // clears bit3
You can wrap this in functions or macros, or possibly declare a bitfield structure that uses a 'legal' field name like 'B3' instead of the 'illegal' '3'. e.g.
Code:
PORTB.B3 = 0;
As alwelch has suggested, you could use the CodeVision compiler which permits the PORTB.3 syntax.
Remember that one day you will move to an ARM compiler. So while irritating it is worth getting into the habit of using standard C.
David. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 03:49 PM |
|

Joined: Dec 30, 2009
Posts: 10
|
|
| Thanks for the help everyone. |
|
|
| |
|
|
|
|
|
Posted: Dec 30, 2009 - 11:55 PM |
|


Joined: Jan 23, 2004
Posts: 7024
Location: Melbourne, Victoria, Australia
|
|
Just so you don't get lost BMan, the tutorial mentioned above is located here:
http://www.avrfreaks.net/index.php?name ... mp;t=37871
If you want to use the magical "PORTB.B2" syntax, do a forum search for "bitfield", which should yield the code required to cast the standard registers into a set of individually alterable bits.
- Dean  |
_________________
|
| |
|
|
|
|
|
Posted: Dec 31, 2009 - 12:08 AM |
|

Joined: Sep 12, 2009
Posts: 963
|
|
In case the OP has efficiency concerns, it is worth pointing out that WinAVR converts code like
Code:
PORTB |= (1<<2);
and
Code:
PORTC &= ~(1<<4);
to single AVR bit-set or bit-clear instructions, as necessary. |
|
|
| |
|
|
|
|
|
Posted: Dec 31, 2009 - 01:44 AM |
|


Joined: Jul 28, 2001
Posts: 275
Location: Rio de Janeiro
|
|
|
abcminiuser wrote:
If you want to use the magical "PORTB.B2" syntax, do a forum search for "bitfield", which should yield the code required to cast the standard registers into a set of individually alterable bits.
Here it is: http://www.avrfreaks.net/index.php?name ... 174#216174 |
_________________ Felipe Maimon
|
| |
|
|
|
|
|