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.

Confused over table 256 byte page boundry

Status
Not open for further replies.

gregmcc

Member
I'm busy writing a program for the 16F877 with a couple of large tables. One of them starts at 0x220 which is over the 256 byte limit. I've followed the recommendations in AN556 and tried a few examples from various sites - I can't seen to get any of them working. My program keeps crashing when I call the table.

I've tried the following:
Code:
   movlw  high   (table_START)
   movwf  pclath
   movf   index,w
   addlw  table_START
   skpnc
    incf  pclath,f
   movwf  pcl
table_START
   retlw  ...

and also some of the examples from AN556:
Code:
    org 0x80
    movlw HIGH Table
    movwf PCLATH 
    movlw offset,F 

     call Table

     org 0x02ff 
Table:
     addwf PCL,F 
     .....

How do you go about addressing tables above 256 bytes. Am I missing something?
 
Last edited:
gregmcc said:
I'm busy writing a program for the 16F877 with a couple of large tables. One of them starts at 0x220 which is over the 256 byte limit. I've followed the recommendations in AN556 and tried a few examples from various sites - I can't seen to get any of them working. My program keeps crashing when I call the table.

There are two different problems with tables. One is when a table crosses a 256 byte boundary and the second is when the table is over 256 bytes long.

Your examples address the first problem. For bigger tables you need a bigger index as a single byte can only hold 0-255.

This will work anywhere in memory,
Code:
FetchTable
   movfw  index+1                     ;=high byte of index
   addlw  high table_START
   movwf  pclath
   movf   index,w
   addlw  low table_START
   skpnc
    incf  pclath,f
   movwf  pcl
table_START
   retlw  ...

One other thing you may have missed is that you have to call this code as it does a retlw when it exits,
Code:
    call  FetchTable     ;returns value in W
    call  DisplayW       ;use it
    inc   index,f        ;point to next one
    spnz
    incf  index+1,f

Mike.
 
I stil seem to be having issues. I've posted the code I'm using below. I call the Check_Keys routine (Its not the most efficient code :)

At a quick glance is there any reason why the 256 boundary would cause issues with the below.

Code:
Check_Keys
	movlw	b'00000001'		
	movwf	PORTC	
	movf	PORTC,	W
	andlw	0xF0			
	btfss	STATUS, Z		;test if any key pressed
	goto	Col1

	movlw	b'00000010'		
	movwf	PORTC	
	movf	PORTC,	W
	andlw	0xF0			
	btfss	STATUS, Z		;test if any key pressed
	goto	Col2

	movlw	b'00000100'		
	movwf	PORTC	
	movf	PORTC,	W
	andlw	0xF0			
	btfss	STATUS, Z		;test if any key pressed
	goto	Col3

	movlw	b'00001000'		
	movwf	PORTC	
	movf	PORTC,	W
	andlw	0xF0			
	btfss	STATUS, Z		;test if any key pressed
	goto	Col4

Col1
	movwf	key
	clrw
	goto Check_Row

Col2
	movwf	key
	movlw 0x04
	goto Check_Row
	
Col3
	movwf	key
	movlw 0x08
	goto Check_Row

Col4
	movwf	key
	movlw 0x0c
	goto Check_Row
	
Check_Row
        movwf index  

	btfsc key,4
	goto Row1

	btfsc key,5
	goto Row2

	btfsc key,6
	goto Row3

	btfsc key,7
	goto Row4

Row1
	goto Keys
Row2
	incf index	
	goto Keys
Row3
	incf index		
	incf index
	goto Keys
Row4
	incf index
	incf index
	incf index
	goto Keys
	
Keys

	movlw HIGH Key_Table
	movwf PCLATH
	movlw index
	call Key_Table


Key_Table  ADDWF   PCL , f
            	
		RETLW   0x31	;1
            	RETLW   0x34	;4
            	RETLW   0x37	;7
            	RETLW   0x2a	;*
            	RETLW   0x32	;2
            	RETLW   0x35	;5
            	RETLW   0x38	;8
            	RETLW   0x30	;0
            	RETLW   0x33	;3
            	RETLW   0x36	;6
            	RETLW   0x39	;9
            	RETLW   0x23	;#
            	RETLW   0x41	;A
            	RETLW   0x42	;B
            	RETLW   0x43	;C
            	RETLW   0x44	;D
 
Last edited:
You problem is the call to Key_Table. After the retlw instruction the processor will return to where it was called from and so will execute Key_Table twice, the second time with an illegal value. As long as in your main code you are doing call Check_Keys and not goto then you can remove the line call Key_Table. Alternatively, if you are not calling Check_Keys, you need a goto somewhere after call Key_Table.

Mike.
 
Aaggh - awesome! Thanks Mike. I'll try it out tonight.

I sat last night for a few hours trying to solve it. :)
 
You might be happy to know if you need large tables you could drop in a 18F4620 in to that 16F877 socket. The 18F has a powerful set of table instructions.
 
Bill, you might be happy to know, the 16F877 can also read and write to large tables in program memory.

Mike.
 
I've used retlw and table, I simply find table more convenient and you don't have to write special code for large tables. They both work, I guess I'm soapboxing :)
 
Ahh I get it, you're using the EEPROM/FLASH read/write functions available on PICs with self modifying code like the 18F1320.

As I said earlier the only advantage is auto increment.

Mike.
 
Tried removing the call but its still falling over. :( I'll go through it with a debugger - maybe I'm missing something else.
 
Greg,

It should work. single step it and if you still can't figure it out then post your complete code tomorrow (4AM here - another story). Seeing part of your code leaves (sp?) us guessing.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top