electronics forum

Rules | Recent posts | topic RSS | Search | Register  | Log in

PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Goto page 1, 2  Next
Post new topic  Reply to topic    EDAboard.com Forum Index -> Microcontrollers -> PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)
Author Message
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post15 Sep 2009 13:33   

keypad 4x3


I am using a Basic to program.
I will describe my problems:
1) When I try to "Print" or "LCDOUT" a decimal, it will convert to HEX value and then "referring to LCD character table" supposed to display something? say like 6...
BUT my LCD would display something I can't understand on the first character or display (first small box I guess) and then only the outcome you want...
Any idea?

PIC16F84A has extremely limited space, so I basically had not enough spots to use my keypad of 4X4 so I did not connect one of the Columns to make it a 4X3. Reason: One of the pins are used for Enable (E) for LCD. *This is PORTB*

For PORTA, Pin 0 to 3 are D4-D7 (LCD) and Pin 4 is Register Select (RS).
R/W is connected to ground to make it read from PIC.

I am not sure if it is the LCD problem or Keypad.
The program works okay IF I use:
Print AT 1,1,"6" or something like that along the lines, anyway the point is, without 'at 1,1,...' it would show rubbish for the first box then only ur result..
I have been trying to make it display my keypad while holding a key so it would display something like "1111111111111111" but I don't know, it just prints out rubbish...

Any ideas?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post15 Sep 2009 16:04   

pic16f84a lcd


I can't help you with a BASIC program, I never use it but what you are asking for sounds fairly easy to do in assembly language so it might be translatable to BASIC.

The 16F84A has 12 I/O pins. You can use 4 pins to drive the LCD data lines and the keypad columns, 1 pin for the LCD RS, 1 pin for the LCD E and 4 pins to read the LCD rows. That gives you a full 4x4 keypad and 2 pins spare.

The LCD will only update when the RS and E pins tell it to, so you can put the keypad scan signals out when the LCD is not being updated.

It sounds like your problem at the moment is the LCD is not configured properly though.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post15 Sep 2009 23:50   

jhd 162a lcd connection


betwixt wrote:
I can't help you with a BASIC program, I never use it but what you are asking for sounds fairly easy to do in assembly language so it might be translatable to BASIC.

The 16F84A has 12 I/O pins. You can use 4 pins to drive the LCD data lines and the keypad columns, 1 pin for the LCD RS, 1 pin for the LCD E and 4 pins to read the LCD rows. That gives you a full 4x4 keypad and 2 pins spare.

It sounds like your problem at the moment is the LCD is not configured properly though.

Brian.

Yeah I think I can change .asm files to .bas since I can write both and yes it is fairly easy to do.

I don't get what you mean. 10 pins to 16F84A then where to do I connect the keypad to? O_o I do not know how to connect / program a multiplexer. I only used D4-D7 lines from LCD to 16F84A.

Yeah it could be not configured properly, I'm not too sure.
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post16 Sep 2009 0:25   

keypad look up table e


You connect the data lines to the LCD to the keypad as well.

Multiplexing just means using the data pins for two purposes, you scan the keypad columns while looking for signals returned from the rows, then if any key was detected, you use the same outputs to write the character to the LCD.

The LCD will ignore the port being used to send the scan signals unless you also toggle to 'E' signal. To scan the keypad, don't change the 'E' signal so the LCD doesn't update. When writing to the LCD, ignore the signals back from the keypad.

So you use the four data lines for two purposes to save pins.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post16 Sep 2009 15:28   

jhd 162a how to test


betwixt wrote:
You connect the data lines to the LCD to the keypad as well.

The LCD will ignore the port being used to send the scan signals unless you also toggle to 'E' signal. To scan the keypad, don't change the 'E' signal so the LCD doesn't update. When writing to the LCD, ignore the signals back from the keypad.

So you use the four data lines for two purposes to save pins.

Brian.


Okay so the rough picture is:
You have D0-D7 of LCD AND the 4 Columns and 4 rows connect to PORTB of 16F84A, am I right? -
[IF possible, can you draw out this part for me please? If not, writing it is fine. ]

