Share

Small Device C Compiler

Tracker: Support Requests

5 PIC14-PIC16 bitwise manipulation of registers and variables - ID: 2897090
Last Update: Comment added ( tecodev )

Hi
I am comming from CCS and GNUAVR, and I am missing some background about
how to manipulate bit-level registers or variables.

Typically, the pic has the ASM functions such as BCF, BSF, BTFSC, BTFSS.

I currently only see a solution to read a full byte (register or variable)
to set or clear or test a bit, for set or clear write it back to the right
place.
Also I would like to not only set or clear a given bit, ie RA1 or RA2, but
make this variable.
Ie, I want to have a routine that sets or clears a bit 1,2,3,4... in a
raw.

In GNUAVR, I know the _BV function, in CCS, you find
BIT_SET(reg+var/reg,bit), BIT_CLEAR(reg+var,bit), BIT_TEST(reg+var,bit).

is this a missing function in SDCC ?

Thanks for any help.


z-control ( z-control ) - 2009-11-13 09:21

5

Open

None

Nobody/Anonymous

None

None

Public


Comments ( 3 )

Date: 2009-11-13 14:59
Sender: tecodev

What does "does not work" mean?

If all the PORTB-pins are 0, you might not have set them up as digital
pins. Try
ANSEL=ANSELH=0;
before modifying the register (ANSELH is the important one for PORTB, see
datasheet):
If you assign tmp to PORTB, the hardware overwrites all bits and you are
fine.
If you clear individual bits, the hardware executes read-modify-write and
-- unfortunately -- all pins read as 0 when configured as analog inputs
(the power-on default, ANSEL=ANSELH=0xff).

BTW: If you want to specify the bit to modify at runtime, the hardware
cannot use BCF/BSF/BTF/... because these require a literal (compile-time
constant) bit index. The compiler will generate a loop for (1 << (BIT)) and
modify the PORT via IORWF or ANDWF instead.


Date: 2009-11-13 12:00
Sender: z-control

thank you for the input, I must make something wrong as I tried your code
couple of days ago. I just checked again and copied the 2 options I had out
of an interrupt routine:
...
#define BIT_SET(VAR, BIT) VAR |= (1 << (BIT))
#define BIT_CLR(VAR, BIT) VAR &= ~(1 << (BIT))
#define BIT_TST(VAR, BIT) ((VAR) & (1 << (BIT)))
....
if(++raw==8)raw=0;
tmp=0xff;
tmp=tmp ^ (1 << raw); // enable led raw (active low)
PORTB=tmp;
//the above code works, each bit of PORTB gets 0 in a raw.
// but with your macro it would be simpler but that does not work !
// is it only limited to variables and not to registers ?
PORTB=0xff;
BIT_CLR(PORTB,raw);
// should do the same, but does not work
// I am using a 16f887

P.S. with VAR/REG I ment applicable to variables and PIC registers within
SDCC.



Date: 2009-11-13 10:31
Sender: tecodev

Hi,

you can use

#define BIT_SET(VAR, BIT) VAR |= (1 << (BIT))
#define BIT_CLR(VAR, BIT) VAR &= ~(1 << (BIT))
#define BIT_TEST(VAR, BIT) ((VAR) & (1 << (BIT)))

SDCC will automatically replace single-bit accesses with the
bit-manipulation instructions offered by the target architecture.

I do not know what 'reg+var' is supposed to mean, but the above should get
you started.

Best regards


Raphael


Attached File

No Files Currently Attached

Changes ( 4 )

Field Old Value Date By
status_id Pending 2009-11-13 12:00 z-control
close_date 2009-11-13 10:31 2009-11-13 12:00 z-control
status_id Open 2009-11-13 10:31 tecodev
close_date - 2009-11-13 10:31 tecodev