How pins work 101: (I haven’t done much doco lately, I hope this redeems me a little)
OK… Uhm crap where do I start… OK let’s just talk about PORTB aka J15 aka the LCD data port. I’ll start at the beginning, so this might get a bit geekey… but it’ll make a lot more sense once you give it a shot I’ll try to keep it as plain-english as possible. Likewise don’t get me wrong, if I explain stuff you already know, it’s just because I’m telling the whole story for everyone’s benefit 
Inside the PIC chip is a bunch of memory cells. These cells hold an electrical charge, LOW or HIGH, aka 0 or 1 in digital terms. Because this is an 8-bit uC, the cells are divided into groups of 8 (a byte) and each byte gets an ‘address’ which is just a glorified way of saying they get counted and numbered accordingly
(these memory locations are all known as SFR’s or Special Function Registers, they’re a memory register dedicated to this special function of providing I/O)
There are 8 of these cells (one byte) who’s charge is used to set the voltage, which is output at 8 of the pins of the PIC chip (yaknow, the legs of metal hanging off the sides). For convenience, seeing as 8 pins are grouped together, we give it a name: it’s a “Port”. We name the ports A, B, C, etc.
The bank of memory cells which controls these pins, is able to be accessed by the program you put on the chip, by referring to the address. In the case of Port B on a PIC18F4620, this address is 0xF8A. Instead of making you remember a bunch of hexadecimal addresses like that, we use a header file, which tells the assembler like, “when we use this name, we are referring to this address”. Thus, we can give them a more convenient name. 0xF8A, is known as LATB, which is short for Latch B, or to be more verbose, the output latch of port B.
Latch? what the heck is Latch? I thought we were talking about a port?
Well, the latch register is the memory, where you write the data, which controls the pins, on that port - but what you write there, only takes effect when the pin is an output. When the pin is an output, the data you write to it’s address, is latched to the pins, similar to the operation of something like a 74HC373 or 573 - but these pins can be inputs too.
When the pin is set as an input, it reads the incoming voltage at the pin, and stores it in an other different memory location. In this case, it’s 0xF81 - and that is the location we have specified in our header file, as PORTB. By reading the memory stored there, we can see if each pin is HIGH or LOW/1 or 0/ON or OFF, etc.
It’s also possible to read or write just one bit of the byte, which equates to one pin. This allows you to control or read a single pin, without effecting the others. in code, this can be done like:
LATB.LATB5 = 1; //sets the 5th bit (counting from 0) as ON/1/HIGH
Mybutton = PORTB.RB6; // Sets your variable to 0 or 1 depending on whether the button is pushed in or not, driving the pin high or low
So, that’s nice, but how can you tell if the pin is an input or an output? Well that’s another memory location. This time it’s 0xF93, which we call TRISB, which is short for Tristate B, the Tristate status of port B. When a pin is ‘tristated’, that means it’s an input. So, if we set a bit within the TRISB byte to 1, then the corresponding pin is tristated, and it’s now an input, and ready to read from the corresponding bit in PORTB. For example:
TRISB.TRISB5 = 1; //sets the 5th pin as an input
TRISB.TRISB5 = 0; //sets the 5th pin as an output
TRISB = 0; //sets the whole port as an output
TRISB = 0x0F; //sets the last 4 pins as outputs, and the others as inputs.
//Hint: 0x0F = 00001111, and we count the pins from the right to left direction in binary!
What’s more, the TRISx byte has a handy effect on the PORTx and LATx bytes. I should mention: Writing to PORTx doesn’t really write to PORTx at all. It will actually write to LATx, because that’s where you set the outputs, and writing to the port is an output operation right… The chip takes care of that. Reading from LATx will always show you whatever you last wrote there, it doesn’t change, it just sits there waiting for you to output it, by setting TRISx to 0. How patient
Reading PORTx, will always show you whatever’s on the pins themselves. It’s an input. Now, when the pin is set as an output (TRISx = 0), that data will be latched from the memory onto the pins right away, so you’d be thinking, that reading PORTx and LATx will have the same value… Most of the time that will be true, but it is possible that some other part of the circuit outside the PIC, will drive the pin low, and in this case, LATx and PORTx will differ. So, that’s how it works from the perspective of the PIC chip itself. Obviously, there are complex sequences of controlling these pins, involved in performing some of the real-world applications. For example, it takes a dozen or so changes of pin states, to output a single character on an LCD module. Who needs to worry about all that every time, right? That’s where the operating system and it’s built-in drivers come into play. Hooray for MIOS. For example, instead of having to code out this massive bunch of pin controls, we let TK do that for us
and we can then use a command to set the pins according to our needs, so we can just type some simple code like
MIOS_LCD_PrintCString("TK is the bomb!")
All of these functions are listed in the Function Reference. If you can use these, it’s best to do so, as they guarantee that it will work, and not break anything. So, that covers off the PIC and MIOS, which leaves us with MBHP - the midibox hardware platform. You may have already noticed, that in addition to the 8 pins I’ve used in the above examples, there are three other pins required to use the LCD (enable - has to be low or the LCD does nothing; R/W, Low = Write, High = Read; and RS or register select, which tells the LCD whether you’re sending it a command (like “reposition the cursor”) or data (“like put the cursor over *there*”), which are LOW and HIGH respectively. As such, it doesn’t just use PORTB, but also PORTA. All the required pins, go to one connector on the MBHP PCB, naturally. These connectors or “Jumpers” (same name as the cable you use to connect your car battery when you leave the lights on) are numbered for ease of reference. It so happens that the jumper for the LCD was number 15, so: J15. We also refer to the individual pins on the jumper by their purpose, such as J15:E (enable) or J15:RW (Read/Write) or J15:D0 (data 0 - that’s PORTB:RB0). You can see how all the J*:* names correspond to the pin names, on that pin list I posted. You should always read the datasheet for the PIC though, to make sure you don’t accidentally do something you didn’t expect. For example a driver I am writing at the moment uses PortE. PortE is a bit different, it only has three physical pins. The PORTE and LATE registers are safe to write to as a whole, but the part of the TRISE register which doesn’t correspond to a physical pin, is used for some other features. I can’t just do
TRISE = 0;
to make it an output, because then I will be overwriting some data that the PIC uses for other things. (Buffer ful/overflow flags for those of you who care).
Uhm… I think that covers it? Hint: I answered your question about SVN with the first link (to the header) have a browse around there, and don’t forget to find the wiki page on SVN client setup so you can copy it to your PC if you need to.
I need to rest my hands!