LCD will not release Port B lines

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

LCD will not release Port B lines

Post by echase »

I am having great trouble getting my PIC to recognise button presses despite the simulation working perfectly. I have 16F886 Port B4-7 connected to the LCD data lines and also to 4 push buttons.

Besides the weak pull-up problem posted elsewhere, a more serious problem is I think that Port B, after it sends data to the LCD, does not rapidly, or at all, switch back to being an input port again.

My hour setting routine is:-

Upon upper nibble port B interrupt go to macro as follows:-

Read the byte on port B upper nibble to decide which switch is pressed.
Got to another Macro:-

Clear LCD
Write string ’Hour’ to LCD
Depending on the button value from previous macro increment or decrement hours
Move cursor to second LCD line
Display the hour varaible
Loop for ever (for test purposes only)

Having checked the PIC and button pins with an oscilloscope I am fairly sure that the problem is that, after a command to the LCD, Port B remains in a state where it is an output, but with all lines low. Thus when a button is pressed it can not raise the voltage on that pin to 5V. Thus the interrupt does not sense a port B change.

To get around this I tried a dummy ‘Read port B’ after every LCD line to try to force the port into being an input as per :-

Clear LCD
Write string to LCD
Read port B
Depending on the button value from previous macro increment or decrement hours
Move cursor to second LCD line
Display the hour
Read port B
Loop for ever (for test purposes only)

But not quite clear if this works as it completely messes up the LCD display and I get garbage or blanks on it mostly now even though teh simualtion continues to work fine. Maybe it nneds some time delays between commands.

How do I force port B out of its output mode until the next time it needs to send LCD data (about evey 1-6 seconds)?

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

If one button is pressed the port in the simulation returns a value of 16, 32, 64 or 128. But in the PIC it’s returning 240 all the time irrespective of the button pressed. This looks suspiciously like all buttons pressed permanently maybe due to the weak pull-ups, even though I thought I had have disabled them.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: LCD will not release Port B lines

Post by Benj »

Hello

To force PortB to be an input you just have to use an input icon on PortB. Your LCD will become corrupted if you are toggling the Enable input whilst converting between an input and an output. Maybe you could try using masking on the input icon to only convert the pins with switches to an input. Also before you do another LCD command it may be wise to set the pins to output mode again by using an output icon and masking.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

I am not using the LCD enable line as an input, only data lines 1-4. And I have used masking in all cases to only look at the top nibble.

Not clear how it can be returning 240 for top nibble = 1111 when the oscilloscope shows the PIC port B pins to be always low apart from some short pulses every second or so to send data to the LCD. Only way I can think is that there is a read port B command hidden in/immediately after those pulses and that the weak pull-ups pull the lines to 5V even though I though I had turned the pull-ups off.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

Do I have to use an LCD start command after every time I change port from input to output and back again? Or is once at beginning of code adequate?

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: LCD will not release Port B lines

Post by Benj »

Once at the beginning should be adequate. Just make sure that your E line is stable and not being converted to an input and the LCD should remain fairly stable.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

So are you saying that the LCD start command puts a high on the enable (E) line and it remains high even after the LCD has cycled through a data read cycle on its otehr inputs? And that as long as I never change that pin to an input (which I do not need to), the initial Start command keeps that line permanently high (until a reset happens)?

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: LCD will not release Port B lines

Post by Benj »

Hello

No the E line is not kept permanently high but it is used to clock data into the LCD. Therefore if this pin is allowed to be set to an input (ie if masking is not used with the input icon) then your LCD may get corrupted by the switch values.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

Ah, I see, thanks. Of course pressing a button on the data lines corrupts the screen too as the correct data bits are not received by the PIC. But it is temporry corruption corrected on next data write.

Instead of putting a port B read command after every group of LCD commands what about putting the port B interrupt on change command there? ( At moment this is run once only at beginning of code.) Will this set the port back to an input again? It’s a masked interrupt that only reacts to upper nibble.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: LCD will not release Port B lines

Post by Benj »

Hello

You could use the PortB interrupts however you would still need to switch between input and output. Eg the LCD start routine sets the pins to output mode. The interrupt enable sets the pins to input mode. Eg so subsequent LCD macros would not get through without converting the port back to an output or calling the start routine again.

The easiest way would be to use the interrupt for a single part of your program eg once the LCD has been updated etc, Wait a while for the interrupt eg a few ms and then disable the interrupt and reset the port to output mode and continue updating the display. Or if you want the functionality throughout your program then use a software macro to do the switching and waiting for you.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

So to get that clear you are saying that the LCD command sets the port to an output and overrides the interrupt, so it can’t then read my switches with the interrupt. So I have to reset the port to an input after every group of LCD commands with a dummy port read command. Is that right?

Wish I had never put the LCD and switches together on Port B. But too late now as pcb designed.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: LCD will not release Port B lines

Post by Benj »

Hello Echase

What I would do is the following. In your LCD component C file in the Flowcode V3/Components directory at the beginning of every function add the following line of code:

Code: Select all

trisb = trisb & 0x0F;       //Sets the high nibble to an output
Then at the end of every function (but before the final return statement if there is one) write

Code: Select all

trisb = trisb | 0xF0;       //Sets the high nibble to an input
This will do all the conversion for you and it may allow the port change interrupt to work. This means that you do not need dummy input icons and you should be able to just read in the data when you need to (eg when the interrupt is triggered). Basically I would create a small v simple program to test this out as I do not have the hardware to hand to give it a go.

PS it may be wise to create a backup of your LCD C file first so you can revert back for other programs or projects.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

Great, that mod to the LCD file works. Suggest you make it a permanent feature of Flowcode but generalise it to the whole port and not just the upper nibble. Not sure if it would have adverse side effects though.

To get my buttons to work with the LCD I had to do this mod AND reduce my resistor values to defeat the weak pull-ups AND connect the port direct to the LCD (not via resistors) even though, when you have an ICSP port connected to Port B, you are recommended to have resistors. In practice it does work without the resistors, although my supply current has probably gone up a bit.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

I guess you can’t generalise the command as it depends on what lines the LCD is connected to.

Does trisb = trisb & 0x0F; simply turn it into an output with the lines tristated (neither high nor low)? Or does it output a fixed value like 0000?

I still get some corruption of the display if buttons are pressed for longer than normal so have to add a periodic LCD Start command to reset it.

User avatar
Steve
Matrix Staff
Posts: 3422
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: LCD will not release Port B lines

Post by Steve »

Setting a bit in TRISx to 0 will set the pin to be an output. And the pin will then be outputting 1 or 0 depending on the value in the PORTx register.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

Good thing these forum posts are kept for a long time. After reloading my PC's software I lost the modified LCD file and had to go back to this thread to work out what to do again. However I can’t remember it all.

The attached is my new modified file but it does not work well as it produces lots of corrupt characters on the LCD (and some good ones) and the buttons do not appear to be working stil. So have I put the added lines in the right place, e.g. I don’t understand Ben’s statement “but before the final return statement if there is one”? Are the { brackets in the right place on the last modified line?

I have only added the statements onto the functions that write characters to the LCD . Should I add them to the Start function etc. as well?

I had upgraded the Flowcode a little to v3.6.11.53 when I reloaded the software. Is this likely to have changed the way this LCD file works? Was the LCD file changed around this time?

The fcf file I am using is the old one that did work with the lost modified LCD file.
Attachments
LCDDisplay_Code.c
Modified to add trisb = trisb & 0x0F statements
(7.94 KiB) Downloaded 264 times

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

Pls ignore last post. I realised that by looking in an old C file of my complete programme I could find a copy of the original modified LCD C code. From this I find that I had added some more lines beyond the trisb ones, as follows:

portb = portb & 0xF0; //Clears the high nibble of the port ensuring the E is not high when the outputs are enabled
trisb = trisb & 0x0F; //Sets the high nibble to an output
clear_bit(intcon, GIE);

ORIGINAL FUNCTION

trisb = trisb | 0xF0; //Sets the high nibble to an input
set_bit(intcon, GIE);

Not sure what I meant by “E” in the comment. The clear_bit(intcon, GIE) lines disable the port interrupt during the execution of the LCD function so that if I press a button whilst the LCD is being written to the button does not corrupt the LCD data.

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: LCD will not release Port B lines

Post by Spanish_dude »

echase wrote: portb = portb & 0xF0; //Clears the high nibble of the port ensuring the E is not high when the outputs are enabled.
This doesn't clear the high nibble but the low nibble. ( X & 0 = 0 )

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

So what would clear the high nibble or both low and high?

I think E may refer to the Enable line of the LCD. I may be trying to ensure there is not a spurious data bit on the E line that would enable the LCD before the actual LCD function calls it.

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: LCD will not release Port B lines

Post by Spanish_dude »

If you want to clear the high nibble : portb = portb & 0x0F
If you want to clear the lower nibble : portb = portb & 0xF0
And if you want to clear the whole port : portb = portb & 0 or portb = 0 should do it.

echase
Posts: 429
Joined: Mon Jun 11, 2007 11:55 am
Has thanked: 49 times
Contact:

Re: LCD will not release Port B lines

Post by echase »

I looked at the C code for the MIAC which also shares PIC pins between the LCD and buttons. It does not appear to need this same modification to the LCD code. So I am not entirely sure why I need to. The MIAC uses a matrix array of switches whereas I used a simpler arrangement of direct connection of one switch to one pin. That may account for the software difference.

Post Reply