Hi Lee - I am not an expert on the PCLATH register, but I have had some very unpleasant experiences because of it (rather because of my lack of knowledge of it). I will try to respond to some of your questions the best I can. Since this is long, let me summarize my recommendations: 1) Be SURE interrupts are off when taking a computed branch, whether a jump or a call. The interrupt service routine can change the value of PCLATH and mess up the call; 2) Try to set aside a "page" of memory (e.g. 1F00-1FFF) for lookup tables. That will eliminate the concern for rolling over the low byte of the PC when computing the table address. This obviously will not apply if your tables are > 256 bytes; 3) Be SURE your computed address is limited to the number of table elements you have. Otherwise, you might vector into la-la land. Hope this helps. --- Lou >Date: Wed, 24 Sep 1997 21:02:20 -0400 >From: Lee Hewitt >Subject: Please help me with PCLATH > >Hello All, > I know that this is a simple question which has no doubt been >asked many times before, but I cannot understand or make any sense of the >PCLATH in relation to look-up tables. When I first started to write PIC >assembly code (about a month back) I never really understood the operation of >the PCLATH in particular the importance of writing a value to the register >prior to calling a look-up table with many entries, each of which being >returned by modification of the program counter value using ADDWF PCL,F as a >computed goto. I have studied AN556 which supposedly clarifies the problem, >but what numerical values are represented by HIGH Table and LOW Table ?, and The value of PCLATH is only written to the high byte of the PC during certain instructions which write to the program counter (e.g. call, goto, addwf PCL). HIGH and LOW just take the high byte and low byte value of the address (Table in this case). That becomes important when your jump address is not within the "page" (i.e. low byte limit) of your table lookup routine. Remember that if you do not ORG your table at a certain address and know its length, the upper byte of the PC could change in the middle of the table. >how do you determine where in program memory a look-up table should be placed >in order to prevent such problems occurring ? - (does this depend upon the >length of the table, i.e. the number of RETLW instructions). Yes, and the starting location of the table. >I can see that since only the low byte of the program counter (bits 0 through >to 7 of the PCL) are manipulated by any instruction with the PCL as the >destination, then only 256 bytes of program space can be addressed (i.e from >PCL = 00000000 to PCL = 11111111), but how do I determine what value to load >in to PCLATH in order to prevent the PCL rolling over from 11111111 to >00000000 ?. You must compute the high and low bytes of the PC as an ordinary 16-bit value. Then you load that into the program counter. My experience has been with the 17C44 where you compute the value, load the MS byte into PCLATH, then write the LS byte to PCL. >Am I correct in assuming that upon power up the PIC 16C65 for example, will >commence program execution at the reset vector (PCL = 00000000) but what >value is in PCLATH, 00000 ?; Yes. It is set to 0000 on reset (at least it is for a 17C44) > as the program continues execution does the PCL >continue to increment after every instruction unless a goto or call is >encountered, and if so does this mean that I have to count each instruction >in my program in order to determine where in program memory a look-up table >should be placed ?. Let the assembler do that. It knows the address of the table. And you can get that with the HIGH Addr and LOW Addr terms. >If I consider the PIC16C84 with 1k of program memory, then right at the top >of the memory (03FFh) will the program counter be set at PCLATH = 00011 and >the PCL = 11111111 (i.e. 03FFh) ? - Am I correct here ?. Yes. > Similarly if I now >consider the PIC16C65 with 4k of program memory (1FFFh), will the program >counter be set at PCLATH = 1F and the PCL = 11111111 (i.e. 1FFF) ?. Yes. > From all >this then how do I configure the PCLATH for maximum addressing range - is >this the objective or am I totally confused somewhere ?. - i.e. In the case >of the PIC16C84, should I set the PCLATH to 0x03 for maximum addressing >range, and likewise in the case of the PIC16C65 should I configure the PCLATH >to 0x1F ?, and where in the program do I do this ? at the start of the >listing or in the actual look-up table before the ANDLW PCL,F instruction ?. The reason PCLATH exists is to allow you to write a computed address value directly into the program counter. Normally, you do not have to do anything with it. You cannot access (write) the high byte of the PC directly. That is what PCLATH is for. You load your computed value into PCLATH, then when you do a jump, call or whatever, PCLATH is written to the high byte of the program counter (PCH) before the jump.