[SOLVED] Slight Help Needed in uderstanding the code

Status
Not open for further replies.

junkie_

Junior Member level 2
Joined
Oct 9, 2005
Messages
24
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,477
Hello all,

I need slight help in understanding the following code, it is written in Hitech C, from what I understand is that LCD data (D4_D7) is defined at PORT A (RA0_RA3), but what I don't understand at which pin R/S and E are defined and if I want to change it to PORT B with different pin assignment how to do it?

Code:
struct lcd_pin_map {
						unsigned DATA:4;
						unsigned RS:1;
						unsigned E :1;
					};
struct lcd_pin_map LCD @ 0x05;
 


It's an unusual but portable way of defining which pins of a port go to the LCD.

The structure is called "lcd_pin_map" and it occupies one byte with the bit fields 'DATA' being bits 3210, 'RS' being bit 4 and 'E' being bit 5.
By allocating the struct to fixed address 0x05 it occupies PORTA on most PIC processors. The advantage of doing it this way is if you wanted to use a different port, for example PORTB, all you do is change the 0x05 to PORTB's address (usually 0x06) and recompile. You can refer to the bits as LCD.DATA, LCD.RS and LCD.E whatever the real port address is set to .

Brian.
 
You don't mention the specific PIC processor but with the specific hardware address of 0x05 I'm guessing that it could be one of the smaller PIC12 or PIC16 families. However that is not really important to the point I want to make.
There is a problem with any MCU where you try to set/clear individual bits using a 'read modify write' process and the register also drives signal lines that might skew the transitions.
The "RMW" problem is documented in many places but it can be avoided in a case such as this as long as:
- all of the values are being written and not read (as in the LCD case - unless you are using the data lines to read back the status register)
- the MCU has LAT registers (that is the name used by Microchip; the RMW problem is generic and other manufacturers could have different names
Therefore, if you can, don't map the structure to the PORT register; rather use the LAT register if at all possible.
Susan
 

Dear All,

thanks for your inputs, first of all the code was done by professional software engineer, LCD in this case works better than many other firmwares.
I dug through Hitech C manual and found that the issue is discussed at length in section 3.3.9 under "Structures and Union" and according to the section the above code is a bit field operation within 8 bit code. The first bit defined will be the Least Significant bit of the word in which it will be stored. Since PORT A is 6 bit wide in this case it will be perfect to attach an LCD.
 

You are understanding it correctly. What Susan mentioned, the 'RMW' problem is endemic amongst almost all smaller processors and is caused by residual charge on pins when rapidly reading and rewriting them. Most people are ever aware of it, the problem only shows when you directy manipulate the bits in a port and it's easy to work around if you know it may happen. If you are using a PIC18 or enhanced PIC16 processor, it may help to make two structures, one to read the LCD pins and one to write them (assuming you read the LCD at all) like this:
Code:
struct lcd_pin_map LCD_Read @ PORTA;
struct lcd_pin_map LCD_Write @ LATA;

Brian.
 

Thanks Brian,

Although I don't need to read anything from LCD, but I ll keep your advise in mind.
 

Unfortunately, while your program might not need to read from the LCD, that does not mean that the RMW problem will not occur.
Every time you alter a bit on a register, what the hardware does is to read the WHOLE register, update the bit you specify and then write back the whole register value (hence the name "read-modify-write").
When the register is a PORT one, the values that are read are actually what is on the pin and not necessarily what was set by the register - this happens if the pin and the associated wiring places a load on the pin so that the voltage transitions are (relatively) slow.
Therefore, you might change a pin from '0' to '1' but the actual voltage on the line will take time to change. If in that time you try to update the register again and therefore the hardware will read the pin voltage, it can read the "old" '0' state if the voltage has not had sufficient time to rise to the '1' voltage threshold. In that case the read of the register will still see the value of that bit as '0'. When it comes to write back the register, it will set that bit back to '0'.
If the first bit you try to update is (say) the RS signal to the LCD and the next bit is the E signal, then the LCD could well see the wrong R/W value and therefore write to a register and not data (or vice versa).
If you must use a MCU that does not have RMW protection, then you should use a "shadow" register technique. What that means in this case is you declare a variable in memory to be of the structure type you have defined. You can set the bit(s) you want and then write the whole variable to the full PORT register. As you are writing to the whole register, the hardware does NOT need to read it beforehand and so you avoid the problem.
Susan
 

Thanks for the detailed explanation, and I'll keep it in mind.

But as they say "real proof of the pudding is in the eating" for now the code is working pretty well, and its not a military grade project therefore I'll just keep using it.

Hmmm, perhaps I forgot to check the thread as "SOLVED" after Brian's last post.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…