From: "Josh Koffman" > Hi all. I've come up against a part of the PIC that I find really hard > to understand. So I'm going to give my interpretation, then hopefully > you can correct me where I am wrong. Basically this involves the > differences between the PCL and jump tables, and the FSR and indirect > addressing. > > To use the FSR, basically you load an address into it, for example 0x50. > Then you can access that memory location using INDR right? And if I do > something like "incf fsr" I can now access 0x51 right? As far as I can > tell, this would be usefull for storing a bunch of variables and then > recalling them later. The advantage is I can change memory locations > easily (by modifying the FSR), and if needed I can access the data out > of order. However, if I wanted to set up some sort of table or something > using the FSR, at the beginning of my code, I'd have to load the data > into the table, or it would be empty (or random). Yeah, you have a pretty good idea of how this works. FSR can be used to index thru an array of variable data. > Now, the PCL I know less about. The basic idea as I understand it is > that dependant on some sort of decision, I can load a value into the PCL > and then on the next instruction, program execution will continue from > that location. But how do I know what value to load? Do I just use any > open value, then put an ORG instruction in front of the code that I want > there? How do I return to my main code again? Ok, questions aside, the > advantages here would be that I could have large tables and that they > could live in program memory, and not take up valuable data memory > right? But how do I deal with program memory banks? I have never figured > that out either. How do I know when I need to switch banks? The PCL is the low-order bits of the program counter, ie: the register that the PIC uses to find the next instruction to execute. Normally, it is simply automatically incremented as each instruction is executed so that instructions are executed consecutively. GOTOs and CALLs modify it to jump to a different location in your program. (Depending on the specific PIC, you may also have to set one or more program memory page bits or the PCLATH register before the GOTO or CALL). Now to use PCL for table lookup you take advantage of the fact that it is visible just like any other register. You would take a value that is known to be within the range of valid indices for the table and add it to the PCL register. This will immediately skip forward that many instructions. By putting all of this in a subroutine and using RETLW instructions as the instructions in the table you get the ability to look up a value in a constant table. Here is an example (assuming, for now, that everything fits in one code page): ... call table_lookup ; look up value in table .... ; now the answer is in W and then somewhere else in your program: table_lookup: movf index_value,W ; get table index addwf PCL,F ; add W to PCL to jump into following table retlw value_0 ; value to return if W was zero retlw value_1 ;value to return if W was one .... retlw value_N ; value to return if W was N Things get trickier when the lookup table can span pages of program space. I expect Olin Lathrop will likely chime in to show you that. What I'll do however, is show you one way of handling a table of exactly 256 entries, as you request for your application. For this example I'll assume you have a PIC with a PCLATH register, but the same principles apply if you don't. First, the call to do the lookup: At this point we assume that PCLATH is pointing to the page containing your main code: ... call table_lookup ; look up value in table movwf lookup_result ; store the resulting value now the answer is in W, but PCLATH is no longer pointing to our main code page, so we might want to put it back with something like this: movlw high(main_code_page) ; Get 8 msbits of main code page movwf PCLATH And later in the same page as your main code: table_lookup: movlw high(lookup_values) ; Get 8 msbits of address of lookup table values movwf PCLATH ; Get ready to jump into the lookup table values movf index_value,W ; get table index movwf PCL ; Jump to the lookup table values Someplace else in your code you place the 256 entry table, which has to start on a page (256-byte) boundary. For example: org 0x200 lookup_values: ; start of table retlw value_0 ;value to return for index of 0 retlw value_1 ; value to return for index of 1 ... retlw value_255 ; value to return for index of 255 Phew! Hope that isn't too confusing. Bob Ammerman RAm Systems -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics