From: SourceForge.net <no...@so...> - 2009-11-13 14:59:41
|
Support Requests item #2897090, was opened at 2009-11-13 09:21 Message generated for change (Comment added) made by tecodev You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=200599&aid=2897090&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Priority: 5 Private: No Submitted By: z-control (z-control) Assigned to: Nobody/Anonymous (nobody) Summary: PIC14-PIC16 bitwise manipulation of registers and variables Initial Comment: 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. ---------------------------------------------------------------------- >Comment By: Raphael Neider (tecodev) Date: 2009-11-13 14:59 Message: 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. ---------------------------------------------------------------------- Comment By: z-control (z-control) Date: 2009-11-13 12:00 Message: 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. ---------------------------------------------------------------------- Comment By: Raphael Neider (tecodev) Date: 2009-11-13 10:31 Message: 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 ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=200599&aid=2897090&group_id=599 |