Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Issues with PIC16F877A and LCD display...

Status
Not open for further replies.

si2030

Member
Hi All,

I am working on a project that uses an LCD and 4x4 keypad. The program almost works in that when I hit one of the keys on the keypad it interrupts and carry's through but the LCD on most occassions displays the following.

|| || || Hz-FREQ

I have set it up to display

54321Hz-FREQ

If I hit and hold the 5 button the correct output displays but most of the time its the vertical bars.

I am using the FSR register and decrementing it displaying the contents down to H'20'. I think most times it doesnt add the offset and therefore decrements from H'20' but thats a guess...

I have included the ASM file as a single file. It compiles.

Hoping you might be able to help.

Simon
 

Attachments

  • FUNCTION_GEN_MAIN_P&.asm
    29.2 KB · Views: 200
hi si,
When you call EVAL_KEY from within the ISR you are not returning to the ISR.?

You should not have that EVAL_KEY call within the ISR section as the EVAL_KEY subr calls all over the place with delays etc.

Why not set a key pressed flag in the ISR and then test in Main for it.

Also I would not enable the interrupts until the PIC has been initialised fully also clear any pending interrupt flags.

I would suggest you simplify the LCD data write method.

OK.?:)
 
Hi,


To continue where Eric left off, your ISR is incomplete.

You exit the isr by restoring W and S , but you do not appear to have saved them on entering the ISR - example code attached
 

Attachments

  • isr..asm
    862 bytes · Views: 161
hi si,

This section will not display the 'bare' key code.
Unless you have preloaded the LCD Graphics ram with a suitable ASCII character.

Dont be disheartened with all these errors, we have all been there.:)

Code:
;DISPLAY_LED
			
			ANDLW	0x0F		; Make sure only 4 lower bits are valid
			MOVWF	PORTD
			CALL	DELAY255 
			CALL	DELAY255 
			CALL	DELAY255 
			RETURN
 
Hi Eric... a quick question. When you set a flag do you use say a bit in a variable and set that and then test for it with BTFSS in main?

Also I assume when you refer to the setting of interrupt flags you mean initialise the LCD as well and then set the interrupt flags...

I only just worked out that 3 in HEX is not the same as 3 in ASCII (I knew this but realised it in this programming context earlier today). The display_led was a crude way to determine if my program was getting there...
 
Hi Eric... a quick question. When you set a flag do you use say a bit in a variable and set that and then test for it with BTFSS in main?

Also I assume when you refer to the setting of interrupt flags you mean initialise the LCD as well and then set the interrupt flags...

I only just worked out that 3 in HEX is not the same as 3 in ASCII (I knew this but realised it in this programming context earlier today). The display_led was a crude way to determine if my program was getting there...

hi,
You can use a byte as flags register, assign a bit to each of the required actions.

Keep the interrupts off until the PIC is initialised and clear any set interrupts.

If you OR the key bits with 0x30 after you have ANDed with 0x0f you will get an ASCII char for the LCD display.

You can write each character to the LCD in the '54321' string sequentially , you dont have to buffer them into a string.
 
Last edited:
Hi,

Following on from Eric again - getting a hex number, 0 to FF, onto a lcd can be a pain, but there are some handy little routines at Piclist where you feed in the hex value and it returns a 3 digit Ascii result ready for the lcd.
See -
 
Hi there guys,

OK I have been playing with this for a few hours and it almost works. The things I have done...

I moved the enabling of the interrupts to after all the initialisations were done.

I enabled a flag variable called INTERRUPT bit "0" for keypad and then tested that in the main program..

I also fixed it so that status, pclath and W were saved off and then restored.

I find that after it displays "HELLO WORLD" it then automatically interrupts once... no matter what I do it seems to go to the EVAL_KEY routine despite no interrupt being tripped and it does this once straight after reset or when you flick the on switch.. then it works..

I also found its sensitive to the sequence in which the interrupt fuses are enabled.. I am not sure I have these correct...

Hoping you might be able to look at the code and tell me why it goes to EVAL-KEY or in other words interrupts immediately after "HELLO WORLD"..

Kind Regards

Simon
 

Attachments

  • FUNCTION_GEN_MAIN_P&.asm
    30.5 KB · Views: 141
hi Simon,
Downloaded your code, will have a peek.:)
Get back to you shortly
 
Last edited:
Hi,

Have not gone through all your code but the most obvious error is still the ISR.

The first instructions on entering the ISR must be the context save of W and S etc.

After that is done, then you can do your normal instructions - however the general rules for the isr is that you keep the code minimal, incase other interrupts are occuring, and that you do not CALL out of the interrupt routine.
You can use a goto withing the ISR but again do not make the code lenghty or complicated.
Ideally use it for simpe code and to set Flags to be used in your main code.

What you are coding, calls/jumps in and out of the ISR all the time so its just going to loose itself and give you all sorts of crashes - don't worry - its one of the regular things that many beginners fall down on - me included.
 
hi si,
Looking quickly at your code, as wp100 points out, a fair number of errors etc.

Would you like me to make some additions and changes to your program or would you prefer to make any changes yourself.?
 
Hi Eric,

I could see two call statements one of which I removed and then moved the other (I moved the call statement to GET_Keys to the EVAL_KEYS routine) but it still played up.. so I am not sure what to do next.. It would be great if you could make the necessary changes and let me know why. As wp100 says these are the traps beginners find and I am no exception..

Simon
 
Hi Eric,