So how do I write for this in asm?
Well I know how to 'scan' in Basic but to write it in asm....*Just use the function called INKEY for PICBasic Very Happy*

Thanks for assisting, by the way.

Shinn.

* Side note: I tried today using USB-to-Serial and connect to PIC to display on LCD to check if it would display rubbish on the first key sent through laptop and it wasn't so I'm guessing it's either the connection or the scanning of keypad is incorrect.
Since my 'E' is current in PORT B last pin, I was wondering if that played a role in messing up while scanning the keypad.
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post16 Sep 2009 16:23   

mplab ide 8.36 pic16f84a


The more I see BASIC, the more I realize how deficient it is!

Yes, you are right about PORTB feeding the 4 data lines to the LCD and the keypad as well.

There are several ways to read a keypad but the most common way is to 'scan' it, the procedure is:

1 Set the port data bits to output mode. Set the row pins to be inputs.
2. You have 4 data bits connected to the columns, think in binary and set the data lines to 0001.
3. Read the row inputs (could be the other half of port B or it could be port A)
4. If 0000 is read back, no keys in the column with '1' on it were pressed, if any bit is '1', it corresponds with the key at the intersection of that row and column so you can tell what it was.
5. Change the column output to 0010 and repeat step 4.
6. Change the column output to 0100 and repeat step 4.
7. Change the column output to 1000 and repeat step 4.

So you are walking a '1' across the columns and then reading the rows. When a key is pressed, it shorts one row to one column so at some point that '1' will appear on the row inputs. For example, on a standard 4x3 telephone keypad, pressing the '5' key would give an output on row 2 when column 2 was driven.

If a key was pressed, your next step is to feed the appropriate data for the LCD on to the data lines, ignore anything on the row inputs, and toggle the LCD 'E' line to write the data to the LCD module. You can then go back to scanning the keypad again.

Make sense?

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post17 Sep 2009 0:40   

jhd 162a commands


betwixt wrote:
The more I see BASIC, the more I realize how deficient it is!

Yes, you are right about PORTB feeding the 4 data lines to the LCD and the keypad as well.

There are several ways to read a keypad but the most common way is to 'scan' it, the procedure is:

1 Set the port data bits to output mode. Set the row pins to be inputs.
2. You have 4 data bits connected to the columns, think in binary and set the data lines to 0001.
3. Read the row inputs (could be the other half of port B or it could be port A)
4. If 0000 is read back, no keys in the column with '1' on it were pressed, if any bit is '1', it corresponds with the key at the intersection of that row and column so you can tell what it was.
5. Change the column output to 0010 and repeat step 4.
6. Change the column output to 0100 and repeat step 4.
7. Change the column output to 1000 and repeat step 4.

So you are walking a '1' across the columns and then reading the rows. When a key is pressed, it shorts one row to one column so at some point that '1' will appear on the row inputs. For example, on a standard 4x3 telephone keypad, pressing the '5' key would give an output on row 2 when column 2 was driven.

If a key was pressed, your next step is to feed the appropriate data for the LCD on to the data lines, ignore anything on the row inputs, and toggle the LCD 'E' line to write the data to the LCD module. You can then go back to scanning the keypad again.

Make sense?

Brian.

Nice. I didn't think about that. *I mean the LCD with Keypad.*
:]
Was seeing too many examples of PIC16F877A which seperates them with different Ports.

Okay, you mentioned 4 Data Lines of LCD to PortB. Do I ignore the other 4?

Oh and another question, how do you toggle the 'E'? So I'm guessing you toggle E to write, display the key you want, toggle E again?
Back to top
Google
AdSense
Google Adsense




Post17 Sep 2009 0:40   

Ads




Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post17 Sep 2009 8:49   

pic16f84a lcd 4 line


You need 8 bits to use a 4x4 keypad, 7 if you use a 3x4 keypad so either use all of port B or use some of port A, it is up to you, the software can use any of the pins.

Probably the easiest way to do it is to assign port B bits 0-3 to the LCD data and keypad columns and port B bit 4-7 to the keypad rows. you can then use port A for the LCD control signals.

