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
Koshchi
PostPosted: Dec 31, 2011 - 02:37 AM
10k+ Postman


Joined: Nov 17, 2004
Posts: 15127
Location: Vancouver, BC

Code:
struct _8bits
{
  unsigned bit0:1;
  unsigned bit1:1;
  unsigned bit2:1;
  unsigned bit3:1;
  unsigned bit4:1;
  unsigned bit5:1;
  unsigned bit6:1;
  unsigned bit7:1;
}
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.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
ViniciusCarvalho
PostPosted: Dec 31, 2011 - 05:15 AM
Newbie


Joined: Dec 30, 2011
Posts: 4


yeahhh! I did it!


Let's pass to other guys! ;D


Code:

//***************************************************************************************
/*
======================================
#define var (*(type*) &address)
======================================

1.create unsigned char with fix address in ram
#define   var_A (*(unsigned char*) 0x10)

2.create unsigned char into the RAM_test[0]
#define var_B (*(unsigned char*) &RAM_test[0])
2a.It looks like crazy because you already created the matrix, so, do that (SAME THING)
#define var_B    RAM_test[0] // <----

3.create a struct into the RAM_test[0]

typedef union
{
   unsigned char byte;
      struct
      {
         unsigned bit0:1;
         unsigned bit1:1;
         unsigned bit2:1;
         unsigned bit3:1;
         unsigned bit4:1;
         unsigned bit5:1;
         unsigned bit6:1;
         unsigned bit7:1;
      };
} estrutura;

//************
#define var_C (*(estrutura*) &RAM_test[0])
/*************

****** bit:field wide has to be the same wide of RAM_test[0] ******

OBS.: var_C full access variable

>>to access it value
var_C.byte

>>to access a single bit
var_C.bit0


//for make it more easily

#define vb0     var_C.bit0
#define vb1     var_C.bit1
#define vb2     var_C.bit2
#define vb3     var_C.bit3
#define vb4     var_C.bit4
#define vb5     var_C.bit5
#define vb6     var_C.bit6
#define vb7     var_C.bit7

//example

vb0 = 1;          //bit

var_C.byte = 0x01; //byte

RAM_test[0] = 0x01; //matrix

*/

 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Dec 31, 2011 - 06:46 AM
10k+ Postman


Joined: Nov 17, 2004
Posts: 15127
Location: Vancouver, BC

Code:
1.create unsigned char with fix address in ram
#define   var_A (*(unsigned char*) 0x10)
And how do you know that this does not stomp on something that is already at that address?

What are var_A and var_B for when you never use them?

Where do you ever define RAM_test?

Quote:
//for make it more easily
The only thing that I see that it does is obfuscate the code.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 31, 2011 - 12:49 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

I don't get it - I gave a link back to danni's excellent sbit.h and you still battle on in this half baked attempt to replicate it - why?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JollyMolly
PostPosted: Mar 12, 2012 - 05:28 PM
Wannabe


Joined: Feb 14, 2012
Posts: 62


#define READ(port,pin) PIN ## port & (1<<pin)

Can anyone explain how this one works

and is it possible to make one that reads when using pullup resistor on pin, Not sure if this one does it.

Is this a valid statement if(Read(port,pin) == 1)

Question
 
 View user's profile Send private message  
Reply with quote Back to top
glitch
PostPosted: Mar 12, 2012 - 05:40 PM
Raving lunatic


Joined: Jan 12, 2002
Posts: 7834
Location: Canada

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 Wink
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 12, 2012 - 05:42 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

