The bsf LATx issue

Thread Starter

MaxHeadRoom

Joined Jul 18, 2013
28,686
. I generally run 6 LCD pins on LATB; 4data, RS and E. Writing all togther for data means writing 6 digital outputs, writing 0 to E at that time of course.

The other two pins are the USART TX/RX
I am assuming that this also applies to PORTA where 6 pins RA0-5 are used for LCD and RA6-7 are the external Clk Xtal?
Max.
 

ErnieM

Joined Apr 24, 2011
8,377
In your case, I would do something like that:

Rich (BB code):
; assuming data are loaded in wreg with correct shift
xorwf LATx, w
andlw 0x0f    ; only changing the selected 4 bits - low nibble in this case
xorwf LATx, f
You do realize that the last statement works by using a R-M-W sequence?
 

MMcLaren

Joined Feb 14, 2010
861
In your case, I would do something like that:

Rich (BB code):
; assuming data are loaded in wreg with correct shift
xorwf LATx, w
andlw 0x0f    ; only changing the selected 4 bits - low nibble in this case
xorwf LATx, f
That's exactly the way I do it (to protect the b4..b7 bits which may be being utilized in other parts of the program). I've always assumed RMW is not an issue with a LATx register (or other non-PORTx registers). Please correct me if I'm wrong.

Cheerful regards, Mike
 

THE_RB

Joined Feb 11, 2008
5,438
I am assuming that this also applies to PORTA where 6 pins RA0-5 are used for LCD and RA6-7 are the external Clk Xtal?
Max.
Yeah it would. :) But generally I reserve PORTA for the valuable ADC and comparator inputs.

For speed and productivity I do a lot of development on my MikroE EasyPIC dev boards. They use a standard pin connect for the LCD on PORTB 0-5 for good reasons, which have been well thought out, leaving RB6,7 for USART. PORTA is valuable for ADC and comparator, and PORTC has the CCPs, SPI, etc depending on which PIC it is.

It's a rare occasion when I use different pins for things, maybe sometimes when i am forced to use a low pin count PIC.

I have never been in a situation where I thought it was a good idea to use BSF/BCF pin writing on a parallel data output! My own LCD code doesn't even use bit operation on the E pin, I handle everythign through a shadow register and the only way the port gets written to is a MOVFF instruction. The same code works fine on PIC16F and PIC18F, with the obvious difference of PORTB and LATB.
 

ErnieM

Joined Apr 24, 2011
8,377
I've always assumed RMW is not an issue with a LATx register (or other non-PORTx registers). Please correct me if I'm wrong.
The whole point of adding the latch "register" is to get around the RMW effects of directly reading port pins. 100% safe and sure
Of course. I would even say R-M-R-M-W. I don't see any problem with that because it uses LAT, not PORT.
Me neither, though there seems to be an undercurrent of opposition to this point.
 

Thread Starter

MaxHeadRoom

Joined Jul 18, 2013
28,686
Yeah it would.

They use a standard pin connect for the LCD on PORTB 0-5 for good reasons, which have been well thought out, leaving RB6,7 for USART. PORTA is valuable for ADC and comparator, and PORTC has the CCPs, SPI, etc depending on which PIC it is.
.
Sounds Good, On my development board I can assign the LCD to any port combo.
I have portB tied up with CCP capture and PWM ECCP full bridge mode, no analogue in this project. ;)
And have PortA relatively free.
In any event, the 23K22 has enough multiplexed functions that there is no real need to pin down a particular port assignment.
Max.
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
The whole point of adding the latch "register" is to get around the RMW effects of directly reading port pins. 100% safe and sure
...
I think that interpretation of "100% safe" is what separates the pros from the hobbyists?

If the code is part of a library that might be reused on PIC16F or PIC18F, then what do you do? Have one set of code that uses a MOVWF to safely write to the port in one operation on the PIC16F, but the code for the port write on the PIC18F uses a lot of clunky bsf/bcf operations? Does that seem professional to you?

