Skip to main content
added 2 characters in body
Source Link
Bruno Ferreira
  • 4.5k
  • 2
  • 27
  • 37

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 thethat 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.

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 the 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.

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.

added 1524 characters in body
Source Link
Bruno Ferreira
  • 4.5k
  • 2
  • 27
  • 37

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 the 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.

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.

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

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 the 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.

Source Link
Bruno Ferreira
  • 4.5k
  • 2
  • 27
  • 37

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.

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