Or just drop the ==1, anything non-zero is true. hence:
Code:
if (Read(port,pin)) {


But why not use danni's macros:

http://www.avrfreaks.net/index.php?name ... 728#835728

then you can:
Code:
#define SENSOR PIN_B3

if (SENSOR) {

which seems more readable to me than having to invoke some Read() macro.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
JollyMolly
PostPosted: Mar 12, 2012 - 05:57 PM
Wannabe


Joined: Feb 14, 2012
Posts: 62


Would work but I can't use that statement, I just wanted to learn how to use Read, my sensor values will come from the adc so I would just use the standard
Code:
If(sensor_Value (operator) WHATEVER_VALUE)
{
do this
}

thanks anyways, I guess it would work if I was using digital sensors maybe?

One question can you do a double define;
for example
Code:
#define READ(port,pin)   PIN  ## port &   (1<<pin)
#define LED_CHECK    READ(A,1)

Does that make sense, so whenever I want to check led status I just
Code:
if(LED_CHECK){}

I guess it's same as danni's macro, just more crap
 
 View user's profile Send private message  
Reply with quote Back to top
mahyarelc
PostPosted: Mar 28, 2012 - 04:40 AM
Rookie


Joined: Aug 24, 2009
Posts: 21


Hi,

I'm new to the assembly
could you explain these instructions (in the datasheet, USART section)

Code:
/* Enable receiver and transmitter */
UCSRnB = (1<<RXENn)|(1<<TXENn);
/* Set frame format: 8data, 2stop bit */
UCSRnC = (1<<USBSn)|(3<<UCSZn0);


I don't know how to use the left shift operator to set these bits

Thanks,
Mahyar
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 28, 2012 - 09:35 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

I don't know how to use the left shift operator to set these bits

Suggest you read the thread:

Bit manipulation 101

in Tutorial Forum which will explain everything.

.... Oh, wait a minute ...

OK so which bit of the explanation in this thread did you not understand exactly?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mahyarelc
PostPosted: Mar 28, 2012 - 05:49 PM
Rookie


Joined: Aug 24, 2009
Posts: 21


I sort of get it,
but to make sure:

Code:
/* Set frame format: 8data, 2stop bit */
UCSRnC = (1<<USBSn)|(3<<UCSZn0)

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 )

Thanks
Mahyar
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 28, 2012 - 06:08 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:
Is it correct?

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.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
ganseree
PostPosted: Apr 02, 2012 - 04:06 AM
Newbie


Joined: Mar 31, 2012
Posts: 1


really nice instruction for newbies like me
 
 View user's profile Send private message  
Reply with quote Back to top
alexotano
PostPosted: Apr 19, 2012 - 02:01 AM
Rookie


Joined: Mar 29, 2012
Posts: 24


clawson wrote:
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
Code:
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:
Code:

TCCR1B |= (1 << CS10) | (1 << CS12)


prescaling to 1024 (ATMEGA2560)

Why all the ORs. Didt understand well that part.

Thanks for the time you spend reading.

Alex
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 19, 2012 - 11:04 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

why do you use |= ??

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 <whatever is on the right>". This therefore converts a bit number to a bit mask.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
capcom
PostPosted: Jul 24, 2012 - 02:16 PM
Rookie


Joined: Jul 19, 2012
Posts: 26


Hi, thanks for the superb tutorial.

I am having a little bit of trouble wrapping my head around the code:

Code:
if(foo & 0x80)
{
}


So this checks if foo's bit number 7 is a 1 or 0, right?

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.

Sorry if I am not explaining my problem well, I hope you understand.

Thanks again!
 
 View user's profile Send private message  
Reply with quote Back to top
Kartman
PostPosted: Jul 24, 2012 - 02:26 PM
10k+ Postman


Joined: Dec 30, 2004
Posts: 11881
Location: Melbourne,Australia

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.
 
 View user's profile Send private message  
Reply with quote Back to top
capcom
PostPosted: Jul 24, 2012 - 02:48 PM
Rookie


Joined: Jul 19, 2012
Posts: 26


Got it, thanks. Makes perfect sense now. And I will read up on that to refresh my memory too.
 
 View user's profile Send private message  
Reply with quote Back to top
markah
PostPosted: Aug 09, 2012 - 10:40 AM
Rookie


Joined: Oct 12, 2011
Posts: 20


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
Code:
#define VALVE   SBIT(PORTD,7)
#define ALARM   SBIT (PORTB,2)

also I defined ON=1 and OFF=0
so something like
Code:
ALARM=OFF;
seems to work.
Then I needed some flags for telling me various states of things so I added a register
Code:
volatile unsigned char CONTROL_REG;
and thought I could use this eg
Code:
#define Start_FLAG SBIT(CONTROL_REG,0)
so
Code:
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
Quote:
dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
If I compile again they go away.

Please can anyone tell me if I am doing something daft and help me understand what the warning means Thanks
Mark
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 09, 2012 - 11:36 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
Location: (using avr-gcc in) Finchingfield, Essex, England

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:
Code:
#include <avr/io.h>
#include "sbit.h"

#define OFF 0
#define ON 1

volatile unsigned char CONTROL_REG;

#define Start_FLAG SBIT(CONTROL_REG,0)

int main(void) {
   while(1) {
      if (Start_FLAG == ON) {
         PORTB = 0x55;
      }
   }
}

and then study the .i file I find that the macros have expanded to be:
Code:
  if (((*(volatile struct bits*)&CONTROL_REG).b0) == 1) {

If you read this interesting page:

http://blog.worldofcoding.com/2010/02/s ... blems.html

You'll understand the issue. As it says there one "fix" is to modify sbit.h to have:
Code:
struct bits {
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
} __attribute__((__packed__, __may_alias__));

but I don't think adding "__may_alias__" in that is really much different from switching off the -Wstrict-alias option.

The bottom line is that it's just a warning of something you may need to be concerned about but as the struct is clearly the same size as the unsigned char I don't really see an issue with it.

_________________
 
 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