To: "Microcontroller discussion list - Public." From: "csb" > I have a register that holds a 3 bit number <0:2>. How do I put the > value of those three bit on PORTC <7:5> without changing the rest of the > bits on PORTC? It depends on what (if) you use on PORTC at the same time. It also depends on PIC family (I assume 16F?) and if read-modify-writes are not a problem and if you have a PORTC shadow file (you should). It also depends on if you can change or not the register that contains the 3 bits. This should work, assuming you have a PORTC shadow reg : movlw b'11111000' ;prepare mask in W andwf PORTC_SHADOW,F ;set your bits to 0, others stay the same. movlw b'00000111' ;prepare 2nd mask andwf SOURCE_REG,W ;keep only 3 bits. others are 0 ;now W contains clean 3 bits to set in PORTC_SHADOW. ;if interrupts are disabled, there should be no problem, else you ;might clear the GIE flag for the operation, because for a short ;while the shadow file contains a temporary value. iorwf PORTC_SHADOW,F ;bits from W get combined with the file movf PORTC_SHADOW,W ;the reason to put ',F' on the IOR above ;is to have an accurate copy of PORTC in ;the shadow file (:), can be important movwf PORTC ;update PORTC. I think this is pretty conservative, and since you know what registers you're using you can probably make this shorter. Good luck, Christian To: "Microcontroller discussion list - Public." From: "csb" OOPS- forget that, I thought you meant bit 0:2 to bit 0:2, not 5:7. You could use RLF/RRF, or figure out a way using XOR, IOR, AND, COMF,aetc. Christian To: "Microcontroller discussion list - Public." Date: Thu, 13 Jan 2005 16:50:29 -0800 Nathaniel: If you had stored the 3 bits in SOURCE bits 5-7 instead of bits 0-2, you'd have been able to do it in 4 lines: MOVF SOURCE,W ;W = SOURCE. XORWF PORTC,W ;Copy W bits 5-7 to PORTC bits 5-7. This ANDLW 11100000B ;code only works if the upper three bits XORWF PORTC ;of PORTC are guaranteed not to change ;between the two XORs. Since the data's stored in bits 0-2, though, you have to do a little more... If you have an extra register to spare, you can do it in 6 lines: SWAPF SOURCE,W ;Copy SOURCE bits 0-2 to W bits 5-7. MOVWF TEMP ; RLF TEMP,W ; XORWF PORTC,W ;Copy W bits 5-7 to PORTC bits 5-7. This ANDLW 11100000B ;code only works if the upper three bits XORWF PORTC ;of PORTC are guaranteed not to change ;between the two XORs. Without a TEMP register, you can do it in 8 lines. Unfortunately, this code glitches PORTC bits 5-7 low, and it switches the pins one at a time: MOVLW 00011111B ;Clear the upper 3 bits of PORTC. ANDWF PORTC ; BTFSC SOURCE,2 ;Copy SOURCE bits 0-2 to PORTC bits 5-7. BSF PORTC,7 ; BTFSC SOURCE,1 ; BSF PORTC,6 ; BTFSC SOURCE,0 ; BSF PORTC,5 ; The shortest way (9 cycles/instructions) that glitchlessly switches all three PORTC pins simultaneously without using any additional registers: BTFSC SOURCE,2 ;Copy SOURCE bits 0-2 to W bits 5-7. ADDLW 10000000B ; BTFSC SOURCE,1 ; ADDLW 01000000B ; BTFSC SOURCE,0 ; ADDLW 00100000B ; XORWF PORTC,W ;Copy W bits 5-7 to PORTC bits 5-7. This ANDLW 11100000B ;code only works if the upper three bits XORWF PORTC ;of PORTC are guaranteed not to change ;between the two XORs. Another way, also 9 cycles/instructions: MOVF PORTC,W ;W = PORTC. ANDLW 00011111B ;Clear W bits 5-7. BTFSC SOURCE,2 ;Copy SOURCE bits 0-2 to W bits 5-7. ADDLW 10000000B ; BTFSC SOURCE,1 ; ADDLW 01000000B ; BTFSC SOURCE,0 ; ADDLW 00100000B ; MOVWF PORTC ;PORTC = W. -Andrew To: "Microcontroller discussion list - Public." From: Dwayne Reid Many different ways to do this - here is one: movfw PORTC andlw b'00011111' btfsc register,0 iorlw b'10000000' btfsc register,1 iorlw b'01000000' btfsc register,2 iorlw b'00100000' movwf PORTC Note that you expressed the bit order in the register as <0:2>. I assume that you explicitly intended b0 to be the MSB and b2 to be the LSB. If not, swap lines 4 & 8 in the code snippet above. This also assumes that all the bits in portC react normally with regard to reads & writes. I bring this up because it is possible that certain modes in certain PICs may change the way some pins are read and written. Check the data sheet for the particular part you are using. Hope this helps. dwayne -- Dwayne Reid Trinity Electronics Systems Ltd Edmonton, AB, CANADA (780) 489-3199 voice (780) 487-6397 fax To: "microcontroller discussion list - Public." Date: Thu, 13 Jan 2005 17:31:28 -0800 I just wrote: > BTFSC SOURCE,2 ;Copy SOURCE bits 0-2 to W bits 5-7. > ADDLW 10000000B ; > BTFSC SOURCE,1 ; > ADDLW 01000000B ; > BTFSC SOURCE,0 ; > ADDLW 00100000B ; > > XORWF PORTC,W ;Copy W bits 5-7 to PORTC bits 5-7. This > ANDLW 11100000B ;code only works if the upper three bits > XORWF PORTC ;of PORTC are guaranteed not to change > ;between the two XORs. Bah, that doesn't work. All the others do, though. Sorry. -Andy try this: rlf reg,w andlw b'00001110' movwf tmp ;tmp register swapf tmp,f ;data now in right place movf portc,w andlw b'00011111' iorwf tmp,w movwf portc make sure that interrupts are OFF, otherwise PORTC might get corrupted by an event during the interrupt. --Bob