When using the LCD in 4-bit mode you have to toggle the 'E' line twice per character so it can tell it to read the top and bottom 4 bits of the data byte. Check the LCD data sheet to see how it is done. You are also not using the LCD R/W pin so you have two methods of checking if the LCD is ready before sending the data to it. You can either wait for a few mS (check data sheet) between writing high and low half-bytes or you can reverse the pin direction of the PIC connected to D7 of the LCD after writing to it, then waiting for it to go low before moving on. The LCD sets D7 high while it internally digests the data then drops it again when it is ready to receive more.

Personally, I always read D7, it is much faster and safer than using fixed delays every time the LCD is used.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post17 Sep 2009 12:42   

how to write to lcd pic16f84a


Okay I really feel like it's my first time touching electronics right now. Haha.

Simply put, I must be posting this in the wrong section Razz. Newbie section was more accurate haha.

Anyways, I think I'm pretty sure with the hardware, now just programming...
I have absolutely no idea how to write this in asm. At all.
Well basically I don't know how to program LCD at all in asm. First time dealing with LCD with asm. How did I program with PICBasic? It was because there was a help program, hehe. I just follow the help examples which made things pretty easy. But if there were changes like this, then it'd be a bit tough, I guess.

And thanks for the tip on D7, I'll keep that in mind. Wait a minute, so I refer to D7 to know when to toggle E? Interesting.

Yes I know I need to use 8 bits for 4x4 keypad, I was referring to the 8 data lines for LCD. Do I use D0-D3 or D4-D7?
Well in this case, I'm going to take the guess it's D4-D7.

Thanks for the help by the way, it really helps me to understand the LCD better.

By the way do you have a link to write LCD with asm ?
Sorry for the inconvenience. If I really can't write in asm then I'll just write with PICbasic if I have to.
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post17 Sep 2009 13:37   

key pad pic 16f84a


The LCD can be used in two ways, one way uses all 8 data bits and you toggle the 'E' line once to transfer the whole byte in one go. The other way is to use only D4-D7 and transfer the data in two 4-bit parts so you toggle 'E' twice, once for each half of the data. You are using 4-bit mode so either leave D0 - D3 unconnected, or better still, connect them to the positive supply through a 10K resistor.

Programming is asm can be frustrating but the MPLAB assembler is very good and it includes an excellent debugging tool. You will find asm programming gives you far better control over what the processor does and when you are familiar with it, you can write smaller and faster running programs than is possible with BASIC or 'C'.
For example, I have recently written an asm program for producing TV test signals in 130 bytes on a 10F202 chip. It would be impossible to do that in any other language.

I have looked but at the moment I do not have any LCD routines on my computer, they are all archived and it would take me some time to find them. A good place to look is on Microchips own forum which has an LCD software section at:
http://www.microchip.com/forums/tt.aspx?forumid=38

but please read the other peoples posts before adding your own. The moderators do not take kindly to "send me the software right now" posts but they will be very helpful to people who try to help themselves first.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post17 Sep 2009 15:25   

jhd162a enable


Ah, thanks I will look into it now.


Hmm, a lot of C users..
Nevermind Very Happy

Added after 1 hours 29 minutes:

I think I saw this one in one of the LCD manuals before [How to use Intelligent LCDs] and,
I noticed this is for D0-D7, So I am guessing I need to make changes for 4 pin D4-D7.
E toggling as well.



Sorry, but you need login in to view this attachment

Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post18 Sep 2009 14:44   

14 pin jhd162a


That is a HORRIBLE mess of a program. Please don't even think of using it.

My guidelines:
1. look closely at the data sheet for the LCD, it tells you how to configure it to work in 4-bit or 8- bit mode and what bytes to send it to set the cursor, blank the screen and so on. you have to do this before you can use the LCD to display messages.

2. Get hold of MPLAB from Microchip's web site, the current version is 8.36.

3. Use the MPLAB wizard to set up your project, it will ask you things like the clock speed (crystal frequency) you want to use and the kind of microprocessor, obviously pick 16F84A from the list.

4. Click on 'File/New' (or the first icon on the top row) to create a new file.

5. Copy the contents of the file "16F84ATEMP.ASM" into it. This is a template file which you can use as a starting point. You will find the file in the folder:
C:\Program Files\Microchip\MPASM Suite\Template\Code.

6. "save as" the file with the name you want to give it. End the name with '.asm'

7. Now you can edit the top of the file to add a description, your name and other notes.

8. Give meaningful names to the pins on the chip using the '#define' directive.
For example you might have a line "#define LCD_RS PORTA,1" which lets you use the descriptive name LCD_RS instead of remembering which pin on port A you are using. Make a list of all the pins near the top of the program. You can now use commands like "bsf LCD_RS" to set the LCD's RS line high.

9. PIC registers are banked which is a problem until you understand it so for now, whenever you refer to a different register, put the line "banksel xxxx" in the line before it. Change the xxxx to the register name, this will tell the assembler to sort out the banking for you.

10. That's it ! Start coding !

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post18 Sep 2009 15:07   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Okay thanks for the guidelines but before that,
what is the initial status of 'E' ?
and for the ROW reading inputs... Is it better to use BTFSC or AND ?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post18 Sep 2009 17:22   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


I think the 'E' line is normally low. If I remember correctly, the data is latched into the LCD on the falling edge of the 'E' signal so it should be safe to set the data pins first then make 'E' high then low again. Don't forget to read D7 from the LCD and wait for it to go low before writing the next data. D7 is used as a 'busy' indicator and the LCD will hold it high while it performs internal operations, when it goes low it means it is ready to use again.

For reading the rows, you can use either method but the shortest routine is to read the port and use the value to look-up the key number in a table. It is easier to do this if you use the lower part of PORT b as the inputs. What you do is read the port and immediately return if the value is zero because that means no keys is pressed. If the value is not zero, a key is pressed and the port will read 1, 2, 4 or 8 depending on the row that had the '1' on it.

Load the value into the W register then call a subroutine with something like this in it:
Code:

addwf PCL,f  ;add the value in W to the program counter.
retlw '0'  ;key in row 1 found
retlw '8'  ;key in row 2 found
retlw 'x'
retlw '5'  ;key in row 3 found
retlw 'x'
retlw 'x'
retlw 'x'
retlw '2'  ;key in row 4 found


If you called that subroutine 'Column 2' and call it when the second column has the '1' on it, it will return with the key number in W. Simple as that !
The 'x' entries are just space fillers, as the rows can only return 1,2,4 and 8, they should never be reached.

Use four different subroutines, one for each column and put the appropriate key numbers in the retlw instructions.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post19 Sep 2009 3:45   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Ah thanks,
but I don't really understand for the row reading.
"lower part of the PORTB" , you mean the last 4 pins or the first 4?
Why add it to program counter? NeutralQuestion
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post19 Sep 2009 9:39   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Sorry for not being clear, I mean the lowest numbered bits, 3,2,1 and 0.

If the row inputs are on the higher nubered bits 7,6,5 and 4, when you read the port you must store the result in a register (I'm calling it 'KeyPadIn' in my example):
Code:

movf PORTB,w   ;read the whole port B
movwf KeyPadIn  ;save the value read in
swapf KeyPadIn,w  ;swap top and bottom bits so b7:4 is now b3:0
andlw h'0F'  ;zero the top bits so only the row data is now in W register


If the rows inputs are connected to PORT B bits 3 to 0, the code is a little simpler:
Code:

movlw h'0F'  ;this will be used to mask the top bits of the reading
andwf PORTB,w  ;read and mask PORT B with the result put in W


There is a neat trick in the PIC 10, 12 and 16 series to implement look-up tables. The PIC18 series has it's own method but that isn't important here.
The trick is to use the 'retlw xx' instruction which means "return from subroutine with the value xx loaded in the W register". Returning from a subroutines is exactly the same as you have used in BASIC so you have to make a call to the routine first.

Imagine your subroutine is called 'MySubroutine' and in your program you placed the instruction 'call MySubroutine'. The program counter is saved so it knows where to return to when the subroutine ends, then the program counter is loaded with the subroutine address so it starts running the next instruction from the subroutine itself. In other words, PCL (and possibly paging bits) holds the address at the subroutine. If you add the value in the W register to it, the program counter will pick up the next instruction 'W' places further along the program. Adding the value in W is like saying jump ahead 'W' places.

After the 'addwf PCL,f' instruction you place a list of retlw instructions, each followed by the value you want to return. When the program jumps ahead, it 'lands' on one of the retlw instructions, loads the xx value into W and returns from the routine. This leaves you back in your main program with the value in the retlw table in W instead of what was there before. For example if W contained the value 5 and the subroutine was called, it would return with the value in the 5th retlw instruction. So you have a quick and easy look-up table, enter with the position in W and return with the value for that position in W.

The only thing to be careful of is that your look-up table doesn't cross a page boundary in memory as the addwf PCL instruction only works on the PCL register, it doesn't switch to the next memory page if PCL is made to count beyond h'FF'.

Does that make sense?
Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post20 Sep 2009 4:17   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


betwixt wrote:
For example if W contained the value 5 and the subroutine was called, it would return with the value in the 5th retlw instruction. So you have a quick and easy look-up table, enter with the position in W and return with the value for that position in W.

The only thing to be careful of is that your look-up table doesn't cross a page boundary in memory as the addwf PCL instruction only works on the PCL register, it doesn't switch to the next memory page if PCL is made to count beyond h'FF'.

since you are the walking '1', should W not contain 1 or can be any value? 1 2 3 4?

I don't get what you said for the last sentence but basically you mean do not exceed FF?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post20 Sep 2009 10:14   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


I think you are confusing two things:

The walking '1' is what you move (walk) across the column outputs of the PIC. You are basically doing four almost identical operations, one on reach column. Only one column at a time has a '1' on it, the others you keep at '0', these signals are ones you create yourself at the output part of the PIC port.

If any key is pressed, at some time in the 'walk', one of the rows will go to a '1', this is because the key that was pressed is connecting the column with the '1' on it to one of the row connections. The switch will have joined one of the column outputs back to one of the row inputs.

Look at the possible combinations of row inputs you can get (assuming only one key is pressed at a time):

Column output 0001 could give row input 0001, 0010, 0100 or 1000.
Column output 0010 could give row input 0001, 0010, 0100 or 1000.
Column output 0100 could give row input 0001, 0010, 0100 or 1000.
Column output 1000 could give row input 0001, 0010, 0100 or 1000.

The problem is how to convert these numbers back into the one printed on the keypad. You could work out the key number by testing each bit individually but that is a slow and inefficient process, it would need 32 'if' type statements to do it. This is where the look-up table is useful and very quick.

Using the list above, and assuming the columns are wired bit 0 to the right side, you could interpret the row signals as:

Column output 0001 could give input for keys A,B,C or D.
Column output 0010 could give input for keys 3,6,9 or #.
Column output 0100 could give input for keys 2,5,8 or 0.
Column output 1000 could give input for keys 1,4,7 or *.

So, using the last line as an example, an input of 0001 would mean key *, an input of 0010 would mean key 1, and input of 0100 would mean key 4 and an input of 1000 would mean key 7.

You could code this as "if the input is 0001 return the value '*'" but as I said earlier this uses a lot of instructions and can be slow to run. If instead you look up the value 0001 in a look-up table it is very fast to execute. The program flow goes like this:

1. Place 0001 on the column outputs
2. read the row inputs
3. if the row inputs are all zero (no key pressed) go to step 5
4. look up the row value in the table and return with the key number
5. Place 0010 on the column outputs

and so on for each of the columns.

The row value can be (in decimal) 1, 2, 4 or 8 so you need 8 entries in the look-up table. The entries for value 3,5,6 and 7 would indicate something is wrong, possibly more than one key is pressed at once. the 'good' values are for one key being pressed so all we need to do is return the real key number from the table

You keep a list of the possible values as 'retlw' instructions and precede them with an instruction that jumps to the correct entry in the list. That instruction is "addwf PCL,f" which means "add the value in W to the program counter so the next instruction to execute is that many addresses further ahead". for example, if W contained the value 8, the next 7 instructions would be jumped over and the 8th one would be executed. The place where the jump 'lands' is one of the retlw instructions which mean "return from this subroutine with the following value stored in W" That's how the look-up works, you enter with the table offset in W and it returns with the value at that offset in W. In the keypad code, you enter with 1,2,4 or 8 and return with the key code *,1,4 or 7. The flow of code only takes 3 instructions to execute, the subroutine call, the addition and the return so it is very fast.

The 'FF' problem is just something to be aware of. The instruction pointer in PIC16 devices is made of two parts, the PCLATH and PCL. PCLATH is the top (most significant bits) part and PCL is the lower 8 bits. Normally the PIC takes care of controlling PCLATH but when you change the value in PCL in your program, the PCLATH is not automatically updated as well. When you add W to PCL, it is possible that the result is greater then h'FF', in other words more than you can hold in an 8-bit register. When this happens, PCL rolls over to zero and starts counting up again. For example, if PCL held h'40' and you added 6 to it, the result would be h'46' which is fine, but if it held h'FD' and you added 6, the result would be h'03' instead of h'103'. The value originally in PCL depends on where the table is stored in memory, it is an address, so be careful to place your table so it does not cross the FF to 00 boundary. The easiest way to do this is to place the tables near the beginning of your program so the chance of reaching the end of a memory page are as small as possible.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post21 Sep 2009 2:41   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Ooo thanks for clearing that up.

You mentioned earlier about reading D7 to know when to toggle 'E', as an indicator.
So I have to keep referring to D7 for each character to display on LCD?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post21 Sep 2009 9:20   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


That is correct.

The LCD has it's own on-board microprocessor (I think it is Samsung KS0066U) which monitors the data connections and takes care of preparing the character shapes and driving the LCD glass. When it is doing internal operations, such as looking up the character font, it cannot also be monitoring for new data being fed to it. So what the manufacturer does, is use the D7 (on the LCD) pin as a 'busy' or 'ready' signal. As soon as it has digested the byte you sent it, it puts a '1' on D7 and keeps it there until it is able to accept fresh data.

So your routine does this:
1. Put the data on the bus
2. raise and lower the 'E' signal
3. change the pin connected to D7 to be an input
4. read D7
5. if it is '1', go back to step 4
6 change the pin to be an output again.

You do that each time you write anything to the LCD. Be sure to change the pin connected to D7 to an insput as quickly as possible or you might be driving it one direction while the LCD is driving it as well.

On the topic of hardware, you should connect pull-down resistors to the rows of the keypad, 10KΩ would be a suitable value or all the row signals will float when the keys are not pressed. It would also be good practice to put isolating resistors of say 100Ω in line with the keypad column connections. The reason - someone will inevitably hold more than one key down and without the resistors, it could directly short the data bits together. A value that low will have no influence on the keypad operation.

You will see the idea here

http://www.atv-projects.com/MkIII_TCG.html although different PIC pins are used in that design.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post22 Sep 2009 2:35   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


So, I'm guessing the flow of the program would be something like
1. Declare variables
2. startup for LCD
3. Toggle 'E' twice?
4. Scan keypad
5. Put the data on the bus
6. raise and lower the 'E' signal
7. change the pin connected to D7 to be an input
8. read D7
9. if it is '1', go back to step 4
10. change the pin to be an output again.


Am I missing something else ? O.O
I also have to write in the program for each time to write character R/W = 0 and RS = 1?
What would happen if I ground R/W? Would toggle 'E' still work?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post22 Sep 2009 8:32   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


You must toggle 'E' twice every time you write data to the LCD, it is part of the writing process. It's the part that says "data is ready- come and get it".

The LCD can be used in two modes, in 8-bit mode you put the whole data byte (8 bits) on D0-D7 and toggle 'E' once, in 4-bit mode you split the 8 bits into two 4 bit 'half bytes' and send them one after the other, toggling 'E' each time. As you do not have enough pins on the 84A, you are forced to use 4-bit mode.

Yes, connect R/W to ground so it is always in write mode. The LCD will still display the message correctly. The only thing you sacrifice is the ability to read the LCD internal registers back so you can't for example, read the font RAM. This is bot important for 99% of LCD users though.

Otherwise, your program flow looks fine except that step 9 should go back to step 8, you want to be in a loop, waiting for the busy signal to go low before proceeding. You should add step 11 which would be 'change to next column and then got ot step 4'.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post22 Sep 2009 10:46   

PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Need a slight clarification.
When you say toggle E. Do you mean its like step 6 ?
And when you say twice, do you mean like:
1) toggle E
2) toggle E
3) send data to LCD ?

