turning on/off one bit on a port

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there an easy way to turn on/off just one bit on a port, such as PORTD, without affecting any of the other bits?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PORTD |= 0x01;

this will enable the first bit. If you know the name of the thing to be enabled, you can also do something like:

PORTD |= (1<<RXD);

where RXD is a mask for that bit.

edit: assuming you're using C, that is...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks. Yes I'm using C.

What if I want to disable just a certain bit (i.e. PORTD starts at 0xFF but I want to selectively turn off bit 2).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

same way,

PORTD = (0<<PDx); where x is your pin number

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Same concept. Use

PORTD &= 0xFB;

or you can use an XOR to toggle the bit, ie:

PORTD ^= 0b0100;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

in the good old days you would have just written cbi(PORTD, 1); or sbi(PORTD,1); but it has been removed...(still in )...

There are pointy haired bald people.
Time flies when you have a bad prescaler selected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cbi and sbi for ever!!!

There are pointy haired bald people.
Time flies when you have a bad prescaler selected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thats what i do

any comments? good or bad all are welcome

i agree with daqq
"cbi and sbi for ever!!!"



	
//***************************************
//*      MACRO'S                         *
//***************************************
	#define SBI(port,bit) 	asm("sbi %0, %1" : : "I" (_SFR_IO_ADDR(port)), "I" (bit))
	#define CBI(port,bit) 	asm("cbi %0, %1" : : "I" (_SFR_IO_ADDR(port)), "I" (bit))

	#define Sp(wrd,bit) 	CBI(wrd,bit) //set bit in port
	#define Rp(wrd,bit) 	SBI(wrd,bit)// reset bit in port
	#define Tp(wrd,bit) 	wrd ^= (1<<bit)//togle  bit in port
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OZ1 wrote:
same way,

PORTD = (0<<PDx); where x is your pin number

Absolutely not.

This will turn off all bits in PORTD, as 0 shifted to anything will always be 0. This means that the above is equivalent to

PORTD = 0

regardless of the chosen PDx. To turn off a specific bit you have to AND the current port value with a mask where every bit is set except the bit you want to clear, thus:

PORTD &= ~(1<<PDx);

.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Zalfrin wrote:
PORTD |= (1<<RXD);

where RXD is a mask for that bit.


Not quite:

RXD is the number of the bit you want to set;

(1<<RXD) is the mask for that bit

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EW wrote a great bit manipulation a while ago, and I've shoved it into the Tutorials section where it belongs. See this thread.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
"cbi and sbi for ever!!!"

Give me a correction if I'm wrong, but I think the compilers (at least GCC and ICC) are using the cbi/sbi instructions when the code is like "PORTD |= 0x01" !?

Jensi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, jensi, but I think that daqq is referring to the cbi and sbi macros that where available in older versions of avr-libc.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all ,
i have just started programming on 8515 using the GCC , and immediately run into this here small problem i.e. easy port bit manipulation in C .
I come from using C compilers which have 'bit ' datatype using which I could go like :

bit sdi PORTA.1

//and in the code ..

sdi=1;
..
.. sdi=0;

Writing SPI code using the bit bangigng method or simply turning just one led on / off is much simpler this way.. is there any such syntax I could use with GCC or is it going to be & and | all the way.. ?? :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're going it have to use a bitfield (do a forum search for examples) if you want to be able to use bits. Create a bitmask to a global flag register, then #define an alias to a bit so you can then use that alias like your old bit datatype.

I strongly suggest you just learn the "proper" C bitmask manipulations - there's a post in the Tutorials section ("Programming 101") which explains how to set, toggle and clear bits in a register/variable.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

#define clear_bit(a,z) (a &= ~_BV(z))
#define set_bit(a,z) (a |= _BV(z))

clear_bit(PORTB, PB7);

works for me :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

old thread, but...

I'm not sure that gcc allows this, but when I was using the motorola/freescale software stationary for an embedded systems class, they did something like this:

struct PORT {
unsigned char bit7 : 1,
unsigned char bit6 : 1,
...
unsigned char bit0 : 1;
}

syntax is not quite right, but you get the idea. There were also unions inside the struct that allowed you to access the whole port if you so desired. Then,you would use something like this:

struct PORT PORTD @ 0x220 //address of PORTD

PORTD.bit0 = 1;

As I said, probably will not work in gcc, but it was a pretty handy way of accessing ports and registers and such.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's the gist of what you do with GCC, and it's called a bitfield. In GCC you have to define an alias name via #define rather than creating a struct at a fixed IO address - a search of the forums for "bitfield" will yield good results.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR program that toggles all bits of PORTB and mointer bit #2 of PORTC if it is On , turn ON bit 7 of PORTC else turn OFF bit 7 of PORTC

M.N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR program that  toggles all bits  of PORTB and mointer bit #2 of PORTC if it is On , turn ON bit 7 of PORTC else turn OFF bit 7 of PORTC 

M.N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like Zabrin says

 

To set a bit to one

 

PORTB |= (1<<PinNumber)

 

To reset a bit to zero

 

PORTB &= ~(1<<PinNumber)

 

To toggle a bit

 

PORTB ^= (1<<PinNumber)

 

In PinNumber you can put a number, varible or constand.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thank you , also please help me with that i am zero experience

 

 AVR program that gets the status of bit5 of PORTB & send it to bit 7 of PORTC

M.N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 AVR program that gets the status of bit5 of PORTB & send it to bit 7 of PORTC

 

M.N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

statusB5 = PINB & (1<<5)

 

if (statusB5) {PORTC |= (1<<7)}
        else                    {PORTC &= ~(1<<7)}

 

I add an atmel solution it uses a library I have personally so it's more complex but you can check it if you want feel free to use the library only GPIO and Timers have been tested

 

https://drive.google.com/file/d/...

Last Edited: Tue. Oct 9, 2018 - 05:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

please can you help me also to find a link ti download Atmel studio 7 

warm regards 

M.N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mohamad najem wrote:
please can you help me also to find a link ti download Atmel studio 7

http://lmgtfy.com/?q=atmel+studi...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mohamad najem wrote:

please can you help me also to find a link ti download Atmel studio 7 

warm regards 

 

Were you a sleep in class the day they showed how to google?

 

http://www.microchip.com/mplab/a...

 

Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AVR program using assembly language to monitor PORT B, if its high, send 55 hex to PORT D, else send AB hex to PORT D. how can i make it??

Lallous

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Elio sebaaly wrote:
to monitor PORT B, if its high
PORTB is EIGHT bits - which one did you have in mind?

 

Anyway the general technique is to set B as input. D as output, then read PINB to get the input state, determine whether the condition is met (not clear what condition you are testing for - see above) then write 55/AB to D based on this.