| Home: | |
| Support home: | |
| General Topics: | ||
| FAQ | ||
| MCU selector guide | ||
| Developer's resources | ||
| Downloads and patches | ||
| Sample programs | ||
The Microchip PICmicro uses a sequence known as read-modify-write when changing an output state on a pin. This can cause unexpected behavior under certain circumstances.
When your program changes a specific pin, the PICmicro first reads the state of all the pins on the port and stores this data in a register. The bit that corresponds to the pin where you've commanded a change is set, then the whole value is written back to the port.
The problems arise when pins on the same port are changed in rapid succession or when an output pin is loaded in such a way that its logic state is affected by the load. Examples of such loads are LEDs without current-limiting resistors or loads with high capacitance or inductance.
Here's an example. Let's say that you want to switch four modules on and off by powering each with a pin on PORTB of your PIC. You connect the power supply pins of each respective module to RB0, RB1, RB2, and RB3. Each module has a small bypass capacitor that is connected from power to ground.
In your program, you are diligent and first set the TRISB register so that RB0:RB3 are outputs:
TRISB = %11110000
At some later point in your code, you need to turn all the modules on, so you write:
PORTB.0 = 1
PORTB.1 = 1
PORTB.2 = 1
PORTB.3 = 1
It doesn't work! Only the module on RB3 comes on. The problem arises because of the time it takes to bring each line to a stable five volts. Because of the bypass capacitor on each module, the voltage does not rise immediately when you set the controlling pin high. There is a delay while the bypass cap on the module charges.
RB0 is set high, but when RB1 is set in turn, the PIC reads the port and sees that RB0 is low (because the cap hasn't allowed the pin to come up). When the modified PORTB value is written back, RB0 is set low. Subsequently, the same happens to RB1 and RB2. Each pin is set high for an instant, but set low again when another pin on the port is changed. Because RB3 is the last pin on the port to be set, it stays high long enough for the voltage to stabilize.
There are different ways to work around this. You might insert delays to let each pin stabilize before going to the next one:
PORTB.0 = 1
PAUSE 1
PORTB.1 = 1
PAUSE 1
PORTB.2 = 1
PAUSE 1
PORTB.3 = 1
Another method would be set all the pins on the port with a single command:
PORTB = %00001111
Top
You can reprogram a corrupted oscillator calibration value use the Serial Number function of one of our programmers (EPIC or Serial Programmer). You will first have to set the programmer's options to allow erasure and programming of the calibration space, as well as enable the serial number function. See the programmer's help file for details.
The Serial Number window can be found under the View menu in either programming software. You can set the location you want to write, the value, and the prefix. The calibration value should be restored with a prefix of 34 hex. (All the values in the Serial Number window are hex.)
For example, let's say you've got a 12F675 that has been completely erased. The calibration location reads 3fff. You know the OSCCAL setting should be D0h, because you've run a program to test different values. In the Serial Number window, you need to set Serial Number = D0, Increment By = 0, Starting Address = 3ff, Number Of Locations = 1, and Add Prefix Byte = 34.
Make sure you shut off the serial number programming and reset your options when you're done. If you leave the serial number enabled and don't realize it, it will write into code space every time your program a PIC. You can spend a LOT of time trying to track down the problem later.
Top
Even the low-power parts need to powered at 5V to properly erase and program. If you are trying to program in-circuit with your target board powering the chip at 3.3V, you may encounter problems.
Top
On the newer flash parts, there can be quite a difference. You should recompile for the exact part you are using, especially if it has features not found on its older counterpart (like comparators on the 877A, not found on the 877).
One of the biggest differences is the programming algorithm. If your non-A part will program, but the A part won't, you probably need specific support for the A part in your programmer's software.
Top
As always the fix is in the datasheet. On most of the parts so equipped, set the OSCCON register to a value of $60 for 4MHz operation. This should be the first thing you do in your program.
Top
If there are analog comparators or converters on the pin, these are probably enabled by default. Look for labels like "ANx" or "CxOUT". Investigate any function that is unfamiliar to you. Find the module that the labels apply to and look at the control registers. The registers can be set to disable the functions.
Some examples of this on popular PICMicros are:
Analog converters on 16F87x, 16F87xA, 18F252, 18F452 - set ADCON1 to $07
Analog comparators on 12F675, 16F676, 16F62x, 16F62xA - set CMCON to $07
Analog converters on larger 18F parts like 18F4620 - set ADCON1 to $0F
Analog converters on recent 12F and 16F parts like 12F675 and 16F88 - set ANSEL to $00
There are too many variations to list here. As always, the datasheet for your particular PICMicro will hold the key.
Top