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]

In fact I've seen (0<<XXX) used in the Atmel Butterfly code, so somebody somewhere must think is okay to do this.

No, no , no. The only use of a 0<< is when you want to document the fact that something is deliberately not being set. maybe something like:

TCCRB = (1 << CS02) | (0 << CS01) | (1 << CS00);

Too often we see threads here where the user has grasped the fact that to set a bit they use:

SFR |= (1 << bit);

but then see variants of:

SFR |= (0 << bit);
SFR &= (0 << bit);
SFR &= ~(0 << bit);

where they believe that using 0 in the mask is the way to switch things off. As we all know, it isn't.

This notion should be stomped on from a great height before it confuses more beginners (especially in this thread we all point them towards to learn this stuff!).

The only use of (0 << foo) is to document that foo is not being used.

Cliff - It was late and my thought was 'jeez this guy didn't even glance at the tutorial' since all it would have taken was a glance to answer his question. Usually I just pass on by but for some reason this one exceeded a threshold, thus my response which the poster sees correctly as me ragging on him. And as usual, your response fully explains why his first usage doesn't make sense and the real 'proper' use of (0<<xxx).

Do not cross post and do not post to tutorials except to suggest improvements to the original article.

The last 202,030 people who have read this thread clearly understood the reason. If you don't I can only suggest you re-read until you understand. Also see the point I just made regarding bit number vs. bit mask in your cross-post.

First, this requires a ";" at the end of it. Second, once you define it, you never use it (just putting .bit0 after some random variable will not work). Third, stop using macros until you actually know how to code. Using macros at this point can only introduce more errors than you already have.

the macro uses the past operator to join the text PIN with whatever value is in 'port' thus if you said read(A, 1) the intermediate stage is "PIN ## A" which is converted to "PINA".

There is no difference in reading a PIN register whether the pullups are enabled or not, so the statement works equally as well in both cases.

Unfortunately your if statement does not work, because the result of the read is the setting of the bit in it's natural position, not in the 1's position. [unless reading pin 0].. you can test for 0, but not 1 like that. Consider the result to be boolean, where 0=false, and any non-zero value is true.

if you want 1 or 0, you can sue a little obfuscated c trickery.
if(!!Read(port,pin) == 1)

I'll leave it to you to figure that one out ;)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

it means shift 1 to the left for USBSn times (as USBSn is bit no.3 in UCSRnC register, we shift 1, 3 times and get 00001000)
the same pattern for UCSZn0(bit no.1) provides us 00000110

Is it correct?

another question is why we write 1 in UCSZn0 and UCSZn1 for the USART? (the code is from datasheet, page 177, mega1284p)
because datasheet says the initial values for these bits are set to 1 by default.
(register in page 191 )

You got it. But I doubt you want to set USBS as almost always you just want 1 stop bit.

Quote:

another question is why we write 1 in UCSZn0 and UCSZn1 for the USART? (the code is from datasheet, page 177, mega1284p)
because datasheet says the initial values for these bits are set to 1 by default.
(register in page 191 )

Yup it's quite ridiculous isn't it (even worse on CPUs that use the URSEl bit which makes it more complex). 99% of users will always want the 8N1 default.

I think this tutorial is trying to be as generic as possible. Not all the AVR C compilers have all the bit names defined in the header files for each AVR part so

TCCR1B |= (1 << CS10);

won't necessarily work on all compilers.

Grat Tutorial Dean!! Im reading all of your tutos from your web!!

About the part of the code wrote here by clawson, if some one is able to answer a silly question...

why do you use |= ?? I download al the example codes and they work the seam without it. I really dont understand why the OR operation bet (1 << CS10) and TCCR1B ... and there's other thing like in the case of:

But that is EXACTLY what's explained in this very tutorial? I'm not going to repeat the text of the tutorial here so I suggest you go back to page 1 and re-read it until you understand what it is saying.

Maybe it helps to add that:

1) OR and only switch additional bits from 0 to 1
2) AND can only switch additional bits from 1 to 0
3) << means move the thing on the left the number of places given on the right. If the thing on the left is just 1 then it's saying "form a number with 1 in bit position ". This therefore converts a bit number to a bit mask.

