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
BMan
PostPosted: Dec 30, 2009 - 02:37 PM
Newbie


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.
 
 View user's profile Send private message  
Reply with quote Back to top
Rukus
PostPosted: Dec 30, 2009 - 02:48 PM
Hangaround


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.
 
 View user's profile Send private message  
Reply with quote Back to top
alwelch
PostPosted: Dec 30, 2009 - 02:51 PM
Resident


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.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Dec 30, 2009 - 02:59 PM
Raving lunatic


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.
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Dec 30, 2009 - 03:13 PM
Raving lunatic


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.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
BMan
PostPosted: Dec 30, 2009 - 03:49 PM
Newbie


Joined: Dec 30, 2009
Posts: 10


Thanks for the help everyone.
 
 View user's profile Send private message  
Reply with quote Back to top
abcminiuser
PostPosted: Dec 30, 2009 - 11:55 PM
Moderator


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 Twisted Evil

_________________

 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
kk6gm
PostPosted: Dec 31, 2009 - 12:08 AM
Resident


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.
 
 View user's profile Send private message  
Reply with quote Back to top
fmaimon
PostPosted: Dec 31, 2009 - 01:44 AM
Hangaround


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