[PIC] assembly language for 2D array in PIC microcontroller

Status
Not open for further replies.

biswajitdas49

Member level 3
Joined
May 17, 2012
Messages
55
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
WEST BENGAL,INDIA
Visit site
Activity points
1,726
Hello everybody!
I have a question that in C language there we can use 2D array,but how to solve same problem in PIC16F1936 microcontroller assembly language.As a example in C- [8row][8col].I know only assembly and I heard if I use FSR and INDF then I can solve this,but I don't understand how and where to start it. If somebody give me any IDEA it will be very helpful for me.

THANKS IN ADVANCE!!!!
 

Hi,

Yes, the FSR is used to point to the location of a large area of Ram and the address can be read and auto incremented etc.

Here is a little bit of code that demostrates its use.

They are just wiping / blanking various area of ram to zero before starting the main routine.

They are in 18F code, so you might have to add banksels as needed.

Code:
ramclr		movlb	D'1'				; define bank1, so it and bank 0 (access) 
								; can be addressed without banking
 			
	 		clrf	FSR1H			; FSR routine to clear ram banks 0 -4 only
			clrf	FSR1L		
clrram		clrf	POSTINC1			; clear location and inc
 			movlw	0x05			; now in bank5 ?
 			subwf	FSR1H,W
 			bnz	clrram		        ; carry on clearing if not at bank5

clrglcd		lfsr	FSR1, 180h			; writes 'space' to glcd ram area
cglcdlp		movlw	' '			          ; acts as a boot up screen clear
	 		movwf	POSTINC1
			btfss	FSR1H,1
			bra	cglcdlp
 

Arrays are just sequential memory locations, you can calculate the address of an element in a two dimensional array by multiplying the first index by it's defined dimension and adding the second index to it.

Brian.
 

Arrays are just sequential memory locations, you can calculate the address of an element in a two dimensional array by multiplying the first index by it's defined dimension and adding the second index to it.

Brian.

Can you please elaborate it.
suppose I have an array -

DT d'2',d'4',d'7',d'2',d'8',d'6',d'9',d'0'
DT d'1',d'6',d'5',d'4',d'8',d'5',d'7',d'9'
...................................................
...................................................

DT d'n',d'n',d'n',d'n',d'n',d'n',d'n',d'n'

please explain it.actually I am new with fsr and Indf.
also please tell me what is FSR0,FSR1 and INDF0,INDF1.
 

DT is the assembler directive to load values into a table. Basically you are directly entering the values into a list at whatever address is next in memory. Each 'DT' value is placed in the next storage address so you are not creating a multi-dimensional array by using two DT lines but making one block consisting of the first followed by the second DT sets of values.

FSR and INDF are registers in the PIC. Most registers are mapped at fixed addresses and when you read or write to that register it always refers to the same address. FSR works a little differently, the FSR and INDF registers themselves are always at fixed addresses but they work like a window into the remaining address space. Whatever address value you write to the FSR makes the contents of that address accesible through the INDF register. For example, if you write 123 to FSR0, the INDF0 register will hold the value at address 123. If you write to the INF0 register, your new data will be written to address 123. It's a way of selecting an address using a variable which otherwise is tricky to do. FSR selects where you want your window to be and INDF lets you access the data there. Some PICs have one FSR ad INDF, some have two or more but they all work the same.way.

They are particularly useful when you want to copy a block of data from one place in memory to another. you load FSR0 with the source address, FSR1 with the destination address then copy the contents of INDF0 to INDF1. By simply incrementing FSR0 and FSR1, they both point to the next place in the source and in the destination so you can repeat copying with the next address for as long as you need.

My comment on the construction of two dimensional arrays was to explain how they are stored in memory. Although you see it as two dimensional, the PIC sees it as a single block of memory. For example if you have 'myVar[2][3]' the PIC interprets that as 'start of myVar + (2 x size of first dimension) + 3' . Try thinking of a single dimension array as a list and a multi-dimentsional array as several lists, one after the other. When you know how long each list has reserved for it, you can uses the index numbers to calculate how far into the combined lists you are referring to.

Brian.
 


THANK YOU SIR For your valuable reply !
But in this point I have a question.
that means if I use DT directive, then I can't use fsr and indf,right ?!
please reply!
 

DT has absolutely nothing to do with any instruction.

All DT does is allow you to enter values directly into program space. Normally, the assembler converts instructions to binary values but sometimes you need to manually force values as well. For example when you want to place a block of values in a look-up table. DT is a directive to the assembler, not an instruction. The PIC doesn't exexcute a DT statement, it just tells the assembler to store the following bytes so the program can access them later. The data in the DT statement is placed inside the .hex file where it can be accessed by the program as required. If you check the help files it explains that DT is just one of several similar directives:
DT = "Define Table" puts your table of data in memory
DB = "Delare Byte" puts a single byte in memory
DE = "Declare EEPROM" puts your data in the EEPROM memory space
DW = "Declare Word" puts a single word of data in memory
DA = "Define ASCII" puts data in text form into memory
and there are a few others too.

What is important to understand is that a directive tells the assembler to do something, it doesn't make the PIC do something. Because a directive is only recognised by the assembler, whatever it does is decided at the time you run the assembler and although it will modify the resulting hex file, it doesn't itself produce any instructions the PIC will run.

So you certainly can still use FSR and INDF registers, and all other instructions as well!

Brian.
 


THANK YOU SIR FOR VALUABLE REPLY.
So if I use DT directive then I can't use FSR,then how to access array using DT directive?

For example if you have 'myVar[2][3]' the PIC interprets that as 'start of myVar + (2 x size of first dimension) + 3' .
Also sir please explain this example!
 

FSR and INDF are registers inside the PIC. You select an address by putting its number in FSR and then access it for reading or writing through INDF. Its as though INDF could be moved anywhere in the address space by loading it's new address in the FSR.

DT is not a program instruction, the PIC doesn't execute it. It is a 'directive', it is an instruction only recognized by the assembler and used to embed data directly into the resulting hex file. After the assembler has produced the hex file it plays no further part. DT tells the assembler that the following values are a table and should be saved as they are 'in line' with the assembled instructions.

The ADDRESS of the DT table can be used by the program by giving it a label (symbol) and that can be used elsewhere in the program.

Example from one of my old projects:

Code:
;4-bit to ascii hex conversion table
convert:
    andlw 0x0F                                                ;mask upper bits
    addwf PCL,f                                                ;jump ahead and retlw with data
    dt '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'

It's a simple routine to convert a binary number to it's printable code. Consider how it could be written if the 'dt' had not been used, it would be very difficult to place the values '0' - 'F' into memory so the program could use them.

If you wanted to use FSR and INDF on a table like that you could do this:
Code:
myLabel dt '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
        movlw myLabel   ; load the address of myLabel into W
        movwf FSR0       ; FSR0 now holds the address of myLabel
        movf INDF0,w    ; W now holds '0' because that's what FSR pointed at.
        incf FSR0        ; add one to the FSR0 register
        movf INDF0,w    ; W now holds '1' because FSR is looking at the next address in the table

Brian.
 

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…