Supposing foo was, for example, 10100110 and we use the & operator with 10000000 as shown in your if statement above.

Now, this will return 10000000, right? But in order for the if statement to execute, shouldn't the code in the brackets result in a value of 1? I suppose it makes sense if the if statement executes for any value greater than zero.

True is a non-zero value, false is zero. Therefore, since the result is non-zero, the code in the brackets will execute. You might want to read up on the difference between logical and bitwise operstors whichis covered in any half decent book on C.

Hi, Great tutorial and how I got to get to grips with bit manipulation, still v new to it all though.
Now I am writing a program with several I/Os and I used the SBIT posted and mentioned a few times in this Tutorial.
I used it in places for control of pins eg

#define VALVE SBIT(PORTD,7)
#define ALARM SBIT (PORTB,2)

also I defined ON=1 and OFF=0
so something like

ALARM=OFF;

seems to work.
Then I needed some flags for telling me various states of things so I added a register

volatile unsigned char CONTROL_REG;

and thought I could use this eg

#define Start_FLAG SBIT(CONTROL_REG,0)

so

if (Start_FLAG ==ON)
{ }

.
I saw at the bottom of the entry in the TUT that

Quote:

Naturally this macro can also be used for internal flag variables, not only for IO registers.

Now when I compile with Studio 6 I get warnings where I refer to the regester eg

In the miscellaneous section of AVR/GNU C Compiler options you may find it illuminating to add --save-temps. When you build the output directory (probably GccApplicationN\Debug) will then contain a foo.i and foo.s for each foo.c in the build. If I build:

I think I get it, makes for interesting reading, a little bit over the head of me as a novice. They say a little knowledge is dangerous!
I'm still not sure if I should worry about it.
There seems to be conflicting opinnion in the blog.

it is not good that we search 2 or 3 weeks to find out what << or >> do in avr-gcc.

1. Welcome to AVRfreaks!

2. Your remark shows that you need to trim your search skills. 2 or 3 weeks to find that tutorial is your problem.

3. You have been searching "for 2 or 3 weeks", but yet you joined AVRfreaks today.. :roll:

Quote:

is there any official web site for avr-gcc to help us what is keywords, operators and etc in avr-gcc?

The shift operators, as has been remaked by clawson above, are not specific to avr-gcc. They are standard C. Get a good C book. Read. (Or would you expect avr-gcc documentation to hold information about the if- and while-statements, on assignments, on the assignment operator etc too? Of-course bot. The avr-gcc documentation coers what is specific to avr-gcc. For standard C it is any document describing standard C. For GCC specifics it is the GCC documentation. For avr-gcc, most of it is also in the GCC documentation. The GCC documentation is available on The Web. Google it.)

Also, avr-gcc/avrlibc is the work of devoted voluntaries. They do not get paid. You either more or less accept the state of those tools and the documentation that come with them, or you pay money to buy a commercial compiler/IDE and support for it. There is no such thing as a free lunch.

If you not only are new to AVRs and avr-gcc but also to the C programming language then you will have a learning experience ahead of you. There will be no one-stop solution to satisfy all your information needs. You will need at least these:

1. A good C book, or tutorial on the net.

2. The avr-gcc/avrlibc help. If you are using Atmel Studio and the avr-gcc that comes with that then the help is on your hard disk and integrated in Atmel Studio.

3. The data sheet for your AVR model.

4. Tutorials etc on programming AVRs. AVRfreaks have a whole forum devoted to tutorials. Get yourself acquainted with the contents of that forum, and it will serve you well.

5. Help on The Web by unpaid voluntaries. We are here. Your job is to ask your questions in a manner that gets us interested in your problem. Present clear and complete information. Read and give feedback on advice that is given. (A whining post like yours above is not the best way to start out...) By and large the AVRfreaks community will treat you as you treat it.

Once again, welcome to AVRfreaks!

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]

If you have further questions about this can you start a new thread in AVR Forum. The purpose of this thread is simply for corrections and clarifications of issues about Bit Manipulation that are outlined in the first post - not timers.

