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.

Accessing higher RAM locations (16F887)

Status
Not open for further replies.

ahydra

New Member
Following some recommendations I've now ordered a 16F887 and a cool LED display thing, and plan to see if I can get the former to drive the latter. I've designed a font which I can encode into 5 bytes per character, and plan to store 40 characters (A-Z, 0-9 plus some punctuation). Hence I need 200 bytes.

The 16F887 has plenty of space for this but how do you access the higher RAM locations? Let's take as an example Bank 2's RAM located at address 0x120. Bank 2 starts at 0x100, so is this then right...

Code:
cblock 0x20 ; 0x120 - 0x100
c0:5
c1:5
c2:5
...
c15:5
endc

; switch to bank 2
BSF STATUS, RP1
BCF STATUS, RP0 

; load c2 into W
MOVF c2, 0

Note: I'm not really going to do it like that! I'll use indirect addressing, it's the only practical way.

Thanks,

ahydra
 
Last edited:
That is how you access the upper banks or, as you say, using indirect addressing (set the IRP bit for banks 2 & 3). However, in this case you would want your character set in ROM not RAM. The way you do this is using dw (define word) and you read it using the EEDATA etc. registers.

Code:
	dw	0x55,0x55,0x00,0x00,0x00,0x55,0x55	;	32	 
	dw	0x55,0x55,0x00,0x5F,0x00,0x55,0x55	;	33	!
	dw	0x55,0x55,0x07,0x00,0x07,0x55,0x55	;	34	"
	dw	0x55,0x14,0x7F,0x14,0x7F,0x14,0x55	;	35	#
	dw	0x55,0x26,0x49,0x7F,0x49,0x32,0x55	;	36	$
	dw	0x55,0x63,0x13,0x08,0x64,0x63,0x55	;	37	%
	dw	0x55,0x36,0x49,0x00,0x22,0x50,0x55	;	38	&
	dw	0x55,0x55,0x04,0x03,0x00,0x55,0x55	;	39	'
	dw	0x55,0x55,0x1C,0x22,0x41,0x55,0x55	;	40	(
	dw	0x55,0x55,0x41,0x22,0x1C,0x55,0x55	;	41	)
	dw	0x55,0x14,0x2A,0x1C,0x2A,0x14,0x55	;	42	*
	dw	0x55,0x08,0x08,0x3E,0x08,0x08,0x55	;	43	+
	dw	0x55,0x55,0x80,0x60,0x55,0x55,0x55	;	44	,
	dw	0x55,0x08,0x08,0x08,0x08,0x08,0x55	;	45	-
	dw	0x55,0x55,0x55,0x40,0x55,0x55,0x55	;	46	.
	dw	0x55,0x60,0x10,0x08,0x04,0x03,0x55	;	47	/
	dw	0x55,0x3E,0x51,0x49,0x45,0x3E,0x55	;	48	0
	dw	0x55,0x00,0x42,0x7F,0x40,0x00,0x55	;	49	1
	dw	0x55,0x62,0x51,0x49,0x49,0x46,0x55	;	50	2

Mike.
 
Thanks - so in your example, does the ROM simply contain the values 0x55, 0x55, 0x00, etc starting at address zero or is there something special going on (for instance, defining 14-bit words you couldn't have 0x5555)?

Edit: since I need bytes, I'll probably just use db to define some bytes. :) I just need to know where they'll start (surely it's got to be address zero).

ahydra
 
Last edited:
Yes, the ROM will contain the values with 6 zeros as the high bits to fill a 14 bit word. The address of them is wherever you put it. I just add tables like this to the end of my code. They definitely shouldn't go at zero as this where the code starts executing after a reset.

Do not use db as it does not do what you expect. It combines 2 values and places them in one 14 bit word.
So, db 0xff,0x45 gets assembled to a single word containing 0x3f45 !!!

If you are storing ascii then you can use da as this stores two 7 bit values in each word.

Mike.
 
Yes, the ROM will contain the values with 6 zeros as the high bits to fill a 14 bit word. The address of them is wherever you put it. I just add tables like this to the end of my code. They definitely shouldn't go at zero as this where the code starts executing after a reset.

Ah, that's why I'm getting "overwriting previous address" errors. I thought the EEPROM and the program flash memory were two separate entities; obviously not.

Do not use db as it does not do what you expect. It combines 2 values and places them in one 14 bit word.
So, db 0xff,0x45 gets assembled to a single word containing 0x3f45 !!!

Yes, I just discovered the behaviour of db :) Oops.

Thanks for the hints!

Edit: I assume I need to finish the code with a constant value for the table offset defined, then compile it and look to see where the table starts and change the constant value appropriately.

Edit 2: Or, perhaps better, do something like ORG 0xF0 to start the code after the table? Though if the chip defaults to location 0 and there's no way to programmatically change that, this won't work.

ahydra
 
Last edited:
The flash and EEPROM are seperate areas. To write to the EEPROM use org 0x2100.

To access your table you simply give it a label,
Code:
CommandTable	dw	'S'		;Set Position
		dw	Ram+XPos,Ram+YPos,Ret
		dw	'P'		;Plot Point
		dw	Ram+XPos,Ram+YPos,Plot
		dw	'U'		;UnPlot Point
		dw	Ram+XPos,Ram+YPos,UnPlot
		dw	'B'		;Box
		dw	Ram+XPos,Ram+YPos,Ram+Width,Ram+Height,Box

And to access it you would do,
Code:
		movlw	low CommandTable
		movwf	Pointer
		movlw	high CommandTable
		movwf	Pointer+1
		call	SetEEAdd
FindCommand	call	ReadEEWord

The routines if your interested are,
Code:
SetEEAdd	bsf	STATUS,RP1		;#2
		movfw	Pointer
		movwf	EEADR
		movfw	Pointer+1
		movwf	EEADRH
		bcf	STATUS,RP1
		return

ReadEEWord	bsf	STATUS,RP1		;#2
		bsf	STATUS,RP0		;#3
		bsf	EECON1,EEPGD
		bsf	EECON1,RD
		nop
		nop
		bcf	STATUS,RP0		;#2
		movfw	EEDAT
		movwf	Acc
		movfw	EEDATH
		movwf	Acc+1
		incfsz	EEADR,F		;Increment address
		goto	DoneREE
		incf	EEADRH,F
DoneREE		bcf	STATUS,RP1	;#0
		return
Both Pointer and Acc are in the shared area 0x70-0x7f.

Mike.
 
Right, so
Code:
low label
gives you the low-order byte of the address of label, and
Code:
high label
gives you the high-order byte. Or at least I hope it does, otherwise things might get fiddly :(

ahydra
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top