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
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.

The table is a quick reference. Below you will find detailed explanations with examples from real lab work.

This is the CPU accumulator: an 8-bit register (one byte, values 0 to 255 — see What 8-bit means) where most arithmetic and logic operations happen before the result is stored somewhere else.

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 1negative 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

PC (Program Counter) points to the next instruction the PIC will execute in Flash program memory. You do not write to it directly in normal code; you change it with jumps and calls:

GOTO start ; PC jumps to label 'start'
start:
CALL delay ; save return address; PC goes to 'delay'
; ... when delay RETURNs, PC comes back here ...
GOTO start ; repeat the loop

When an interrupt occurs, hardware saves PC on the stack so the main program can resume where it left off.

The stack is auxiliary LIFO memory (Last In, First Out: the last item in is the first out). A CALL pushes the return address; a RETURN pops it and execution continues where it left off. The STKPTR register tracks the current stack position.

  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?