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

Status
Not open for further replies.
That is a massive jump ahead - well done !!

It might actually work at the moment but I'm not going to try it !

A few minor points, these are not mistakes, just suggestions to make the code clearer and easier to debug:

1. instead of allocating all the variable addresses yourself, consider using the 'cblock' directive. It makes it less likely to make mistakes, especially if you add more variables later. Change:
Code:
w_temp        EQU     0x0C        ; variable used for context saving 
status_temp   EQU     0x0D        ; variable used for context saving
Del1		  EQU	  0x0E
Del2		  EQU	  0x0F	
LCD			  EQU	  0x10
Print		  EQU	  0x11
Display		  EQU	  0x12
Home	  	  EQU	  0x13
to
Code:
cblock	0x0C
w_temp		; variable used for context saving 
status_temp	; variable used for context saving
Del1
Del2	
LCD
Print
Display
Home
endc
The assembler will allocate the numbers by itself and if you need to add an extra variable, just put it between the cblock and endc statements and all the numbers will magically adjust accordingly.

2. You use 'BTFSC h'03',2 ;Check Zero Bit' several times, this is correct but not easy to read because you need to remember that h'03' means the STATUS register and '2' is the Zero bit. Instead, use the register and bit names so it becomes 'BTFSC STATUS,Z' it's much easier to understand. Just like you gave names (aliases) to the pin names, if you look in the 'p16F84A.inc' file you will find the registers and all the bit number have been given names too.
The #include directive simply means "put all the code in the include file right here", you could do exactly the same by copying the contents of the file into your program but why bother when its all done for you.

3. Some of the code is duplicated, whenever you see more than a few lines being used over and over again, put them in a subroutine and call them every time they are needed.

Other than that it looks pretty good. You have mastered the look-up tables nicely and noticed that you can't actually reach the first entry, it just has to be there to keep the others in the right place. I'm not sure you are setting the column scan quite right, are you putting the '1' on only one column at a time?

Now a hint of a bug for you to hunt down. Sometimes you have to imagine a total idiot (me perhaps!) is going to use your device and think what might happen if they try to hold several keys down at once. Think of the resulting value on the row inputs and what might happen in the look-up tables.

Brian.
 

Haha thanks.

Wasn't sure about 2.

Not sure about 3. I will try to make it better

Yeah I was going to ask you about that bug haha. Okay I will try to write first.
 

Houston, we have a problem !

It's not working !
But I managed to get LCD commands working, just not keypad :O .

I will paste the program

I just pasted the circuit.

Tell me if there's anything wrong

Oh yeah the LCD commands,
say I want to Display On, Cursor on, Blink on - I need to send h'0F' to Dlines,
I need to send F first then followed by 0 for it to work.

So.... I'm not sure if there will be any effect on the keypad - print though, I just added an extra swap :|
 

There were still a few problems in your code, for example, after putting the '1' on a column you did not set it back to '0' when you moved to the next column. So after the first keypad scan, all the columns had '1' on them.

In your processor configuration (__CONFIG) you enable the watchdog timer which causes an automatic software reset every 18mS unless you use the CLRWDT instruction before then. It is a protection mechanism, the idea is that if you program crashes, it will not execute the CLRWDT instruction so an automatic restart takes place.

The other software problem was that you did not properly initialize the LCD, although I give you full credit for trying. What you missed was that the LCD powers up in 8-bit mode so you have to set it to 4-bit mode first. It also needs up to 100mS from power-up to being ready, the delay is for the LCDs own microprocessor to initialize before it will accept commands.

There is one hardware problem, you do not connect the contrast control pin on the LCD module. You need to wire a potentiometer (any value from 5 - 25KΩ will do) across supply to ground and connect the wiper to LCD pin 'CV'.

I have attached UNTESTED code for you to work with. It is based on your program but I have tidied it up and added the missing code. I put lots of comments in it to help you. I ran it in the MPLAB simulator and it seems to work but I have not actually built anything to try it in 'real life'.

There is still the bug that can show if you hold down more than one key on the keypad - I left that in for you to find yourself Have fun finding it!

Brian.
 

    Shinnster

    Points: 2
    Helpful Answer Positive Rating
Well I can tell you that , that program doesn't work
BUT it is a lot neater than mine and I finally get your h ints on the 3) You mentioned earlier.

By the why, what does cyan coloured ' ' mean?
Anywho I suspect the 8 bit changing to 4 bit is wrong in hex. h'38' is for 8 bit - 2 lines - 5x7
h'28' is for 4 bit - 2 lines - 5x7.
5x7 or 5x8 not too sure.
Anyway regarding that bug, do I add debouncer?
OR, I reroute those returned with 'X' values to another subroutine?
 

I'm not really surprised it doesn't work, most of it was written from memory and it's a log time since I used one of those LCDs or a 16F84.