First thing to do: Shift to the first page and read the tutorial. If someone put time into that then do them the honor of reading it. Then ask specific questions, referring to that text, on what you don't understand in it.

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]

First thing to do: Shift to the first page and read the tutorial. If someone put time into that then do them the honor of reading it. Then ask specific questions, referring to that text, on what you don't understand in it.

i'm sorry, but i have read the 1st page, and i don't have the answer, i mean why do program have many way to write that code (PORTB |= 1<<PB1,etc) if only have one purpose?

i mean why do program have many way to write that code (PORTB |= 1<<PB1,etc) if only have one purpose?

The << operator is a part of the C language itself.

The rest of the variations comes not form the C language as such but from what different people have written in header files that you include.

So, to set bit 6 in PORTB you write

PORTB |= (1<<6);

E.g. some people think that the use of the << operator is not pretty, or understandable (or whatever) so they hide it behind a macro that they define like so:

#define _BV(bitnumber) (1<<bitnumber)

And can then write

PORTB |= _BV(6);

Now, the use of the explicit '6' here might not seem so troublesome, but for other registers where bits have special meanings it will make for obscure code if the bit number is given as a number. So there are definitions of bit numbers for all the bits of all special purpose registers (the ones where you control UARTS, timers etc..).

If a Timer/Counter Control Register has a bit at position 4 for Timer Overflow Interrupt Enable then you might write

TCCR |= 1<<4;

but it would be much clearer to code e.g.

TCCR |= 1<<TOIE;

This has then been worked back to the digital I/O ports where the names of those bit numbers simply become e.g. PB0, PB1, PB2...

So now someone can code

PORTB |= (1<<PB6);

or

PORTB |= _BV(PB6);

Again, all variation here is due to what is coded in header files. They are not defined in the C language as such.

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]

the choice amongst those is purely down to personal taste. If you take a typical device header file (I used mega16) and look at the definitions of bit 6 relating to PORTB it has all of:

#define PINB6 6
#define DDB6 6
#define PB6 6

(no definition of PORTB6 in fact - just PB6) so yuou can use anything that will expand out to be "6" in either (1<<n) or _BV(n) or whatever other way you want to expand it out to be a bit mask. So you could use:

PORTB |= (1 << DDB6);
PORTB |= _BV(PINB6);

Sure those bits are supposedly for the DDR register and the PIN register but they are all 6 so any of them could be used. My own personal preference in fact is always to use the Ppn form so PB6 or whatever and use it for all three when accessing any of PORTB, PINB or DDRB. But each to their own - you may choose something else.

BTW there's nothing magic in any of this a pre-processor macro is just a string substitution so you can use anything that would equate to 6 in order to access bit 6. If you look at the iom16.h file it has:

I'm not suggesting you do this (unless you deliberately wanted to make the code very confusing for the reader!) but simply pointing out that there's nothing special about where the 6 you use comes from.

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

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

if (~(PIND) & (1<<PD0))

as BenG has pointed out in the first page of this thread.

I read this several times and although I thought it made sense I of course must be missing something.
In the code below I want to upon start up display two lines of text. Which worked. I then want to look at portb.0 and if it is pressed display what is inside the {}

I tried using the example above but it does not appear to get teh unit to change the screen. I know I am doing something wrong because when I hit pause during debugging, the disassembly window pops up. I am using AS6 and an STK600 with a MEGA2560

What I end up with is the screen scrolling through both sets of texts at a very high rate. And if I hit pause, I get the disassembly window letting me know I screwed up. I am gonna work on this for a few more hours before bed.

EDIT:I GOT IT TO WORK!!
I found my boo boo's with a lot of reading and google :? but it works now.

I know the indentation sucks. I figured that out after I lost track of my {}'s. But I needed to hold after the screen did it's write. In other words, the screen kept refreshing, so I insert the WHILE statements and there it goes.
I have to admit I have some more reading to do as I found a post elsewhere using the Bit_is_set/Bit_is_clear shortcut as opposed to the & != stuff that made it all happen. I will need to look into how those two statements work better.

Ok off to bed. 3:30am is fast approaching

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman