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.

16F628A PCL/PCLATH Question

Status
Not open for further replies.

Jon Wilder

Active Member
If I'm understanding this correctly, the contents of PCLATH only get written to PCH in the event of a write to PCL?
 
Yes, you've got it in one.

PCLATH is only needed because the program counter is larger than 8 bits.
 
OK cool...yeah I was having an issue with table lookups and realized that when the table is located on a memory page other than page zero you had to write the page byte to PCLATH to keep it from jumping to a location on page zero. It also seems that the page location of the actual call instruction that calls the table doesn't matter, but that the page location of the table is what matters regardless of the location of the instruction that called it. In other words, if both the table and the table call instruction were both on page 1, you still had to write that to PCLATH otherwise it would load all zeroes from PCLATH to PCH and jump back to page zero. I'm assuming here that while PCH follows the current program memory page that the PC is on, PCLATH does not follow this along with PCH and is why PCLATH must always be loaded with the page byte when calling a table that resides on any PMP other than page zero?
 
Last edited:
Hey Jon. Just want to clarify some things for you... When you execute a normal instruction, PCL is advanced by 1, as you probably know. If PCL is at 255, it will rollover to 0 and PCLATH will be advanced by 1. Both PCL and PCLATH are writable registers.

This means that if we add for example 10 to PCL and store it in itself, PCL will advance by 10. If PCL was at around 255, it will rollover, but because this is an ADD instruction, PCLATH is not affected. This can leave you somewhere bad in code. To avoid this, it is routine to check if an overflow will occur and if it will manually increment PCLATH.

Hope this helped,
Mike
 
Hey Jon. Just want to clarify some things for you... When you execute a normal instruction, PCL is advanced by 1, as you probably know. If PCL is at 255, it will rollover to 0 and PCLATH will be advanced by 1. Both PCL and PCLATH are writable registers.

This means that if we add for example 10 to PCL and store it in itself, PCL will advance by 10. If PCL was at around 255, it will rollover, but because this is an ADD instruction, PCLATH is not affected. This can leave you somewhere bad in code. To avoid this, it is routine to check if an overflow will occur and if it will manually increment PCLATH.

Hope this helped,
Mike

This is confusing.

Correct me if I'm wrong but as I thought I understood it -

PCL is incremented by 1 per instruction. Once it reaches 0xFF (255), it rolls over and increments PCH by 1. But PCLATH's contents do not change unless you write data to it.

However, when you add say 10 to PCL, PCL advances by 10 and the current contents of PCLATH are loaded into PCH simultaneously, which overwrites the current data in PCH. If PCH was incremented once already but PCLATH was never written to and is still in its default state, this would reset PCH to 0x00 once the current contents of PCLATH are loaded into PCH and cause the program counter to jump to an unknown location on the first 255 lines of code.

Is this correct?
 
Last edited:
This is confusing.

Correct me if I'm wrong but as I thought I understood it -

PCL is incremented by 1 per instruction. Once it reaches 0xFF (255), it rolls over and increments PCH by 1. But PCLATH's contents do not change unless you write data to it.

However, when you add say 10 to PCL, PCL advances by 10 and the current contents of PCLATH are loaded into PCH simultaneously, which overwrites the current data in PCH. If PCH was incremented once already but PCLATH was never written to and is still in its default state, this would reset PCH to 0x00 once the current contents of PCLATH are loaded into PCH and cause the program counter to jump to an unknown location on the first 255 lines of code.

Is this correct?

Yes, that is correct. PCLATH only gets changed if it is written to, otherwise it keeps the same value.

Mike.
 
Last edited:
birdman0_o said:
PCH is PCLATH, they aren't two separate registers.


This is not how they explain it at all. They explain it as if PCH is its own register and is not directly accessible and PCLATH is a "buffer register" that can access PCH and you use PCLATH to indirectly write to PCH, but the contents you write to PCLATH only get written to PCH upon initiating a write instruction to PCL either by a movwf PCL, addwf PCL,F, incf PCL,F, decf PCL,F, etc etc.

It's not that I'm doubting you at all...it's just that what you're stating seems to conflict with what the data sheet states.
 
Last edited:
I apologize! I personally struggled with this table stuff last year and actually gave up on it because I could never get it to work. I think I see why now!

Indeed PCLATH and PCH are two different monsters. Apparently the only time when PCLATH is important is when you have more than 2kbytes of code OR when you add to PCL.

In the first case, the program counter steals 2 bits from PCLATH whenever its doing a goto instruction. With less than 2kb of code this will be 00, so no PCLATH adjusting is necessary.

In the 2nd case, it steals PCLATH (5 bits) to finish off the 'computed goto'. Therefore whenever implementing a table, unless you are on page 0 (which is where I always put my table, didn't know why it worked until now) you MUST preload PCLATH with the HIGH address of your table!

Extra precaution is needed for long tables!

I apologize once again, but I think now we both understand what is going on :)
 
I apologize! I personally struggled with this table stuff last year and actually gave up on it because I could never get it to work. I think I see why now!

Indeed PCLATH and PCH are two different monsters. Apparently the only time when PCLATH is important is when you have more than 2kbytes of code OR when you add to PCL.

In the first case, the program counter steals 2 bits from PCLATH whenever its doing a goto instruction. With less than 2kb of code this will be 00, so no PCLATH adjusting is necessary.

In the 2nd case, it steals PCLATH (5 bits) to finish off the 'computed goto'. Therefore whenever implementing a table, unless you are on page 0 (which is where I always put my table, didn't know why it worked until now) you MUST preload PCLATH with the HIGH address of your table!

Extra precaution is needed for long tables!

I apologize once again, but I think now we both understand what is going on :)

And this is what I just recently learned as I too was having the same issue if my table happened to be located anywhere other than the first 255 lines of code. The Microchip instructional videos were what got my attention on this matter.

I ran into this very issue recently on a bit of MIDI code I was writing for a MIDI decoder I'm making for a guitar amp. The table contains the default values that get loaded into EEPROM when the "Restore Defaults" routine is called. As I added lines of code at the beginning of the program that pushed the table onto the next 255 lines of code and it was then that the issue appeared. I knew there had to be a much easier way of doing this other than relocating the table to the first 255 lines of code and it was the video that got me to research it.

So I sim'ed the table in MPLAB to see what was happening. Then once I had the program increment PCLATH by 1 just prior to the table call instruction, it started working properly. It was then that I realized what was happening along with how PCLATH offsets it.

What I didn't know was if the data contained in PCLATH got loaded into PCH any other time other than when it called the table, which was the purpose of this thread.

However, in my code I now have it increment PCLATH just prior to the table call, THEN once it returns from the table I have it decriment PCLATH back to its default value just to avoid any potential mishaps.

Now the other question I have is...if 2K is considered a "page boundary", what are the 0xFF/255 boundaries known as?
 
Last edited:
Think of a page boundary as a book, it contains a whole bunch of pages, but you can only read within that book. They are both called page boundaries, just used in different contexts.

Instead of 'incrementing' PCLATH load it with the right value with MOVLW HIGH Table and replace Table with the name of yours...If you do this for every table, you won't need to decrease PCLATH again after.
 
Instead of 'incrementing' PCLATH load it with the right value with MOVLW HIGH Table and replace Table with the name of yours...If you do this for every table, you won't need to decrease PCLATH again after.

I take it the word "HIGH" is a nemonic that the assembler knows is the high byte of the table address?
 
Last edited:
Status
Not open for further replies.
Back
Top