I could type out a super long lesson on the instruction set for a mid range PIC with meanings and all. However, start here with the PIC 16F628 datasheet. Go to page 109 and start there. This is the instruction set summary for this PIC. It will explain the meaning behind each instruction as well as the syntax and more -
https://www.electro-tech-online.com/custompdfs/2011/01/40300C.pdf
The thing with assembly though is that you have to know the hardware (i.e. the particular PIC you plan to write code for) inside and out. The PIC has SFRs (Special Function Registers) that control the very functions of the PIC. Writing to an SFR makes the PIC do what it does. The SFRs are mapped in data memory so you would address them just as you would any register in RAM.
They're also spread across "banks" so you have to know what bank each SFR is in and you must use a bank switching instruction in your code prior to accessing registers in different banks. The data sheet for each PIC shows a memory map that tells you where each SFR is located.
Two of the most used SFRs on any PIC are the tristate registers (TRISA, TRISB) and the port status registers (PORTA, PORTB). These are the SFRs that directly control the I/O ports that interface with the outside world either via monitoring data that is sent to it or sending data to other external devices. I will explain these two in this example.
The Tristate registers TRISA and TRISB control the direction of Port A and B respectively. By "direction" I mean the bits in the tristate registers designate which pins on the port they control are input and output. TRISA and TRISB are located in Bank 1 and are 8 bits wide and each bit in the tristate register is assigned to an I/O line on the port that the register is assigned to.
Setting a bit in the TRIS registers (i.e. making the bit a "1") designates the pin controlled by said bit as an "input" while clearing a bit in the TRIS registers (i.e. making the bit a "0") designates the pin controlled by said bit as an "output".
For an example code for this you would write -
Code:
;TRISA Bit Map
;|RA7|RA6|RA5|RA4|RA3|RA2|RA1|RA0|
;| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
banksel TRISA ;select bank in which SFR TRISA resides
movlw b'01010101' ;set RA7, RA5, RA3 and RA1 as output
movwf TRISA ;set RA6, RA4, RA2 and RA0 as input
;TRISB Bit Map
;|RB7|RB6|RB5|RB4|RB3|RB2|RB1|RB0|
;| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
movlw b'10101010' ;set RB7, RB5, RB3 and RB1 as input
movwf TRISB ;set RB6, RB4, RB2 and RB0 as output
Notice the comments I added in. You can do this in your code so that it's easy to follow along as you read it. Anything proceeding a semicolon gets ignored by the assembler. You must use a semicolon for each new comment line.
I commented in the bit map for TRISA and TRISB to illustrate which bits control which pins. They're read MSB first (Most Significant Bit...or the highest bit) and LSB last (Least Significant Bit...or the lowest bit).
The first instruction, "banksel", is actually an assembler directive that tells the assembler to generate the required asm code to select the proper bank for the file register address that is the operand (i.e. the address which follows the instruction). In this case, it would be SFR TRISA, which also happens to be the same bank TRISB resides in. You can do this for any file register.
The 2nd instruction, "movlw" is an abbreviation for "
move
literal value into the
w register. This is a single operand instruction that moves any value you wish from 0-255 (or 00 - FF in hex). The "b" before the value tells the assembler that the value nested in the single quotes is "binary". You would use "d" for decimal and "h" or "0x" for hex. When using 0x, you don't have to use the single quotes. You can just simply say 0x00 for "hex zero".
The 3rd instruction, "movwf" is an abbreviation for "
move data in
w into
file". This is also a single operand instruction, and the operand is the file address that you are copying the data in W to. With MPASM and the includes file for your PIC, your SFR addresses are pre-labeled so you can simply use the label which represents the file register rather than having to look up the physical address of the SFR that you're moving data into.
In Bank 0 you have the PORTA and PORTB registers. You would read these registers to find the current state of your input pins while writing to PORTA and PORTB writes to the port latch. You would write to PORTA and PORTB when you're wanting to change the state of an output pin (i.e. make the pin put out a "high" or a "low" signal). The bit mapping in the PORTA and PORTB registers is identical to the TRISA and TRISB bit map.
An example code to turn on the output pins would be -
Code:
;TRISA Bit Map
;|RA7|RA6|RA5|RA4|RA3|RA2|RA1|RA0|
;| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
banksel TRISA ;select bank in which SFR TRISA resides
movlw b'01010101' ;set RA7, RA5, RA3 and RA1 as output
movwf TRISA ;set RA6, RA4, RA2 and RA0 as input
;TRISB Bit Map
;|RB7|RB6|RB5|RB4|RB3|RB2|RB1|RB0|
;| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
movlw b'10101010' ;set RB7, RB5, RB3 and RB1 as input
movwf TRISB ;set RB6, RB4, RB2 and RB0 as output
;PORTA Bit Map
;|RA7|RA6|RA5|RA4|RA3|RA2|RA1|RA0|
;| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
banksel PORTA ;select bank in which SFR PORTA resides
movlw b'10101010' ;set all PORT A outputs "high"
movwf PORTA
;PORTB Bit Map
;|RB7|RB6|RB5|RB4|RB3|RB2|RB1|RB0|
;| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
movlw b'00000000' ;set all PORT B outputs "low"
movwf PORTB
Setting port output pins "high" switches the pin to the Vcc pin, which is connected to the positive supply rail. This makes the pin put out a +5V voltage.
Setting port output pins "low" switches them to the Vss pin, which is connected to ground. This makes the pin put out a 0V voltage, or a ground reference.
So to summarize, the bits in the TRISA/TRISB SFRs designate I/O pins on Port A and Port B respectively as "input" or "output". A "1" designates "input" while a "0" designates "output".
The bits in the PORTA/PORTB registers are for reading the state of an input pin (whether it be high or low, depending on what input you feed to the input pin) and for writing to it to set output pins high or low to send digital logic signals out from the output pins.