Thanks for the help.
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post22 Sep 2009 22:58   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Sorry been away all day, a 500 Km trip so my body is back home but my brain is still on the move! I need coffee !!

By toggling 'E' I mean changing it's state for a moment them changing it back again.
So in this case, I mean making 'E' = 1 then making 'E' = 0 again. Raising and lowering it.

The LCD needs 8 bits of data but you are using it in 4 bit mode. This is perfectly OK and the manufacturer has made provision for this. To get the 8 bits down the 4 data wires you do it in two stages, I quote from the data sheet of the HD44780 which is an almost identical LCD controller but from Hitachi rather than Samsung:
Code:

For 4-bit interface data, only four bus lines (DB4 to DB7) are used for transfer. Bus lines DB0 to DB3
are disabled. The data transfer between the HD44780U and the MPU is completed after the 4-bit data
has been transferred twice. As for the order of data transfer, the four high order bits (for 8-bit
operation, DB4 to DB7) are transferred before the four low order bits (for 8-bit operation, DB0 to
DB3).
The busy flag must be checked (one instruction) after the 4-bit data has been transferred twice. Two
more 4-bit operations then transfer the busy flag and address counter data.


So if you imagine you wanted to display the character 'X' which has ASCII code 0x58 you would do this:
1. put the '5' of the 58 on the data bus
2. raise 'E' then lower 'E'
3. put the '8' of the 58 on the data bus
4. raise 'E' then lower 'E'
5. change the pin connected to LCDs D7 to be an input
6. keep reading D7 until it goes low
7. change the pin back to an output

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post22 Sep 2009 23:46   

PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


OHHHH I get the toggling E now! Thanks a lot!

How 'exactly' you 'put' the 5 on the data bus though? :S
Say D4 D5 D6 D7...think binary? Which is LSB and MSB?
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post23 Sep 2009 9:23   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


D7 is the MSB (Most Significant Bit) because changing it ha most significant effect on the value. Obviously, this makes D0 the LSB.

There are several ways of 'splitting' a byte into two halves. All you are trying to do is align the top half or the bottom half with the data lines you are using. I'm not sure how your circuit is wired so these are some alternative ways:

Assuming the byte is in a register called 'LCDchar' and the 'E' pin is named LCDE.

If your LCD data lines are connected to PORTB bits 7 to 4:
Code:

movlw h'F0'          ;this will be used to remove the lower bits
andwf LCDchar,w  ;top half of W now contains the top half of LCDchar value
movwf PORTB       ;output it to the port
bsf LCDE              ;make E high
bcf LCDE              ;make E low again
movlw h'F0'
swapf LCDchar,f    ;swap top and bottom half of LCDchar
andwf LCDchar,w  ;top half of W now contains the bottom half of LCDchar
movwf PORTB       ;output it to the port
bsf LCDE              ;make E high
bcf LCDE              ;make E low again


If the LCD data lines are connected to PORTB bits 3 to 0:
Code:

movlw h'0F'
swapf LCDchar,f
andwf LCDchar,w
movwf PORTB
bsf LCDE
bcf LCDE
swapf LCDchar,w
andlw h'0F'
movwf PORTB
bsf LCDE
bcf LCDE


I think you can work out suitable comments for the second code! Sorry about the strange comment spacing, I can't see a way of entering tabs into the reply window.

Note that in these examples ALL the bits of PORTB are driven simultaneously but the ones not connected to the LCD are set to '0' and only go to the keypad anyway so they will not cause harm.

Brian.
Back to top
Shinnster



Joined: 15 Sep 2009
Posts: 34
Location: Hello World!


Post23 Sep 2009 12:20   

PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Okay so I did a simple test with LEDS on each Data bits
and yeah, what you said was right. I got question though.
If you Toggled 'E' three times, what would happen?
Assuming that you want to write X "Same example earlier",
I send 5 then toggle 'E' TWICE in a row and then send 8 then toggle 'E', What would happen? Just curious.
and I will be using D4-D7 for the convenience of my stripboard.
Oh and I got a question on the Backlight, I need a current limiting resistor so what ohm should I put roughly?
I think I'm good to go on writing the program! :]
I will post the program when I am done Surprised. I might make a mistake on setting up the LCD but oh well, I'll do my best.
OH and I need to you ask you about the column resistors of 100ohm, does the resistor go through 'only' the keypad or data lines as well?


