3
\$\begingroup\$

I have been learning(trying to at least) how to work with pic microcontrollers, and I have noticed this behavior that I am not sure whether it is just my fault or is supposed to happen. I wrote the below program with hopes to make an led blink. It does blink just fine, when connected to the pin labeled RA2, but when I connect the led to pin 15 (labeled RA6/OSC2/CLKO on datasheet) the led stays on, as though I had connected it to Vdd. Then when I put it back in RA2 where it belongs, it is off. The only way to get it back on again is connecting a 10k resistor between Vdd and MCLR (like how it is when programming). What is happening here? MCLR is also needed when tapping it to some other pins. Am I causing damage?
The circuit is 3 AA batteries powering the pic, with a 330 resistor and 3mm led in series running from pin 1 (RA2) to pin 5 (ground).
pic16f88 datasheet
Code:

#include <xc.h>

__CONFIG(MCLRE_ON & CP_OFF & WDTE_OFF);

void main(){

    TRISA = 0x0000;
   // RB6 = 0b000010;
    for(;;){
        RA2 = 1;
        Wait();
        RA2 = 0;
        Wait();
    }
}
int Wait(void) // gives me a delay of 1/3rd a second or so
{
for (int i = 0; i < 50; i++)
 {
 }
}
\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

You need to tie the MCLR pin high during normal operation otherwise the chip will be held in reset. Notice the bar over MCLR, this means it is active low.
Use a resistor between MCLR and Vdd of around 10kΩ (<40kΩ)
See p.132/133 of datasheet.

\$\endgroup\$
10
  • \$\begingroup\$ So I need to keep that 10kΩ resistor there permanently? It seemed to work ok when that wasn't there. What does being held in reset do? Would putting _MCLRE_OFF in the config portion of the program fix this? \$\endgroup\$ Commented Aug 25, 2012 at 22:52
  • \$\begingroup\$ It will work intermittently when it's not there due to the very high impedance of the CMOS input - just touching it with your hand will make a difference when it's floating. If the part is held in reset (MCLR actually pulled to ground rather than floating) then the main oscillator is shut down and the part "sleeps" (very low power consumption) Turning MCLR off will make the pin state irrelevant, yes. \$\endgroup\$
    – Oli Glaser
    Commented Aug 25, 2012 at 22:58
  • \$\begingroup\$ Which is better/safer/smarter for the mcu, keeping mclr off in the config, or keeping it on and keeping the resistor there. What is usually done? \$\endgroup\$ Commented Aug 25, 2012 at 23:06
  • \$\begingroup\$ It's up to you, if you don't need to be able to externally reset the micro (e.g. button press) then turning it off and saving a couple of components is an option. Microchips have many app notes on these subjects, I'd have a search on their site and do a bit of reading. \$\endgroup\$
    – Oli Glaser
    Commented Aug 25, 2012 at 23:19
  • \$\begingroup\$ That works well, thanks. I am noticing that if I touch pin 9 (RB3/PGM/CCP1) with my finger the led will hold on and then go off. After about 5 seconds it will turn back on. What is happening there? \$\endgroup\$ Commented Aug 26, 2012 at 0:18
2
\$\begingroup\$

Your problem lies on the !MCLR pin. When you program the PIC you are using the VPP function, but the same pin has the !MCLR (Master Clear) function, and since this function is active low, you need to assure this pin stays high so the PIC can run your code. As Oli said, you can achieve this by connecting a pull-up resistor for to the !MCLR pin.

As an alternative you can disable the MCLR function by reseting (writing a 0) the MCLRE bit on the CONFIG1 register.

__CONFIG(MCLRE_OFF & CP_OFF & WDTE_OFF);

Detail of the MCLRE bit from page 130 of the datasheet:

MCLRE: RA5/MCLR/VPP Pin Function Select bit
1 = RA5/MCLR/VPP pin function is MCLR
0 = RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD


Added

Regarding the Read-Modify-Write issue, it happens due to the way the PIC works. 8 bit PICs need four clock cycles for each instruction cycle. Writes are made on the last clock cycle, while reads are made on the first clock cycle. This may cause problems when you are working with different bits of the same port.

Suppose you have the following code:

RA0 = 1;
RA1 = 1;

You would expect that both RA0 and RA1 be high after running this code. This may not be the case. If you have all bits set to 0 on PORTA, when you execute RA0 = 1 the PIC will read the value on PORTA on the first clock cycle, set the bit 0, and write the result back to PORTA. So far no problem, but when you execute the second instruction (RA1 = 1), the PIC will first read the value of PORTA, and most likely the RA0 pin had not time to rise to 1, then the value read for that pin is 0 instead of 1, then the bit 1 is set, then the result is written back to PORTA, but only the bit 1 is set.

To avoid this you can add delays between the instructions like this:

RA0 = 1;
asm("nop");  // No operation
RA1 = 1;

One nop instruction should be enough.

In you code you should not have this problem for two reasons:

  1. You are not changing different bits on PORTA
  2. You have a wait instruction between writes the bits of PORTA

The shadow register that Leon was talking about consists on a register where the individual bits are modified before writing the whole register to the PORT.

\$\endgroup\$
1
\$\begingroup\$

You may want to make sure your config fuses are set such that RA6 is a GPIO pin and not the CLKO function that the pin can also take on. I ran into this problem with a simple program and CCS' compiler. The compiler has such poor documentation that it's impossible to know exactly what is happening without looking at the fuse bits yourself.

I would have expected that whether the LED is on RA2 or RA6, you would have erratic behaviour if MCLR# isn't pulled high. Perhaps RA6 is closer to MCLR# and the problem is exacerbated; not sure.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.