Editing Read before write

Jump to navigation Jump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
 
==== Read before Write ====
 
==== Read before Write ====
  
The issue with 'read before write' is that, unlike a PIC18, it is impossible for a program running on the PIC16 to read the state of its output port latch.
+
The issue with 'read before write' is that, unlike a PIC18, the PIC16 does not store the state of it's output pins anywhere.
  
 
The classic issue occurs when individual port bits are set, or toggled, causing outputs on the pins to behave unexpectedly.
 
The classic issue occurs when individual port bits are set, or toggled, causing outputs on the pins to behave unexpectedly.
Line 9: Line 9:
 
For example with trisb set to zero, if you set portb.1=1, then later set portb.2=1. If portb.1 is excessively loaded, the PIC16 will read portb.1 as a zero and write 4 (0b100) to portb, instead of the expected 6 (0b110) to portb.
 
For example with trisb set to zero, if you set portb.1=1, then later set portb.2=1. If portb.1 is excessively loaded, the PIC16 will read portb.1 as a zero and write 4 (0b100) to portb, instead of the expected 6 (0b110) to portb.
  
There are three solutions to the above issue:
+
There are two solutions to the above issue:
  
 
One solution is to use a processor that does allow us to read the state of its output pins -- such as the LATx register on the PIC18 processors.
 
One solution is to use a processor that does allow us to read the state of its output pins -- such as the LATx register on the PIC18 processors.
  
The second, and by far the best is to ensure the output pins are not excessively loaded.
+
The first, and by far the best is to ensure the output pins are not excessively loaded.
 +
 
 
This is the best solution, as code not necessarily under your control, such as UART and I2C code will not affect the remainder of your application.
 
This is the best solution, as code not necessarily under your control, such as UART and I2C code will not affect the remainder of your application.
Unfortunately, this doesn't work when implementing an open-collector bus.
 
  
The third solution is to use some kind of 'shadow' register, in which the individual bits can be manipulated, then the resulting CHAR values can then be written to the port.
+
The second solution is to use some kind of 'shadow' register, in which the individual bits can be manipulated, then the resulting CHAR values can then be written to the port.
You use this shadow register to emulate the LATx registers on other processors.
 
  
 
The various _port macros below, if called in place of the _bit macros, should do the job:
 
The various _port macros below, if called in place of the _bit macros, should do the job:
Line 25: Line 24:
  
 
#define set_port(port, no)\
 
#define set_port(port, no)\
set_bit(sport[&port-PORTA], no);\
+
set_bit(sport[&porta-PORTA], no);\
port=sport[&port-PORTA];
+
port=sport[&porta-PORTA];
  
 
#define clear_port(port, no)\
 
#define clear_port(port, no)\
clear_bit(sport[&port-PORTA], no);\
+
clear_bit(sport[&porta-PORTA], no);\
port=sport[&port-PORTA];
+
port=sport[&porta-PORTA];
  
 
#define test_port(port, no)\
 
#define test_port(port, no)\
test_bit(sport[&port-PORTA], no)
+
test_bit(sport[&porta-PORTA], no)
  
 
#define toggle_port(port, no)\
 
#define toggle_port(port, no)\
toggle_bit(sport[&port-PORTA], no);\
+
toggle_bit(sport[&porta-PORTA], no);\
port=sport[&port-PORTA];
+
port=sport[&porta-PORTA];
 
</pre>
 
</pre>
  
Line 43: Line 42:
  
 
* [http://massmind.org/techref/readmodwrite.htm The Read-Modify-Write problem]
 
* [http://massmind.org/techref/readmodwrite.htm The Read-Modify-Write problem]
* [http://circuitguru.com/79/pic-microcontroller-read-modify-write-bugs/ Circuit guru: "PIC microcontroller read-modify-write bugs"]
 
* [http://www.cornerstonerobotics.org/curriculum/lessons_year2/erii_rmw_problem.pdf Cornerstone Robotics: "Read-Modify-Write (RMW) Problem with Mid-Range PIC Microcontrollers ... and Avoiding the Read-Modify-Write (RMW) Problem with LATx Registers in PIC18Fxxxx"]
 
* [http://electronics.stackexchange.com/questions/7684/what-causes-turning-on-an-single-output-pin-on-a-microchip-pic16f690-to-spontane Stackexchange: "What causes turning ON an single output pin on a Microchip PIC16F690 to spontaneously turn OFF another pin on the same port?"]
 
  
  
 
[[Category:BoostC]][[Category:PIC]]
 
[[Category:BoostC]][[Category:PIC]]

Please note that all contributions to OpenCircuits may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see OpenCircuits:Copyrights for details). Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)