Skip to content

Basic architecture

The PIC18F4550 uses a Harvard-style architecture, where program memory and data memory are separated. This allows the microcontroller to fetch instructions and handle data through different spaces.

Comparison between Von Neumann and Harvard architecture
The PIC18F4550 uses Harvard architecture: separate buses for program (Flash) and data (RAM). — Based on Topic 1 — UNEXPO · Mechatronics Engineering · Microcontrollers

The six registers of the general scheme are in Basic concepts. This figure is this chip only:

PIC18F4550 block diagram: data bus, instruction bus, W, ALU, program counter, stack, and ports
PIC18F4550: W enters the ALU, the instruction register (IR) sits on the instruction-bus path, STKPTR points at the stack, and ports and peripherals hang off the data bus. — PIC18F4550 block diagram — Microchip datasheet

The numbers beside the lines are not addresses. They say how many bits that path carries.

NumberWhere it isWhat it means
8Data bus, W, and the ALUOne byte. A value from 0 to 255 travels there. That is why 8 shows up on almost every data path.
16Instruction busEach PIC18 instruction is 16 bits wide. It leaves Flash and enters the IR.
12Data address and FSRThe address of one data byte. Twelve bits name 4096 locations. FSR (the PIC’s data-address register) is 12 bits.
4BSR, next to the bankSelects the data-memory bank. Those 4 bits, plus the 8 bits that come inside the instruction, make the 12-bit address.
21Table pointerA 21-bit pointer to one byte of program memory. Table reads and table writes use it.
20Next to the program counterThe PC reaches bit 20. It is written PC<20:0>: from bit 0 through bit 20 that is 21 bits. The 20 on the drawing is that highest bit, the same width the PC uses to point at Flash.
ElementFunction
WREGWorking register. Many operations go through it.
STATUSStores flags such as zero, carry, and negative.
SFRSpecial function registers used to control peripherals.
GPRGeneral purpose registers used as variables.
BSRSelects the memory bank to access registers.
PCProgram counter. Points to the next instruction.

Class names (any microcontroller) and the PIC18 name:

In classOn the PIC18
Classic accumulator (after the ALU)The PIC does not work that way: W sits before the ALU (WREG)
STATUSSTATUS — flags C, Z, DC, N, OV
General-purpose registersGPR — data-memory bytes you use as variables
Data-address registerInstruction address f (direct) or FSR (indirect)
SPSTKPTR — top of the stack
IRInternal opcode register. You do not write it in the .ASM
PC and stackPC and the hardware stack (stores addresses, not data)

The table is a quick reference. Below you will find detailed explanations with examples from real lab work. The generic register set is in Basic concepts — registers.

In the general scheme the accumulator sits under the ALU: the result lands there, and that same value can go back in as an operand. A PIC does not work that way. W sits before the ALU: it is an operand that enters together with another value. The result can return to a register or to W.

Comparison: on a traditional microprocessor the accumulator sits under the ALU; on a PIC, W sits before the ALU
Left, traditional microprocessor: the registers feed the ALU and the result falls into the accumulator. Right, PIC: W enters before the ALU and the result can return to a register or to W. — Class comparison — traditional accumulator versus PIC W
Traditional microprocessorPIC18
Where it sitsThe accumulator is under the ALUW (WREG) is before the ALU
What enters the ALUA value from the registers and, through the loop, the accumulator itselfW and another register
Where the result landsAlways in the accumulatorIn a register (,F) or in W (,W)

It is still the 8-bit working register (one byte, 0 to 255 — see What 8-bit means).

Think of it as the processor’s temporary hand: pick up a value, operate on it, then place it in a register or variable.

MOVLW D'5' ; load 5 into WREG
ADDLW D'3' ; WREG = 5 + 3 → WREG is 8
MOVWF counter ; copy WREG to GPR 'counter'

Without WREG you could not use MOVLW, add numbers, or move data between registers with most PIC18 instructions.

After many operations, the PIC stores flags in STATUS. Each flag is one bit: either 1 (set/active) or 0 (clear/inactive). On an exam you need to know what each value means, not just the name.