If I have written a nice library that can be used on either then the only difference in the library (set by a simple #define) is this;
Rich (BB code):
PORTB = shadow_b;   // used on PIC16F
LATB = shadow_b;    // used on PIC18F
Then there are the hardware issues, which definitely affect the "100% safe" point. Have you had a design where you have had to find and fix PIC output pin latchup issues? I have. The 8 pins on a port share one BUS on the silicon, which is why the PIC datasheet has max current specs for each pin and total for the port.

Using multiple bsf/bcf writes on a parallel port exposes it to repetitive currents being sourced or sunk within 100-200nS of each other, which can cause issues with line reflections, pin latchups etc. A single write to the port in one cycle gets everything done in one instant and there are no pins being toggled while hardware line issues or PSU issues are occurring 100-200nS later etc.

Is there actually a gain from writing lots of parallel pins using bsf/bcf code? Not much when the entire goal is to write a single parallel data value (like LCD data4 and RS). Even less when needing to write parallel 8bit value!

The LAT register makes writing bits to a port MUCH safer, but I would not say it is "100% safe" and it is far from being the best way to write a parallel value out a port as a general practice.
:)
 

ErnieM

Joined Apr 24, 2011
8,377
I think that interpretation of "100% safe" is what separates the pros from the hobbyists?
Once again you start with a straw man argument.

Perhaps your compiler is not capable of conditional compilation, but mine does and I make good use of that feature. I use my own LCD library (a heavily modified version of the Microchip XLCD source code) with no issues. About the only limitation on that library is the data pins need be a continuous nibble (0-3 or 4-7). The 3 control lines can be anywhere. Heck, this code even has options to drive a 5V LCD from a 3.3V device as long as the pins are 5V tolerant.

And yeah, I sense the BUSY flag meaning I use the port as both input and output, or as some people say I both "walk and chew gum."

As it happens I have not used PIC16 devices never ever in any application where I’m driving an LCD, but if I did I'd just modify my library to arrange the code for such.

So don’t you think it’s just a tad unfair when I say something about a LATCH register to object that it doesn’t apply to a PORT register?

The LAT register makes writing bits to a port MUCH safer, but I would not say it is "100% safe" and it is far from being the best way to write a parallel value out a port as a general practice.:)
Again, extraordinary claims require extraordinary evidence. Do you have a single instance of a RMW on a LATCH register causing issues?

Or do you just have some magic way (excuse me, professional way) to write to ports that does not entail using either LATCH or PORT? Posting such would actually be helpful, as opposed to just thumping your chest.
 

NorthGuy

Joined Jun 28, 2014
611
If the code is part of a library that might be reused on PIC16F or PIC18F, then what do you do? Have one set of code that uses a MOVWF to safely write to the port in one operation on the PIC16F, but the code for the port write on the PIC18F uses a lot of clunky bsf/bcf operations?
You can just create your own LATx on PIC16F which you copy to PORTx when needed, but you don't do it on PIC18F where you already have it. Only one extra line of code is required on PIC16F.

However, for lots of the stuff, you would have different code for PIC18F, which would take advantage of its better architecture.

bsf/bcf or xor? For single bit bsf/bcf is definitely more efficient - less instructions, faster. You can do really fast - bcf/btfsc/bsf, or if you do not want cycling the pin for some reason - btfss/bcf/btfsc/bsf. It's less efficient with xor - clrw/btfsc/iorlw/xorwf/andlw/xorwf. For multiple bits at correct positions, xor certainly wins. Depends on what you need/want.

BTW: Display outputs hardly source/sink any current (probably in uA). No reason to worry about high currents.
 

Thread Starter

MaxHeadRoom

Joined Jul 18, 2013
28,686
So what is wrong with using the only 6 available bits (0-5) on portA (6-7 Xtal Osc) and output the high and then low nibble together with RW-RS using MOVFF LATA?
E to be a bsf/bcf LATx on separate port.
mAX.
 

THE_RB

Joined Feb 11, 2008
5,438
...
So don’t you think it’s just a tad unfair when I say something about a LATCH register to object that it doesn’t apply to a PORT register?
...
Although I quoted you the bulk of my text was not aimed at you specifically.

You stated that the discussion of doing multiple successive BSF/BCF operations on a LAT register was "100% safe and sure".