Thanks again.
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post23 Sep 2009 17:30   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


The 'E' signal tells the LCD to read whatever is on the data lines so you could get out of step if you throw an extra one in. It could get confused between first and second half bytes. There are two mechanisms that help to protect against that:

1. The LCD takes about 100mS (0.1 seconds) to initialize which gives plenty of time for the PIC to settled down and get its pins in the right states before the LCD even looks at the 'E' pin.

2. The busy flag (D7) only goes to a busy state after the second time 'E' is toggled so if necessary, put h'00' on the data pins and toggle 'E' until D7 goes high. When D7 drops you know it is prepared to accept the first half byte.

The data sheet says the backlight LED has a built-in resistor so it should run directly from 5V but I have seen LCD modules with the resistor shorted out by a link. There are 5 parallel chains of two LEDs in series so if in doubt, assume the forward drop of the LEDs is 3V and use a 22Ω resistor to give about 100mA current.

The 100Ω resistors are there so that if more than one key is pressed, the wires to the LCD or PIC don't become directly shorted to each other. Put the resistors in line with the keypad only. You can put them in the row and column connection if you like, the current through the keys is insignificant so they will make no difference to the performance but will give a degree of protection.

I await your code. Shocked

Brian.
Back to top
bjhotmail



Joined: 29 Sep 2007
Posts: 10
Location: South Africa


Post23 Sep 2009 19:20   

PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


if you not sure how to translate to asm then check out a prog i wrote a while back for 3x4 keypad with lcd. its not the most elegant code but it works, maybe give you a clearer understanding hopefully

Added after 1 minutes:

sorry! forgot the link http://www.piclist.com/techref/microchip/3x4Key-4bLCD-Lock.htm

Added after 10 minutes:

sorry! forgot the link http://www.piclist.com/techref/microchip/3x4Key-4bLCD-Lock.htm
Back to top
betwixt



Joined: 04 Jul 2009
Posts: 385
Helped: 63
Location: Wales, UK


Post23 Sep 2009 20:44   

Re: PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)


Houston, we have a problem!

Bjhotmail, your code is for driving a serial LCD but Shinnster has a parallel interfaced one. I have not simulated your code but I think you might have a problem in your keypad scanning routine. You seem to drive the columns accumulatively rather than sequentially so it may be possible to get wrong code numbers by holding more than one key down. Using look-up tables makes the code much smaller.

Brian.
Back to top
Arabic versionBulgarian versionCatalan versionCzech versionDanish versionGerman versionGreek versionEnglish versionSpanish versionFinnish versionFrench versionHindi versionCroatian versionIndonesian versionItalian versionHebrew versionJapanese versionKorean versionLithuanian versionLatvian versionDutch versionNorwegian versionPolish versionPortuguese versionRomanian versionRussian versionSlovak versionSlovenian versionSerbian versionSwedish versionTagalog versionUkrainian versionVietnamese versionChinese version
Post new topic  Reply to topic    EDAboard.com Forum Index -> Microcontrollers -> PIC16F84A with LCD JHD162A and Keypad 4X3(sort of)
Page 1 of 2 All times are GMT + 1 Hour
Goto page 1, 2  Next
Similar topics:
lcd and 4x3 matrix keypad (1)
4x3 keypad and LCD on the same IO lines ? (6)
keypad 4x3 and pic18 with c (5)
16f877a alarm issue with JHD162A LCD (1)
4x3 alphanumeric keypad (4)
interfacing LCD and keypad with C8051F020 (3)
lcd interfacing with 8051 and 4*4 matrix keypad (1)
4x3 press button numeric keypad (6)
[50 pts] PIC scrolling a Keypad 4x3 (8)
can we scan 2 keys at the same time using 4x3 keypad (10)


Abuse || Administrator || Moderators || Support us || sitemap
topic RSS