Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Setting specific bits in variables *PIC*

Status
Not open for further replies.
Pommie said:
You cannot ignore time. If you ignore time wont you always receive 1010101010. Surely, receiving Manchester encoded data is exactly the same as RS232 (timing wise) except you get twice as many bits.

RS232 uses fixed timing, Manchester doesn't, it's the transitions that are the data, NOT the HIGH or LOW points. In fact you can recover the original 'clock rate' from the Manchester coding if you didn't know it.

Obviously timing can't be completely ignored, a transition shouldn't occur too early, or too late - but there's a LOT of variation possible.

The reason this is important is that neither IR or Wireless links provide the same data output as you supply to the transmitter - which makes RS232 type timing unreliable. As long as you're running at a fairly low speed, you can read RC5 by a crude timed sampling technique, but obviously if you drift outside the correct bit you will read completely the wrong data - and as RC5 uses many more bits than RS232, it's got more chance of doing so. Having played for years with IR and Wireless links, I still find it confusing that the pulse widths from the receiver vary in width depending on the number and sequence of high and low bits, and the received signal strength.

Notice how the SIRC's IR system uses very different pulse widths, it's for the same reason - so timing is VERY non-critical.
 
Brian Hoskins said:
But I was reffering to a variable I have created in my program, not an I/O port of the PIC. Before posting I did check the header file to see how they accomplish the setting of the ports. I could see what they were doing but wasn't able to relate it to my application.
You can do it by creating a union of a struct and a char like this:
Code:
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;
 };
} data;
//You can access them like this:
	data.byte = 0x55;
	data.bit0 = 0;
	data.bit1 = 1;
//etc....
 
kchristie,

Ahhh ok. I can see how that would work. I think I need to revise my understanding of structures then. One question,

"data.byte = 0x55;"

Why is this line required and what is it for?

Brian
 
Another question, I assume that you can manipulate the variable "byte" in the same way as any other variable? I'm talking about performing shift instructions on it etc.

Brian
 
Brian Hoskins said:
Another question, I assume that you can manipulate the variable "byte" in the same way as any other variable? I'm talking about performing shift instructions on it etc.

Brian
Yes. It is like any other variable, the only diff is that the compiler knows how to access it on the bit level.
 
kchriste said:
You can do it by creating a union of a struct and a char like this:
Code:
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;
 };
} data;
//You can access them like this:
	data.byte = 0x55;
	data.bit0 = 0;
	data.bit1 = 1;
//etc....

Again, isn't this C18 specific?

What do you have against Var|=1;

Mike.
 
It looks standard to me, too. I have studied structures a little but I've not used them in embedded programs (infact this is my first microcontroller program written in C).

But Mike's var |= 1 solution works fine actually.

Brian
 
Sorry, shouldn't have said C18 specific. I was referring to the OP stating that his compiler uses Ra0=xx etc and that the original question is best answered by using |=. The use of union and structures is just complicating the issue.

Mike.
 
Pommie said:
Sorry, shouldn't have said C18 specific. I was referring to the OP stating that his compiler uses Ra0=xx etc and that the original question is best answered by using |=. The use of union and structures is just complicating the issue.

Mike.

I would say no. The structs are a good thing because they allow the naming of bits and fields. But without the compiler provided header file it will not compile.

If you do not like the idea of the compiler vendor owning the header file you can write your own. It would not be any more work then defining a good set of masks for doing bitwise operations.
 
Brian Hoskins said:
But Mike's var |= 1 solution works fine actually.
Yes. If you look at the disassembly listing, you'll see that it's translated into a simple BSF instruction, as Mike said. Hi-Tech PICC compiler always checks if the mask is actually a 1-bit operation.

If you like to use bit numbers, you could use a simple macro, that will be translated into 1-cycle instructions (i.e. BCF or BSF):
Code:
unsigned char tmp;

#define bitset(var,bitno) (var|=1<<bitno)
#define bitclr(var,bitno) (var&=~(1<<bitno))


// test

// ...


    tmp = 0;

    tmp |= 0x01;
    
    while(1)
    {

        bitset(tmp,0);
        NOP();

        bitclr(tmp,0);
        NOP();

    }
 

Attachments

  • asm.png
    asm.png
    2.3 KB · Views: 145
Last edited:
The C18 compiler generates BSF instructions to set and clear single bits for structs. People have been writting C compilers for 30 years.
Code:
6:                 void main()
7:                 {
8:                     TRISA = 0x00;  
  00F4    6A92     CLRF 0xf92, ACCESS
9:                     LATAbits.LATA7 = 1;
  00F6    8E89     BSF 0xf89, 0x7, ACCESS
10:                }
  00F8    0012     RETURN 0

I see no great right or wrong here.

EDIT: I was curious about the CCS PCM compiler. It also used BSF for struct bit fields.
 
Last edited:
Pommie said:
Again, isn't this C18 specific?
What do you have against Var|=1;
Mike.
No, it's plain old C coding. I have nothing against any programming method as long as it is clear and it does what the programmer intended. Var|=1 is perfectly fine too. The union also makes it easier to test the state of a bit within a byte by using the IF statement:
Code:
	if ( data.bit1 == 0 ) { x++; }
What is neat about unions is that it makes for easy translation of data types and the grouping of bits within a byte, word, dword, float, etc:

Code:
union {
 unsigned char byte;
 struct {
  unsigned bits0_2:3;
  unsigned bits3_5:3;
  unsigned bits6_7:2;
 };
} OddBit;

	OddBit.byte = 0;
		for( OddBit.bits3_5 = 0x7; OddBit.bits3_5 > 0; OddBit.bits3_5-- )
		{ OddBit.bits0_2++; }
So you can see it allows you to manipulate bits within a byte in any order you please and use the standard C statements to do so.

Brian Hoskins said:
"data.byte = 0x55;"
Why is this line required and what is it for?
I'm sure you've figured it out by now. I was just demoing how to access the same variable using a full byte instead individual bits.
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top