How to manipulate one bit in a register?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to manipulate one bit in a register?

3,679 Views
fredycolombia
Contributor I
Hi,
I have a little trouble.
I need to change one bit  in  one register on my program,  if that bit is zero chage to one a vice-versa.


#include <hidef.h>
#include "derivative.h"
int dato;                 
DDRA=0x00;
PTA=dato;

how I can ask about seven bit y my variable "dato" and change only that bit?
 I have tried to use this:

asm bclr 7, dato          //if I use this, I have a mistake when a compile   ( "invalid opcode or ":" expected)


also I try with this:

DDRA=0x00;          //first port as input
dato =PTA;            
change();


void change (void){
 

 DDRA=0xFF;      //then por as output
 PTA=dato;
 
        if (PTA_PTA7==1){
        PTA_PTA7=0;
        dato=PTA;}
         else{
             if (PTA_PTA7==0){
             PTA_PTA7=1;
             dato=PTA;}
              else{}
             }
          dato=PTA;
         
}

When I simulate this program  it works,  but I think there isn't to useful and so complicated   ¿I can manipule only one bit in the variable "dato"?


thanks for your answers.

Regars,
Fredy


Labels (1)
0 Kudos
Reply
8 Replies

1,557 Views
JimDon
Senior Contributor III
PTA_PTA7 ^= 1;   // XOR with a 1 toggles a bit
0 Kudos
Reply

1,557 Views
Ake
Contributor II
Hi,
To set a bit use
 
PTA_PTA7 = 1;
 
To clear it, use
 
PTA_PTA7 = 0;
 
Regards,
Ake
0 Kudos
Reply

1,557 Views
fredycolombia
Contributor I
hi,
that's ok, but  can I manipulate bit by bit over my variable "dato" ?
I don´t need manipulate  bits on  porta, I need manipulate bits  on  "dato"
 
Is this posible?
 
Regards
Fredy
 
 
0 Kudos
Reply

1,557 Views
bigmac
Specialist III
Hello Fredy,
 
Your line of code -
  asm bclr 7, dato
 
The error occurred because the BCLR instruction will only work for variables that reside in page 0.  In all probability the variable dato will reside in DEFAULT_RAM, which is generally not page 0.  The variable would need to be specifically assigned to MY_ZEROPAGE section.
 
For the variable to remain at the present location, it is possible to use a mask value instead of the bit number.-
 
To clear bit-7,
  dato &= 0x7F;
 
To set bit-7,
  dato |= 0x80;
 
To toggle bit-7,
  dato ^= 0x80;
 
Alternatively, you could create a bit field for the variable, but this is more complex.
 
Regards,
Mac
0 Kudos
Reply

1,557 Views
fredycolombia
Contributor I
hi again,
 
That's a  great solution and very easy,  about your alternative, I have tried that, but  It really be complex.
 
 
Thanks for your help.
 
P.D. Can you help me  about  how I can use the correct location (zero_page), when  I use instructions like  "asm bclr 7,dato"
0 Kudos
Reply

1,557 Views
bigmac
Specialist III
Hello Fredy,
 
The following assumes that MY_ZEROPAGE is appropriately defined within the Project.prm file -
 
#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE
byte dato;
#pragma DATA_SEG DEFAULT
 
Further to my previous post, you might consider use of the following macros that allow any bit to be manipulated.  They should not be dependent on the variable location.
 
#define set_bit(bitnum,reg)  ((reg) |= 1<<(bitnum))
#define clr_bit(bitnum,reg)  ((reg) &= ~(1<<(bitnum)))
#define togl_bit(bitnum,reg) ((reg) ^= 1<<(bitnum))

To set bit-7 of dato, you would use the following line -

set_bit(7,dato);

Regards,
Mac

 



Message Edited by bigmac on 2008-02-06 01:26 PM
0 Kudos
Reply

1,557 Views
fredycolombia
Contributor I
thanks bigmag,

Is interesting to know how I can do that things, your really help me a lot.
again... thanks.


regards,

Fredy
0 Kudos
Reply

1,557 Views
JimDon
Senior Contributor III
Yes,

XOR Function
   | 0 | 1 |
------------
0 |  0 | 1 |
------------
1 |  1 | 0 |
------------

Where ever there is a 1 it will invert.
data  = 0x5;  // 0101
data ^= 0xf;  // 1010 4 bits Inverted.

If you plan on being  a coder, you should read and understand this:
Boolean Logic

0 Kudos
Reply