BitNameWhat it measures
0CCarry
1DCDigit carry (low nibble)
2ZZero result
4OVSigned overflow
7NResult sign (bit 7)
Flag= 1 (active)= 0 (inactive)
ZThe operation result is zeroThe result is not zero
CThere was carry past bit 7 (in addition: value exceeds 255 in unsigned 8 bits)No carry out of the byte
DCThere was carry in the low nibble (bit 3 → 4)No digit carry
NBit 7 of the result is 1 → negative number in two’s complement (signed)Bit 7 is 0 → not negative in signed 8 bits
OVSigned overflow: result does not fit in -128 to +127Signed operation was valid

Numeric example with Z — is counter zero? The PIC has no CMP (compare) instruction; you compare by operating and reading the Z flag in STATUS:

MOVLW D'0' ; WREG = 0 (what we compare against)
XORWF counter, W ; XOR counter and WREG bit by bit → result in W
; (XOR gate: matching bits → 0, different bits → 1)
; counter unchanged; only W and flags update
;
; if counter = 0: every bit matches WREG
; → result 00000000 → Z = 1 (active)
; if counter = 5: some bits differ from zero
; → result 00000101 → Z = 0 (inactive)

Example with C after addition. WREG holds only 8 bits (2⁸ = 256 values: 0 to 255); if the sum exceeds 255, what does not fit is recorded in C and W keeps the remainder:

MOVLW D'200' ; WREG = 200
ADDLW D'100' ; 200 + 100 = 300
; 300 > 255 → does not fit in 8 bits
; 256 overflows (one full byte) → C = 1 (carry)
; WREG holds: 300 - 256 = 44

You use flags to make decisions with conditional branches:

MOVLW D'0' ; reference: compare against 0
XORWF counter, W ; counter == WREG? → if equal, result 0, Z=1
BTFSS STATUS, Z ; skip if Z=1 (counter was 0)
GOTO continue ; if Z=0 → jump to destination
GOTO handle_zero ; if Z=1 → jump to destination
handle_zero:
; counter was 0 ...
continue:
; counter was not 0 ...

BTFSC skips when the flag is 0; BTFSS skips when it is 1.

On an exam: “How do you know an operation gave zero?” → Z = 1. “How do you know an addition overflowed past 255?” → C = 1.

SFRs (Special Function Registers) control internal hardware: ports, timers, ADC, UART, interrupts, and more. Each bit or byte has a fixed meaning defined by Microchip.

Real example — turn on an LED on RB0. To change one bit of an SFR without touching the others, the PIC uses BCF (Bit Clear File → sets the bit to 0) and BSF (Bit Set File → sets the bit to 1):

BCF TRISB, 0 ; TRISB is an SFR, bit 0 → force that bit to 0
; (bits 1..7 of TRISB stay unchanged)
; on TRISB: 0 = output → RB0 becomes an output
BSF LATB, 0 ; LATB is an SFR, bit 0 → force that bit to 1
; (bits 1..7 of LATB stay unchanged)
; RB0 goes high → LED on

You are not writing the whole byte: BCF/BSF only change the bit you specify; the rest of the register stays the same. TRISB and LATB are fixed hardware names — you do not invent them.

Other SFRs you will use soon: INTCON (interrupts), TMR0 (Timer0), ADCON0 (ADC).

GPRs are RAM bytes your program uses as variables: counters, temporaries, state-machine states, and so on. They do not control hardware directly; they hold data.

With counter RES 1 you do two things at once: the name (counter) defines the variable — a symbol you will use in code — and RES 1 reserves 1 byte of RAM for it. Later when you write INCF counter, F, the assembler already knows which address that is.

; In the variable section:
counter RES 1 ; define 'counter' and reserve 1 byte in RAM
; In code:
INCF counter, F ; counter = counter + 1
MOVF counter, W ; copy counter to WREG
DECFSZ counter, F ; decrement; if zero, skip next instruction
GOTO wait

The key difference from an SFR: counter is yours — you name it and use it however you need. TRISB is not — its name and function come from the hardware.

Both SFRs and GPRs live in data RAM, split into banks (0 through 15). The BSR register tells the CPU which bank you are in when you access an address.

Many SFRs (TRISB, LATB, INTCON…) live in the access bank and do not require touching BSR. But if you place GPR variables in different banks with RES, you must select the correct bank:

; 'temp' declared with: temp RES 1
MOVLW 0x01
MOVWF BSR ; activate bank 1
CLRF temp ; clear the GPR variable in that bank
CLRF BSR ; return to bank 0

The ALU combines two operands and writes the result. On the PIC18 one operand is usually W (or a literal embedded in the instruction) and the other is a file register f (GPR or SFR). Flags go to STATUS.

PIC18 ALU: W and file-register inputs, result routed by d to W or f, flags to STATUS
On a PIC, W sits before the ALU. The orange trapezoid is the ALU. d = 0 returns the result to W; d = 1 returns it to file register f. — PIC18 architecture — UNEXPO

The d (destination) bit says where the result goes:

dIn sourceWhere the result goes
0 (destination 0),WInto accumulator W
1,FInto register f
ADDWF counter, W ; d = 0 → W = W + counter; counter unchanged
ADDWF counter, F ; d = 1 → counter = counter + W

How the instruction says where the data comes from:

ModeMeaningExample
LiteralThe number travels inside the instruction. It is not read from RAM.MOVLW .5
Direct (general)The instruction names the register (f). That name is the data-memory address.MOVF counter, W
IndirectFSR is the data-address register. INDF is the byte at that address.MOVF INDF, W reads what FSR points to

More on literals and ,W / ,F in Assembly.

MOVLW .20
MOVWF FSR0L ; data-address register = 0x20
MOVF INDF0, W ; W = byte at that address

PC (Program Counter) points to the next instruction in Flash. You do not write it by hand: GOTO, BRA, CALL, and RETURN change it.

The PIC18 stack is an array of PC addresses, not variables. It is LIFO. STKPTR (the SP) marks the top.

  • PUSH: stores an address. CALL PUSHes the return address, then loads the PC with the destination.
  • POP: removes that address and puts it in the PC. RETURN performs the POP.

CALL must return. Without RETURN (or RETFIE in an interrupt), that address never leaves the stack: the program does not resume where it was, and repeated CALLs without a return fill the stack.

An interrupt also PUSHes the PC. RETFIE POPs it and re-enables interrupts. See Interrupts.

InstructionWhat it does to the PCUses the stack?When to use it
CALLJumps to a subroutineYes — PUSHCode that must return (RETURN)
RETURNGoes back to the stacked addressYes — POPEnd of a CALL
GOTOJumps to any labelNoLong jumps or loops that are not subroutines
BRAShort relative jumpNoLocal loops, such as a delay

BRA and GOTO change the PC without saving a return address. That is why a delay loop uses BRA, not CALL. Cycle comparison in Delay calculation — BRA vs GOTO.

start:
CALL delay ; PUSH PC; jump to delay
GOTO start ; no stack: only changes the PC
delay:
; ...
RETURN ; POP: PC returns just after the CALL
  1. The PIC reads an instruction from program memory.
  2. It decodes it.
  3. It executes the operation.
  4. It updates registers, flags, or peripherals.
  5. It moves to the next instruction unless there is a jump or interrupt.

Why is it important to distinguish SFR and GPR?

Because SFRs control internal hardware such as ports, timers, and interrupts; GPRs are working memory used as program variables.

Interactive exam

Architecture and CPU elements

Based on: Clase Tema 2 y 3 (1).pdf

0 of 0 answered

In Harvard architecture, program and data...
Which register selects the memory bank?
SFRs are used to...
Where is the result of `MOVLW D'5'` before copying it with `MOVWF`?
If the Z flag in STATUS is active (Z = 1), it means that...
What does the PC (Program Counter) register do?
A byte declared with `counter RES 1` is an example of...
To set RB0 as output and turn on an LED, which SFRs would you use?
If C = 1 after an unsigned 8-bit addition, it means that...
If N = 1 in STATUS, bit 7 of the result is 1, which indicates...
What does it mean that the PIC18F4550 is 8-bit?
After `MOVLW D'200'` and `ADDLW D'100'`, what is in WREG and flag C?
In `ADDWF counter, W`, destination d = 0 means the result stays in...
Which instruction changes the PC without the stack, using a short relative jump?
In PIC18 indirect addressing, FSR and INDF are...