I could see two call statements one of which I removed and then moved the other (I moved the call statement to GET_Keys to the EVAL_KEYS routine) but it still played up.. so I am not sure what to do next.. It would be great if you could make the necessary changes and let me know why. As wp100 says these are the traps beginners find and I am no exception..

Simon

hi,
OK, it will take a while, could be as late as tomorrow before I post back.:)
 
I really appreciate the time, effort and help your are giving with this.

hi,
This ISR now only interrupts on a key press.
I have added the register save/restore into the ISR.
Depending upon the state PORTB.HI nibble the flags register is set/reset.
The label INTERRUPT has been changed to flags.
The main loop now includes GETKEY/EVAL calls.
I will look further into your program.

Copy and Paste this section in place of the current ISR.

One point I am not clear about is how you are reading the keystroke,,, in the program you say test for a high pin on PORTB.HI but you have set
the PORTB weak pull ups and PORTC is outputting lows.???


Code:
;===============================================================================    
; PROGRAM JUMP TO START.    
;===============================================================================    
	org	RESET_V		;RESET VECTOR LOCATION.
	goto	START
		 
;=============================================================================  
;THIS IS THE INTERUPT ROUTINE.  sss
;=============================================================================  
SERVICE_INTRPT 
	org	ISRV_V		;INTERRUPT VECTOR LOCATION.

	movwf   W_ISR_TEMP            ; save off current W register contents
	movf	STATUS,w          ; move status register into W register
	movwf	STATUS_ISR_TEMP       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	PCLATH_ISR_TEMP	  ; save off contents of PCLATH register
 
	movf  	PORTB,W ;	 read PORTB to clear any mismatch condition
	bcf	INTCON,GIE	;DISABLE ALL INTERRUPTS.
	bcf 	INTCON,RBIF	;clear portb intrf
	
	bcf	flags,0		;clear the key pressed flags bit
	movf    PORTB,W		;check sense of portb intr
	andlw	0xf0
	sublw 	0x00		;if PORTB 7~4 are high the key has been released
	btfss	STATUS,Z
	bsf	flags,0		;else a key is pressed down
	nop

		;call	DELAY30	
ISREND		 
	movf	PCLATH_ISR_TEMP,w	  ; retrieve copy of PCLATH register
	movwf	PCLATH		  ; restore pre-isr PCLATH register contents
	movf    STATUS_ISR_TEMP,w     ; retrieve copy of STATUS register
	movwf	STATUS            ; restore pre-isr STATUS register contents
	swapf   W_ISR_TEMP,f
	swapf   W_ISR_TEMP,w          ; restore pre-isr W register contents
	retfie                    ; return from interrupt


;===============================================================================    
; PROGRAM STARTS HERE.    
;===============================================================================    
START:  ;sss
	call	PIC_INIT	;INITIALIZE FOR RC0-7 TO BE OUTPUTS.
	call	LCD_INIT	;NOW INITIALIZE THE LCD FOR 4 BIT OPERATION.
	call	DISPLAY		;DISPLAY "HELLO WORLD".
;===============================================================================    
;ENABLE INTERRUPTS.    
;===============================================================================  													  
	clrf 	PIE1
	clrf 	INTCON		; clr ALL intr
	movf 	PORTB,W		;read PORTB
	bcf	INTCON,INTF	;CLEAR INTERRUPT FLAG.
	bsf	INTCON,RBIE	;ENABLE INTERRUPT ON RB4-7 CHANGE.
	bsf	INTCON,GIE	;ENABLE ALL INTERRUPTS.

LOOP	
	;bsf	INTCON,GIE	;restore intr
	btfss	flags,0		;TEST FOR KEYPAD f=flags bit
	goto 	LOOP    	;not set so loop
	bcf 	flags,0 	;clear the flag

	call	GETKEY		;KEY PRESSED NOW IN W (0 - 15).

	;iorlw 	0x30
	;Call 	LCD_DISP_CHAR
	
	call	EVAL_KEY
	bsf	INTCON,GIE	;restore the intr
	goto	LOOP
 
Last edited:
Hi Eric, Others

After floundering around for hours and hours with this I now have it working with the interrupt and the LCD displaying the number entered onto the keypad just like a calculator... I wasnt able to get the interrupt to work with a flag as you showed unfortunately no matter what I tried... hey it works and I am making sure that any calls from the interrupt dont go more than two deep keeping in mind that you can only go 8 deep..

So many many thanks for your time on this...
 
Hi Eric, Others

After floundering around for hours and hours with this I now have it working with the interrupt and the LCD displaying the number entered onto the keypad just like a calculator... I wasnt able to get the interrupt to work with a flag as you showed unfortunately no matter what I tried... hey it works and I am making sure that any calls from the interrupt dont go more than two deep keeping in mind that you can only go 8 deep..

So many many thanks for your time on this...

hi si,
If would like to post your program asm file, I could look at ito see why you had a problem with the flags method.
 
Hi Eric,

I kept modifying the code until it worked and didnt keep a copy of the asm program at that stage... trying to work through the details myself... I have loaded the program as it worked without the flags mod..

I have another problem and will start another thread in a few moments with the program as it stands now...

Simon
 

Attachments

  • FUNCTION_GEN_MAIN_P&.asm
    14.1 KB · Views: 115
Hi Eric,

I kept modifying the code until it worked and didnt keep a copy of the asm program at that stage... trying to work through the details myself... I have loaded the program as it worked without the flags mod..

I have another problem and will start another thread in a few moments with the program as it stands now...

Simon

hi si,
I'll give it a go.:)
Why dont you continue to use this thread.

EDIT:
You have not posted the include files within that last *.asm .?
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top