I have problems when writing to multiple pins on a port in rapid succession. When I insert pauses, it works.
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
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
PORTB.1 = 1
PORTB.2 = 1
PORTB.3 = 1
Another method would be set all the pins on the port with a single
PORTB = %00001111
I've somehow managed to erase the factory calibration value in a PICmicro. Is there a way to restore the value?
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.
Can I compile for and program the low-power, "LF" parts like the 16LF877?
Yes, these parts use the same programming algorithms and memory maps as their normal counterparts. Select 16F877 to program the 16LF877.
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.
Is there a difference between a part with an "A" suffix and one without? For example 16F877 vs 16F877A.
On most of the non-flash parts, the parts are pretty much the same. You should always target the exact part number that is printed on the chip, just to be sure.
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.
I've configured my PICMicro to run on its internal oscillator, but it doesn't seem to run or runs VERY slowly.
Some of the recent PICs with internal oscillators can be configured to run different speeds. Most with this capability come up by default at 32KHz. That's quite a bit slower than the 4MHz the compiler expects and can appear not to run at all.
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.
Certain pins on certain ports of my PICMicro don't behave as expected. Normal I/O doesn't work, or only works partially.
The first step is to check the datasheet for the part and look specifically at the functions assigned to the pin you're trying to use.
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.
Configuration Setting "Enhanced CPU"
Enhanced CPU should be disabled when using our products. The latest revision of PicBasic Pro disables this by default.