Microchip Technologies

Gotchas

Also: MPASM,  MPLAB Bugs, FAQ, Port Pin GotchasElectronic Gotchas

http://www.microchip.com/10/lit/suppdoc/errata/index.htm is the current Microchip errata page.


RB3 must be pulled low on a 'F87xx series if LVP is not disabled
Robert Rolf says: The default of the F87xx series [is] LVP (low voltage programming) ON! [You] must ensure that RB3 is pulled low, particularly at reset, or the part goes into programming mode. see 16F877/high voltage programming

You can save memory with db vice dt for string literals on some chips.
Walter Quitt found:
ent1 dt "123"

assembles to

retlw 0x31
retlw 0x32
retlw 0x33

which uses more memory than necessary on processors that can directly access the memory

string db A'1',A'2',A'3',0x00

assembles to

0x31,0x32,0x33,0x00

bytes in ascending memory. No useless retlw opcode bytes shoved between them as with dt. (see memory )


Watch out for the difference between equates and defines
Q: Given the following code:
 buffer = 31     ; String buffer at end of memory.
 ASC_0 = '0'     ; ASCII numbers: 30h thru 39h.

Does the above assign the value to hex 31 to a variable called "buffer" and assign the value to hex 30 to a variable called "ASC_0" or does it set up a register called "buffer" at hex address 31 and set a register called "ASC_0" at hex address 30 ('0").
A: Dr. Imre Bartfai [root at PROF.PMMF.HU] says:

Neither. It says purely the compiler: if you find the word 'buffer', replace it with '31'. It is completely irrelevant what do you intend thereafter. It may be as well a register naming act as well as naming a constant. I guess the 1st assignment would a register, and the 2nd one is a named constant. Note, that the difference is purely the question of the context. E. g. you can write
        movlw   buffer
        movwf   buffer

The 1st statement loads the constant 31 to W, the 2nd one moves W into the register #31.


Watch out for the difference between "=" and "equ"
Q: Is "=" the same as "equ"
A: Dr. Imre Bartfai [root at PROF.PMMF.HU] says:
Almost. Theoretically, equated variables (they are in fact compiler variables, or - if you prefer - symbols) can not be changed afterwards, but assigned ["="] can.

END is not SLEEP or Sometimes the damn things just won't stop!
Q: Why is my PIC program runnining in a loop when I just want it to run once each time the PIC is reset? My program ends with
          movf ADRESH,w
          movwf PORTC
          end


A: Robert A. LaBudde says:

You're rolling off the end of memory and then restarting at x'0000'. If you want it to quit at the 'end', you need to tell the processor to stop. The 'end' just tells MPASM it's the end of your source file. The PIC just goes on to the next instruction. A reasonable choice would be a SLEEP instruction, or an endless loop:
        label:  goto    label


Also check the following items:

  1. Watch Dog Timer?
  2. Power spikes on Vcc causing a reset?
  3. Noise spikes on /MCLR causing a reset?
  4. Bad IC?
  5. EMI noise causing a reset?
  6. Add "& _LVP_OFF" to the end of your __CONFIG line to disable Low Voltage Programming.

Source code line missing in AN526 (DS00526E page 22)?
Martin Schaefer [schaefer at elektronik21.de] of elektronik 21 GmbH, Germany says
IMHO, there is a source code line missing in AN526 (DS00526E page 22). Between line 121 and 122 there should be the instruction
        incf    ACCbLO

Watch out for maximum speed limits during low voltage operation
When running a pic at low voltage, the maximum clock speeds are not supported... check the data sheet carefully.

16F873's start with RA0- as A/D not digital IO
Don't think that signs will be removed in MPASM for calculations or other intermediate values with constant expressions
Martin Schaefer [schaefer at elektronik21.de] of elektronik 21 GmbH, Germany says
I spent some time in figuring out, that the description for constants in the MPASM User's Guide is not correct. In DS33014G-page 91 it read's:
NOTE: Intermediate values in constant expressions are treatet as 32-bit unsigned integers.

This is definitely wrong. Intermediate values are 32-bit SIGNED integers.

Immediately before this note, you can read, that "Constants can be optionally preceded by a plus or minus sign." This would not be possible, if intermediate values would be treated as unsigned.

Internal EEPROM access on 12CExxx devices
The emulators don't work the same way the production parts do, the sample code is wrong.

Check what PAGESEL and BANKSEL are actually produceing: They might overwrite W.
In MPASM you can add a PAGESEL before each and every jump, call, etc.. This is nice because it still allows you to write relocatable modules that can be linked with code from other languages (C for example) after assembly. PAGESEL and BANKSEL may assemble to either a set of 0 to 3 BCF/BSF instructions or to a MOVLW followed by a MOVWF PCLATH. Beware that W may get trashed. Use the sequence PAGESEL , MOVLW (or whatever), CALL to avoid this. I'm told that future versions of MPASM will settle on BCF/BSF sequences for PAGESEL and add a new PAGESELW that always does the MOVLW thing.

Make sure your interrupt enable didn't get re-enabled by an interrupt occuring just as you cleared it.
John [jsand at PIXIE.CO.ZA] says:
After disabling interrupts i.e.
    bcf    intcon,gie

complete safety is not assured unless you check the global enable bit to see that it *really* is as expected (clear, that is).

My trouble with this magically vanished when I started to use macros for int. enable/disable:


int_off         MACRO                ;disables all interrupts
                     bcf intcon,gie
                     btfsc intcon,gie  ;make sure bit cleared (int could
                                                   ;have occurred 1/2way
thru instruction)
                     goto $-2
           ENDM

int_on         MACRO               ;re-enable interrupts
                     bsf intcon,gie
           ENDM


Michael Rigby-Jones [mrjones at NORTELNETWORKS.COM] says:

...this was a known problem with the 16C6X and 16C7X devices. The datasheet says:
"If an interrupt occurs while the Global Interrupt Enable (GIE) bit isbeing cleared, the GIE bit may unintentionaly be re-enabled by the users Interrupt Service Routine (the RETFIE instruction)." It then goes on to describe the work around which is as per the macro's above.


Roman Black points out that as per the 16C84 datasheet, this is fixed in the 16F84 and presumably any later chips.


ICE 2000 locks up when attempting to step through a program memory read routine.
Olin Lathrop [olin at cognivis.com] of cognivis.com says:
The only problem I have run into with the ICE and 16F87x parts is when trying to access the program memory as data. You can't step thru a program memory read, or the whole system will lock up and complain about stack overflow. You can run thru program memory reads, but they take *much* longer than the real thing. One of my projects reads some audio data in program memory and chugs it out via PWM in the interrupt routine. This appeared not to work at all. Eventually I realized that the ICE was running so slowly that it looked broken, and that the PWM also got interrupted somehow during a program memory read. I programmed a real chip with the same code and everything worked fine.

See also:

PICList post "Please help!, retfie fast does not restore w."

Comments:

See:

Interested:

Questions: