0% found this document useful (0 votes)
121 views36 pages

PIC 18 Introduction: GCS250 Computer Architecture Gustavo Rodriguez-Rivera Purdue University

The document provides an overview of the PIC18 microcontroller. It discusses the PIC18's architecture, memory organization, registers, I/O capabilities, instruction set, and programming. The PIC18 is an 8-bit microcontroller that features digital I/O, analog-to-digital conversion, pulse width modulation, USB support, and serial communication. It has separate memory spaces for program code and data. Programming involves using assembly language instructions and addressing modes to manipulate registers, variables, and I/O ports.

Uploaded by

amhosny2010
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views36 pages

PIC 18 Introduction: GCS250 Computer Architecture Gustavo Rodriguez-Rivera Purdue University

The document provides an overview of the PIC18 microcontroller. It discusses the PIC18's architecture, memory organization, registers, I/O capabilities, instruction set, and programming. The PIC18 is an 8-bit microcontroller that features digital I/O, analog-to-digital conversion, pulse width modulation, USB support, and serial communication. It has separate memory spaces for program code and data. Programming involves using assembly language instructions and addressing modes to manipulate registers, variables, and I/O ports.

Uploaded by

amhosny2010
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 36

PIC 18 Introduction

GCS250 Computer Architecture


Gustavo Rodriguez-Rivera
Purdue University
PIC18
• In the labs you will use the PIC18
• This is a 8 bit processor that provides
– Digital I/O
– Analog to Digital Conversion
– Pulse Width Modulation
– USB support
– RS232 (Serial Line)
• Data Sheet of PIC18:
– http://ww1.microchip.com/downloads/en/DeviceDoc/39632e.pdf
PIC18
• It follows a Harvard Architecture, that is,
code and data are stored in separate
memory.
– Code - 32KB
– Data - 4KB
• Instructions can be 2 or 4 byte long.
• The data word is 1 byte.
Data Memory
• RAM is 4KB or 212
• Therefore, pointers are 12 bits long
• The memory is divided into 16 banks.
• Each bank is 256 bytes long.
• That is 16x256=4KB
Memory Addresses
• The instructions that access data use a
reduced pointer that is 8 bits long (0 to 255)
• The remaining 4 highest bits are specified
by the argument “a” in each instruction.
– If a=0 the address refers to the “Access Bank”
that uses bank 0 for 0x00 to 0x5F and 0x60 to
0xFF from bank 15.
– If a=1, the 4 highest bits are contained in a
register called BSR (Bank Selection Register)
– 99% of the time a=0 in your programs.
Special Function Registers and
General Function Registers
• The data memory is divided into
– SFRs – Special Function Registers. Used for
control and status of the processor.
– GPRs – General Purpose Registers. Used to
store temporal results in user application.
Working Register (WREG)
• Most arithmetic and logical operations use
a register called Working Register or
WREG.
Processor Status Register
(PSR)
• This is a register that contains the status of the
Arithmetic Logical Unit.
• It is separated in bits
– N – Negative bit. Turns to 1 if the result of the last
operation was negative (highest bit is 1).
– OV – Overflow bit. Last operation in ALU results in an
overflow.
– Z – Zero bit. Last operation in ALU resulted in 0.
– C – Carry or Borrow. Set to 1 if addition resulted in carry
or borrow.
• Also the PSR is used in multiple branch
instructions.
Digital Input/Output
• PORTA, PORTB, PORTC, PORTD
– They are the registers that are mapped to the
inputs/outputs of the PIC18.
– Each bit in the port is identified as RA0, RA1 …RA7,
RB1, RB2…RB7 and so on,
• TRISA, TRISB, TRISC, TRISD
– Used to configure ports as input/output.
– Each bit can be configured to be a digital input or
output..
• 0 – Output
• 1 – Input
Digital Input/Output
• When configured PORTA as output for
example
– 0 in bit RA0 of PORTA gives 0V in terminal RA0
– 1 in bit RA0 of PORTA gives +5V in terminal RA0
• When configured PORTA as input,
– 0V in terminal RA0 can be read as 0 in bit RA0 of
PORTA
– +5V in terminal RA0 can be read as 1 in bit RA0 of
PORTA
Minimum PIC18
Addressing Modes
• Inherent (Immediate)
– Used in instructions that do not need an argument such
as SLEEP and RESET
• Literal
– Used in instructions that specify a numeric constant
such as “MOVLW 0x40” that loads 0x40 in WREG
• Direct
– Used in instructions that need an address as argument
such as “MOVWF 0x080” that moves WREG into 080.
• Indirect
– A register or memory location contains the address of
the source or destination.
Indirect Addressing
• It uses the FSR registers and the INDF operand.
• There are four registers:
– FSR0, FSR1, FSR2, FSR3, and the corresponding
– INDF0, INDF1, INDF2, INDF3.
• INDF0 to INDF3 are “virtual registers”.
• A read from INDF2 for example, reads the register
at the address stored in FSR2.
• Since FSRs is 12 registers long, you can use
FSRL(lower byte) and FSRH(higher 4 bits) for the
instructions.
Byte Operations
d = 0 means destination is WREG.
d = 1 means destination is a file register and it is the default.
a is the access bank. By default it is 0.
• ADDWF f,d,a - Add W to f where d=0->W, d=1->f, a is
generally not specified (access bank stuff)
• ADDWFC f,d,a - Add W and Carry bit to f
• ANDWF f,d,a - And W with f
• CLRF f,a Clear f
• COMF f,a Complement f
• CPFSEQ Compare, skip if f==W
• CPFSGT Compare, skip if f > W
• CPFSLT Compare, skip if f < W
Byte Operations (cont.)
• DECF f,d,a Decrement f
• DECFSZ f,d,a Dec f, skip if 0
• DCFSNZ f,d,a Dec f, skip if not 0
• INCF f,d,a Increment f
• INCFSZ f,d,a Increment f, skip if zero
• INFSNZ f,d,a Increment f, skip if not zero
• IORWF f inclusive-OR W with f
• MOVF f,d,a Move f (usually to W)
• MOVFF f,ff Move f to ff
• MOVWF f,a Move W to f
• MULWF f,a W x f
Byte Operations (cont.)
• NEGF f,a Negate f
• RLCF f,d,a Rotate left f thru Carry (not-quite multiply by 2
with carry)
• RLNCF f,d,a Rotate left (no carry)
• RRCF f,d,a Rotate right through Carry
• RRNCF f,d,a Rotate right f (no carry)
• SETF f,a Set f = 0xff
• SUBFWB f,d,a Subtract f from w with Borrow
• SUBWF f,d,a Subtract W from f
• SUBWFB f,d,a Subtract W from f with Borrow
• SWAPF f,d,a Swap nibbles of f
• XORWF f,d,a W XOR f
Bit Operations (cont.)
• BCF f,b,a Bit clear, bit is indexed 0 to 7
• BSF f,b,a Bit set
• BTFSC f,b,a Bit test, skip if clear
• BTFSS f,b,a Bit test, skip if set
• BTG f,b,a Bit toggle
Control Operations (cont.)
• BC n Branch if Carry, n is either a relative or a
direct address
• BN n Branch if Negative
• BNC n Branch if Not Carry
• BNN n Branch if Not Negative
• BNOV n Branch if Not Overflow
• BNZ n Branch if Not Zero
• BOV n Branch if Overflow
• BRA n Branch Unconditionally
• BZ n Branch if Zero CALL n, s Call Subroutine
Control Operations (cont.)
• CLRWDT Clear Watchdog Timer
• DAW Decimal Adjust W
• GOTO n Go to address
• NOP No operation
• POP Pop top of return stack (TOS)
• PUSH Push top of return stack (TOS)
• RCALL n Relative Call
• RESET Software device reset
• RETFIE Return from Interrupt and Enable Interrupts
• RETURN s Return from subroutine
• SLEEP Enter SLEEP Mode
Operations with Literals (constants)
• ADDLW kk Add literal to W
• ANDLW kk And literal with W
• IORLW kk Incl-OR literal with W
• LFSR r,kk Move literal (12 bit) 2nd word to FSRr
1st word
• MOVLB k Move literal to BSR<3:0>
• MOVLW kk Move literal to W
• MULLW kk Multiply literal with W
• RETLW kk Return with literal in W
• SUBLW kk Subtract W from literal
• XORLW kk XOR literal with W
Common PIC Assembler
Constructions
• Including the PIC18 constant defined
values
– Add
#include “P18f4550.INC”
at the beginning of the file
– In this way you can specify PORTC instead
of 0xF82 when specifying names of
registers
Defining a variable
• To define space for a variable use “res”.

Delay1 res 2

• This defines a variable called Delay1 that


will take 2 bytes.
• Make sure that it is at the beginning of the
line.
Using registers
• Loading a constant into WREG
MOVLW 0x40
• Moving the value from a register to WREG
MOVF reg,0
• Moving the value of WREG into a register
MOVWF reg
• Moving the value of a register reg1 to reg2
MOVFF reg1, reg2
Adding and Subtracting
• Add reg1 and reg2. Put result in reg1
MOVF reg1,0 ; WREG = reg1
ADDWF reg2,0; WREG = WREG + reg2
MOVWF reg1 ; reg1 = WREG

• Subtract reg2 - reg1. Put result in reg2


MOVF reg1,0 ; WREG = reg1
SUBWF reg2,0; WREG = reg2-WREG
MOVWF reg2 ; reg2 = WREG
Subroutines
• To call a subroutine

CALL foo ; Calling subroutine foo


• To define a subroutine
foo ; Defintion of foo

RETURN ; Return from subroutine
If/else statements
– If (reg1 == 0x40) {XXX} else { YYY}

MOVLW 0x40; WREG = reg1


CPFSEQ reg1
GOTO elsepart
….; XXX Then part
GOTO endifpart
elsepart
… ; YYY else part
endifpart
Using Arrays
• Arrays are implemented using Indirect Indexing
• Defining an array of bytes called “myArray” of 4 elements:
myArray res 4
• Initializing array:
MOVLW 0xFE            ; myArray[0]=0xFE
    MOVWF myArray
    MOVLW 0xFD          ; myArray[1]=0xFD
    MOVWF myArray +1
    MOVLW 0xFB ; myArray[2]=0xFB    
MOVWF myArray +2
    MOVLW 0xF7 ; myArray[3]=0xF7
    MOVWF myArray +3;
Using Arrays
• Indexing the Array myArray[i].
• Address is stored in FSR0 and then it is
dereferenced from INDF0
LFSR 0, myArray ; Load array address in FSR0
    MOVF i,0 ; Load the value of i into WREG
    ADDWF FSR0L,1 ; Add myArray and i to get
address ; of ith element.
    MOVF INDF0,0 ; The ith element can be read
; from INDF0. Read it and put
; it into WREG. WREG=myArray[i]
    MOVWF PORTB ; Now do something with it like
; writing it to PORTB
An Example. Rotate Segments
#include "P18f4550.INC"
CONFIG WDT=OFF; disable watchdog timer
CONFIG MCLRE = ON; MCLEAR Pin on
CONFIG DEBUG = ON; Enable Debug Mode
CONFIG LVP = OFF; Low-Voltage programming disabled (necessary for debugging)
CONFIG FOSC = INTOSCIO_EC;Internal oscillator, port function on RA6
org 0; start code at 0

Delay1 res 2 ; variable Delay1


Delay2 res 2 ; variable Delay2
Delay3 res 2 ; variable Delay3

Start:
CLRF PORTD ; Initialize with 0's output D.
CLRF TRISD ; Make port D output
CLRF Delay1; Clear delay variables
CLRF Delay2
SETF TRISC ; Make port c an input
MOVLW H'40' ; Initialize delay3 to 0x40. This is the delay used to rotate the segments.
MOVWF Delay3
BSF PORTD,RD0 ;Turn on bit 0 in RD0
Example (cont.)
MainLoop:
RRNCF PORTD ; Rotate bits in D. This causes the segments in display to shift.
MOVF Delay3,0 ; Reload Delay2 eith the value of Delay3. Delay2 controls the rate the
MOVWF Delay2 ; rotate takes place.
MOVLW H'F0' ; Test if Delay3 is at the maximum of 0xF0 or more. If that is the case, do not
CPFSLT Delay3 ; read the left switch.
goto noincrement
MOVLW 4 ; Read the left switch.
BTFSS PORTC,0 ; If the switch is 0 (gnd), then increase Delay3 by 4, otherwise skip the increment.
ADDWF Delay3,1

noincrement:
MOVLW H'05' ; Test if Delay3 is at the minimum pf 0x5 or less. If that is the case do not
CPFSGT Delay3 ; read the right switch.
goto Delay
MOVLW 4 ; Read the right switch.
BTFSS PORTC,1 ; If the switch is 0, then decrement Delay3 by 4, otherwise skip the decrement
operation.
SUBWF Delay3,1

Delay:
DECFSZ Delay1,1 ;Decrement Delay1 by 1, skip next instruction if Delay1 is 0
GOTO Delay
DECFSZ Delay2,1 ;Decrement Delay1 by 1, skip next instruction if Delay1 is 0
GOTO Delay
GOTO MainLoop
end
Example: Driving a Full-Color LED
• To drive the full-color LED you will use Pulse
Width Modulation (PWM).
• PWM sends pulses to the LED with different
widths to the three color LEDs.
• If for example, the width of the pulse is small for
the red LED, then the red LED will display a low
intensity red light.
• If the red LED receives a pulse with a wide width,
then the red LED will display a high intensity red
light.
Pulse Width Modulation
• Short Width = Low Intensity
• Long Width = High Intensity
Algorithm for Driving Full Color
LED
• Start
– Initialize Ports and Registers
– Initialize colors and counters
• MainLoop
– Put in a variable val the current color value (red, green, blue)
– Read button 1 and 2. If they are “on” increase or decrease val. Make
sure that val is not increased beyond maxColor and is not decreased
beyond 0.
– Update “msg” (the display buffer) with:
• msg[0]= c[currentColor]
– where c is an array with the characters “r”, “g” or b” in seven-segment values.
• msg[1]= “=“
– in seven segment value “=“ is(0x48)
• msg[2] = digit[(val>>4)&0xFF]
– Displays most significant nibble of val
– digit is an array with the hex digits in seven segment value.
• msg[3]=digit[val&0xFF]
– Displays least significant nibble of val
Algorithm for Driving Full Color
LED (cont.)
– Store val in currentColor red, green or blue
– Update Display. See example code.
– Read button 3 to change color if necessary. Use a
variable previouslyPressed to store the previous status
of the button.
– Only update the color name if previouslyPressed is
false and button3 is pressed.
– To update the color name write into msg (the display
buffer” the name of the color in seven-segment values.
– Now refresh the red, green, blue LEDs PWM See
example code.
• Goto MainLoop

You might also like