I countered that it is not a good general coding practice for the reasons I have brought up, (hence the "pro" comment").


...Again, extraordinary claims require extraordinary evidence. Do you have a single instance of a RMW on a LATCH register causing issues?
...
It's not the RMW itself that is the problem. The hardware is more stable and more reliable writing to an entire port in one operation. Fast successive bsf/bcf operations can cause pin latch up.

You claim to have a lot of experience, haven't you encountered this? Where doing fast successive bsf/bcf on a LAT port give you output pin latchup or incorrect output pin value, then adding some NOPs into the code stabilises it? That's a hardware issue with line refections etc. On a PIC18F at >=40MHz HSPLL I avoid back to back bsf/bcf operations like the plague!

And I believe it's worse now on the new process PICs that have the reduced pin and port current specs. The pin output drivers are much smaller and less capable, and more fussy regarding what they drive.


MaxHeadRoom said:
So what is wrong with using the only 6 available bits (0-5) on portA (6-7 Xtal Osc) and output the high and then low nibble together with RW-RS using MOVFF LATA?
E to be a bsf/bcf LATx on separate port. ...
That's a great way to do it. You can also have E on the same port, and MOVFF again to set E high, and then again to clear E. That is how I generally do it. All 6 required LCD pins on one port.
 
Last edited:

Thread Starter

MaxHeadRoom

Joined Jul 18, 2013
28,686
After writing the code for the routine to output to the LCD, the results were not there so tracking the problem I ended up just connecting a discreet 8 LED board in place of the display.
I have a routine (shown) that is called with the data in the temp_wr location.
Using the trace and watch screen, I found that each time it is called some data was OK some missing bits.
Attempting to trace the problem, I have the routine only loaded and running as a simple program and loaded the data from 1 to F and compiled each time.

All the registers and locations in the Watch screen show correct, LATA etc.
The 4 data output LED's show below for the corresponding data word sent.
1 = 0000
2 = 0000
3 = 0011
4 = 0100
5 = 0100
6 = 0100
7 = 0111
8 = 1000
9 = 1000
A = 1000
B = 1000
C = 1100
D = 1100
E = 1100
F = 1111

Rich (BB code):
;Called with byte in temp_wr, e.g. 0xc0
LCDWriteNibble:

        bsf        LCD_E            ; Setup to clock data
        swapf    temp_wr
        btfss     Flags, 7
        bcf        temp_wr, 4    ;LCD_RS
        btfsc     Flags, 7
        bsf        temp_wr, 4    ;LCD_RS
        bcf        temp_wr, 5    ;LCD_RW
        movff     temp_wr, LATA
        NOP
        NOP
        bcf        LCD_E            ; Send the port data

        return
Port A bits 0-3 data, RA4 - RS, RA5 - RW ,, RC3 - E

Never had so many problems as this with other 18f Pic's!

Anyone any ideas?
Max.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Late to the party here but according to the HD44780 datasheet, LCD_E should be LOW when changing RS,R/W,data etc. Set up the data then strobe E for 1us minimum. You're changing things with E high.

Presumably, you've visited all of the setup registers associated with port A (ASNSEL, CMxCON, VREFCONx and others called out in table 10-2 and 10-3 of the datasheet). See table 10-4 too.

Don't use bsf/bcf to set TRIS registers.

Good luck.
 

Thread Starter

MaxHeadRoom

Joined Jul 18, 2013
28,686
But I am not outputting to a LCD at the moment, it is straight LED's with a 1k res.
So the E strobe is not part of it.
The thing that gets me is the register and port show the correct value with Watch screen when stepped through, and if I read the status of the TRISA back it shows correct?
Max.
 
Last edited:

NorthGuy

Joined Jun 28, 2014
611
Perhaps pin 0 and pin 1 on PORTA are shorted?

If not, I would start with something very simple:

clr LATA
bsf LATA,0

and see the results

Then re-comple with

clr LATA
bcf LATA, 0

Then re-compile with

clr LATA
bsf LATA, 1

and so on with all 4 LEDs

and see if they work as expected and there's no "cross-talk".
 
Top