| Home | Price List | Order Info | Microcontrollers | Assembler | C and C++ |
| Writing PIC Programmes Larger Than 2K |
|
For our American friends I will translate the title:- Writing PIC programs larger than 2K (Sorry people but I think the Oxford dictionary has it wrong - the true English is in the title that I have chosen.....) The EPE September 2003 edition arrived a few hours ago. One article which caught my eye is about the use of the HIGH operator in MPASM. (In our assembler MSB[LABEL] has the same function). The author Malcolm Wiles suggests that by setting PCLATH manually rather than using LCALL and LGOTO that a contiguous programme larger than 2k can be successfully written. He is quite right but he does not fully explain the problem. Consider this section of programme code:-
If count starts with a value of 10 the programme will loop back to LABEL1 ten times then return. This section of programme will only work correctly if the location of LABEL1 is within the same 2k memory page as the GOTO LABEL1 instruction. If we want this section of code to be able to float in a section of memory larger than 2k we cannot just change to using LCALL and LGOTO. The reason is that LGOTO creates three instructions so it cannot be used after DECFSZ because when the test is met just one instruction is skipped over. If we set PCLATH manually rather than using LGOTO we are able to place the two extra instructions before DECFSZ and so avoid the problem. The modified code is as follows:-
This will work correctly anywhere in memory even when the 2k boundary crosses the middle of the routine. Take special notice that PCLATH must be set immediately before DECFSZ. I have also chosen to set PCLATH manually before the CALL. LCALL could be used in this routine without the two preceding lines of text but as LCALL also sets PCLATH back to its original value that option would create another two instructions. My Viewpoint There is no doubt that if we manually set PCLATH as in the above example that PIC code can be written which occupies the whole memory as one contiguous programme. In the real world any PIC programme which exceeds 2k is a very large programme. Remember that this size in a properly organised programme will not include lookup data as that must always be organised into a known area of the memory. So the idea that this manual technique will actually make the programme easier to be free of bugs can only be wrong. My advice when the programme is very large is to place all the major subroutines into high memory and keep all the main code within the first 2k. Then create a sequence of LCALL instructions with RETURNs at the end of your code making sure that they are within the first 2k. By doing it this way all your CALL and GOTO instructions will be normal instructions. Any that call into the high memory will go via your call table. Do something like add a Z to the front of the label when it is in high memory and then life becomes very simple AND simple programming gives the greatest freedom from bugs. For more information about the use of high memory addresses see page 219 and 223 of Experimenting with the PIC16F877 An example programme of a simple 4 bit counter is shown below. This can be run on the Brunning Software programmer module using a PIC with at least 4k of memory. When the two push buttons are pressed alternatively so the count shown on the 4 LEDs goes from zero to 15 then starts again.
Note that each subroutine in the high memory should ideally be completely self contained in which case all the CALLs and GOTOs will be normal. Calls can be made to external subroutines in which case it is best to use LCALL to the name in your call table even when the routine being called is in the same area of high memory. This prevents the problems that would result if at a later date the subroutines are moved when you have long forgotten that certain ones need to be in the same 2k area of memory. The programme shown above is the complete text which needs to be typed into BWPICA. If you have never used the Brunning Software PIC assembler you may be surprised to see that there are no definitions needed. BWPICA has these programmed into it which creates a more reliable system. For example bit 1 of port B is called RB1 if RB1 is used with port A (e.g. BCF PORTA,RB1) BWPICA will give an error message. All other assemblers will accept this instruction although it obviously has an error. If you have any comments on this please email high@brunningsoftware.co.uk |