You are probably correct about the bytes to configure the LCD, try them, if it works they are correct.

Placing a character between ' ' marks tells the assembler to use the ASCII code rather than the number itself. So if you used "retlw 5" it would return with the number h'05' but "retlw '5' " it would return with h'35' becasue that is the ASCII character code for a printable 5. As your LCD expects ASCII codes, it makes sense to return them directly from the table rather than use extra software to convert them.

Incidentally, if you want the code to look a little more compact, you can use the "dt" directive to build the table. It still produces the same HEX code but it might make your source code easier to read. For example:
Code:
TABLE4		ADDWF		PCL,f
			RETLW		'X'
			RETLW		'*'	
			RETLW		'0'
			RETLW		'X'
			RETLW		'#'
			RETLW		'X'
			RETLW		'X'
			RETLW		'X'
			RETLW		'D'
becomes
Code:
TABLE4		ADDWF		PCL,f
			DT 'X','0','X','#','X','X','X','D'
sometimes, especially when handling text messages, it is easier to read when the characters are all in one line. 'DT' just means 'Define Table' of RETLW instructions with these values.

I'll help you with the bug - it is in two parts, firstly, the row inputs are floating so they could randomly read high or low, they need pull-down resistors (10K will do) to ensure they read zero unless a key is pressed. Secondly, if the bottom key of any column is pressed (returning 1000 on the row input) and another key is held as well, the returned value will be more than 8. This means that when you call the look-up table, it could go beyond the end of the table and either land in another table or on an instruction which could crash the program. There are two way to fix this, either you can check and reject any value greater than 8 or you can add an extra 8 dummy values to the end of the tables so they can't overflow.

As for debouncing, you might need to do this but get the program working first. All that can happen without debouncing routines is that you get several entries on the LCD from pressing a key just once.

When you get it working, you will come across another problem to do with the second line of the LCD but leave that until the first line works!

Brian.
 

    Shinnster

    Points: 2
    Helpful Answer Positive Rating
Yeah I noticed the problem with second line during my very start of trying out.

Naughty people like me like to spam :} and it went over 16 characters >.>

I have something to ask you as well.

Can you recheck that LCD set up section?

When you wrote send h'03' to sendmsg 8, after swap, if you mask that with F0, wouldn't that be 0?
I tried to change around but for some reason, it's not working >.>
Hmmm...
I'm going to keep trying some other hex values until I get something.

Ahhh I only have 2 10k resistors left. Bummer. >.<.
What happens if you use 15k ~.~?
Oh, only got 1 15k grr I got like a bundle of 2k's hmm.


Hmmm I will keep trying around with LCD until it works. Going to rip out the LCD part alone and do some hex testing tomorrow morning.
 

2KΩ is a bit low but it should work OK. When a key is pressed, the PIC has to source the current to raise the logic level to a high. With 2K the current will be about 2.5mA which is FAR more than necessary but the PIC is rated at 20mA so it should work.

I'll try to look at the LCD code later. I have someone staying with me at the moment and it is difficult to spend time at the computer. I have to take them home tomorrow (500Km trip !) so i will be out of action most of the day.

You are probably correct about the data to initialize the LCD, I did most of it from memory and just checked the scan worked and the delay times in the MPLAB simulator. I didn't check the values sent to the LCD or the RS & E signals.

The clue to why the second line doesn't work is in the data sheet. Each character position on the screen has a corresponding memory location in the LCD controller chip. On a single line LCD the addresses go from h'00' to h'0F' to give the 16 characters. On a two line LCD though, the second line uses addresses h'40' to h'4F' so there is a large hole in the memory map.

I have a similar issue on something I'm working on at the moment. If I send characters to the LCD, they fill the top line, then the third line, then the second line then the bottom line !!

Brian.
 

YEAH!!! On your last statement !
I had that same problem when doing with PICbasic 4x3! HAHA.
Except mine displayed '?' hehe.
Mine printed 1st line left, 1st line at the end, 2nd line left then 2nd line end!! :]

Yeah I figured about the second line out. I remember typing a code for that in basic few weeks before coming here to make it type on second line.

 

Mr. Brian I bring forth good and the bad news!
Good news!
It's working!!!
Works perfectly!
Once it hits to the 16th's character address, I make it move to 2nd line and once it hits that, I did two versions, one is clear the screen, another is overwrite the 1st line. And yes, keypad works well.
Such a good day!

Bad news it be sad is :
I did it in PICbasic. But anywho, it was because of the hardware you provided assisted with, the flow of the program and even the bug :] and added debounce and many more.

This is only part of learning a bigger picture.
Result: Alarm system O.O
But i'm about 98.99% unfamiliar with this so I started small

BUT this doesn't mean I don't want to learn asm!
I still want to figure out why that asm is not working.
Because PICbasic flow should be EXACTLY, the same but, hmm. I think the program is missing something important in the LCD area.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…