Catto / Topic Map · Digital Electronics III Year 6
Digital Electronics III · 144 h · Topic 1 of 7

The microcontroller family

In Year 5 the microcontroller was a concept. Here it becomes a concrete chip with numbered pins, named registers and a four-hundred-page datasheet. Learning to read that datasheet is, to a large extent, what this year is about.

Microcontrollers Registers I/O ports Memories Datasheet

01Where we are coming from

In microprocessor and microcontroller architecture we established what is inside: a CPU with an ALU and registers, memories, buses and peripherals, all in one chip. Now the point is to use one, and that means answering three very concrete questions:

Which pin does what?

The pinout and the multiplexing of functions: almost every pin serves several purposes and you have to choose.

Which register configures it?

Everything the chip does is decided by writing bits into special function registers. Programming a peripheral is, literally, putting ones and zeros in the right place.

Which memory do I use?

Flash for the program, SRAM for the variables, EEPROM for what must survive a power cut. Choosing wrong is expensive.

FamilyArchitectureInstructionsSpeedWhere you see it
Mid-range PIC
16F84A, 16F628A, 16F877A
Harvard, RISC3520 MHz → 5 MIPSArgentine industry, equipment in service, plenty of documentation in Spanish
High-end PIC
18F, dsPIC
Harvard, RISC75+40–70 MHzWhen more peripherals or more computing power are needed
AVR
ATmega328P, ATtiny85
Harvard, RISC13120 MHz → 20 MIPSArduino. One cycle per instruction and free tools
ARM Cortex-M
STM32, RP2040
32-bitThumb-248–480 MHzThe current industry standard
ESP3232-bit + radio—240 MHzAnything that needs WiFi or Bluetooth
Why we study a small, old family

Because in a mid-range PIC you can see everything: the memory map fits on one page, the registers are eight bits wide, there is no operating system or layers of abstraction, and every instruction takes a known time. What you learn there —reading the datasheet, configuring a peripheral bit by bit, measuring timing— carries over unchanged to a 200 MHz ARM. It doesn't work the other way around: whoever starts with libraries never sees what is underneath.

02The pinout

It is the first useful page of any datasheet. It shows the package with its numbered pins and, for each one, all the functions it can perform, separated by slashes.

microcontroller 28-pin DIP package 1 PC6 / RESET 2 PD0 / RXD 3 PD1 / TXD 4 PD2 / INT0 5 PD3 / INT1 / OC2B 6 PD4 / T0 7 VCC 8 GND 9 PB6 / XTAL1 10 PB7 / XTAL2 11 PD5 / OC0B 12 PD6 / OC0A 13 PD7 / AIN1 14 PB0 / ICP1 15 PB1 / OC1A 16 PB2 / SS / OC1B 17 PB3 / MOSI 18 PB4 / MISO 19 PB5 / SCK 20 AVCC 21 AREF 22 GND 23 PC0 / ADC0 24 PC1 / ADC1 25 PC2 / ADC2 26 PC3 / ADC3 27 PC4 / SDA 28 PC5 / SCL Power: a 100 nF capacitor on each pair, and all pairs connected Reset and in-circuit programming (ICSP/ISP) Oscillator: crystal with its two capacitors, as close as possible Communication and analog inputs: fixed on these pins Almost every pin has several functions: the slash separates the alternatives, and the program has to pick one.
Figure 1. Pins of a 28-pin microcontroller, animated. The groups are highlighted in turn: power, reset and programming, oscillator, and input-output ports. Almost every pin has several functions and you have to choose which one is used.
GroupTypical pinsWhat to get right
PowerVDD / VCC y VSS / GNDA 100 nF capacitor right next to each pair, and if there are several pairs, all of them connected. Without that capacitor the micro resets by itself.
ResetMCLR̄ / RESET̄Active low: it goes with a 10 kΩ resistor to the positive supply. Leaving it floating is the number one reason a micro “won’t start.”
OscillatorOSC1/OSC2, XTAL1/XTAL2Crystal with its two 22 pF capacitors, as close as possible. If the internal oscillator is used, those pins are free to use as I/O.
ProgrammingICSP: MCLR, PGD, PGC · ISP: MOSI, MISO, SCK, RESETIt pays to bring them out to a connector even if the project is final: reprogramming without desoldering is worth its weight in gold.
AnalogAN0…ANn, VREFAt power-up, many pins start out configured as analog. If you want them digital, you have to say so explicitly.
PeripheralsTX/RX, SDA/SCL, SDO/SDI/SCK, CCP/PWM, INTThey are fixed to certain pins: the printed circuit board has to respect them, or you have to use pin remapping if the chip offers it.
The classic trap: analog pins by default

On many PICs, after reset the ANSEL register (or ADCON1) leaves several pins as analog inputs. A program that reads them as digital always gets zero, with nothing to indicate the error. The first lines of any serious program configure those registers. On AVR something similar happens with the comparator and with DIDR.

03Special function registers

The CPU has no “instructions for turning on an LED.” What it has is access to a set of named memory locations —the SFRs— where each bit governs something in the hardware. All peripheral handling comes down to reading and writing those bits.

// Three ways to write the same thing (AVR): set bit 5 of port B to 1
PORTB = PORTB | 0b00100000;   // explicit, hard to read
PORTB |= (1 << PB5);           // the idiomatic form
PORTB |= _BV(PB5);            // with the library macro

// And to clear it, the inverted mask
PORTB &= ~(1 << PB5);

// Test an input bit
if (PIND & (1 << PD2)) { /* pin 2 is high */ }

These few lines are 90% of the work with registers. They come straight from the bitwise operators covered in the C language.

How to read a register in the datasheet

Each register appears with its eight bits, the name of each one, whether it is read, write or both, and its value after reset. That last item is the one most often overlooked: if a bit starts at 1, the peripheral is already doing something before the program says anything.

The other important convention: an overbar over the name, or a trailing n (MCLRn, CSn), means active low.

Read-modify-write

PORTB |= (1<<PB5) doesn’t just write: it reads the port, changes one bit and writes it back. If another pin on the same port is loaded —an LED that pulls the voltage down, a pin that is still switching— what is read is not what had been written, and that pin changes state by itself. It is a famous PIC bug. The fix is the LAT register, which returns the last value written instead of the actual state of the pin: LATB |= (1<<5).

04Input and output ports

Each digital pin is handled with two or three registers, and it is worth getting the mechanism clear because it is identical in all families, even though the names change.

DDRB 0 0 0 0 0 0 0 bit 5 PORTB 0 0 0 0 0 0 0 bit 5 Only bit 5 is shown; it controls pin PB5. pin PB5 enables the output 0 0 button to ground read here DDR = 0 · the pin is an input: the pushbutton is read 0 1 button to ground read here internal pull-up DDR = 0 and PORT = 1 · input with internal resistor: no longer floating 1 1 LED ground DDR = 1 and PORT = 1 · output high: the LED turns on 1 0 LED ground DDR = 1 and PORT = 0 · output low: the LED turns off
Figure 2. The path of a pin, animated. The direction register decides whether the pin faces outward or inward; the data register sets the level when it is an output; the read register returns what is on the pin when it is an input.
PICAVRFunction
DirectionTRISxDDRxInput or output
WritePORTx / LATxPORTxOutput level
ReadPORTxPINxActual state of the pin
Pull-up resistorWPUx / OPTIONPORTx with DDR set to inputPrevents floating inputs
The two conventions are opposite: don’t mix them up

On PIC, TRIS set to 1 is an input (the mnemonic: 1 looks like an I for input, 0 like an O for output). On AVR, DDR set to 1 is an output. It is exactly the opposite, and it is the most common confusion for anyone moving from one family to the other. A pin configured as an output by mistake, connected to a pushbutton that pulls it to ground, gets destroyed.

Example · How much current a pin can handle
  • AVR: 40 mA absolute maximum per pin, 20 mA recommended, and 200 mA in total for the whole chip.
  • Mid-range PIC: 25 mA per pin, and 200 mA summing the whole port.
  • A red LED with a 2 V drop supplied from 5 V through 330 Ω draws (5 − 2)/330 = 9.1 mA: no problem at all.
  • Eight LEDs on at once on the same port draw 73 mA: still within limits, but at 20 mA each it would be 160 mA and the chip heats up and the voltages drift.
  • A 12 V, 30 mA relay, a motor or a lamp never connect directly: they need a transistor (the transistor as a switch) with its flyback diode.

05The three memories and the configuration bits

MemoryPIC16F877AATmega328PWhat it holds
Flash8 K words of 14 bits32 KBThe program. It is loaded with the programmer or with a bootloader.
SRAM368 B2 KBVariables and stack. It is erased when power is removed.
EEPROM256 B1 KBConfiguration, calibration, counters: whatever must survive a power cut.
368 bytes of RAM are 368 bytes

A 40-character text string eats 11% of the RAM of a 16F877A. An array of 100 16-bit integers doesn’t fit. The compiler doesn’t always warn you: the program compiles, gets programmed and fails in strange ways when the stack collides with the variables. That is why on small microcontrollers you use right-sized types (uint8_t instead of int), avoid strings and keep constants in Flash.

Configuration bits: what is decided before the program runs

They are called configuration bits on PIC and fuses on AVR. They are not data memory: they are programmed along with the program and define how the chip starts up.

  • Clock source: crystal, resonator, internal oscillator, with or without the divide-by-8. It is the fuse that most often leaves a chip “dead”: if an external crystal is selected and there is no crystal, the micro doesn’t start and can’t be reprogrammed the normal way either.
  • Watchdog: enabled or not, and with what timeout.
  • Brown-out: at what voltage the chip resets if the supply drops.
  • MCLR as reset or as an input pin.
  • Code protection: prevents reading the Flash. It is used in a finished product; in the workshop it is best left off.

06The instruction set

A mid-range PIC has 35 instructions. You don’t need to memorize them, but you do need to understand which classes exist and how long each thing takes, because the real timing of the program comes from there.

ClassExamplesWhat they do
Data transferMOVLW, MOVWF, MOVFMove data between the accumulator (W) and memory.
Arithmetic and logicADDWF, SUBWF, ANDWF, XORWFOperate, leaving the result in W or in the register.
Bit-orientedBSF, BCF, BTFSS, BTFSCSet, clear and test a bit. They are what make handling peripherals so convenient.
ControlGOTO, CALL, RETURN, RETFIEJumps, subroutines and return from interrupt.
SpecialCLRWDT, SLEEP, NOPRefresh the watchdog, sleep, waste a cycle on purpose.
Example · How long a delay really takes

A PIC with a 4 MHz crystal. The clock is divided by 4, so one instruction cycle lasts 1 µs.

  • Almost all instructions take one cycle: 1 µs.
  • The ones that jump —GOTO, CALL, and the test instructions when they actually skip— take two.
  • A delay loop of three instructions repeated 250 times takes about 750 µs; by nesting two such loops you reach the millisecond with microsecond precision.

That calculation is the reason a micro can guarantee a timing, something that is impossible on a computer with an operating system. It is also why loop delays get replaced by timers as soon as the program does more than one thing (peripherals).

Assembly and C coexist

Today almost everything is written in C, and that is fine: it is faster to write and to maintain. But it pays to know how to read the assembly the compiler generates, because it is the only way to answer questions like “how many cycles does this interrupt service routine take?” or “why isn’t this variable updating?” In current environments you see it with one click (disassembly window).

07Special features

Watchdog

An independent counter that resets the chip if the program doesn’t refresh it in time. It is the safety net against a hang: an infinite loop caused by noise or unexpected data doesn’t leave the equipment dead, it restarts it.

It is refreshed with CLRWDT (or wdt_reset()) in the main loop, never inside an interrupt: if the main program hangs and the interrupt keeps running, the watchdog would never act.

Brown-out reset

It monitors the supply and holds the chip in reset while the voltage is below a threshold. Without it, when the voltage drops slowly the micro keeps executing with corrupted data: it writes garbage to the EEPROM and activates outputs at random. In equipment that handles power, enabling it is not optional.

Low-power modes

SLEEP stops the CPU clock and drops consumption from milliamperes to microamperes. The chip wakes up on an interrupt, on the watchdog or on a change on a pin. It is what lets a battery-powered sensor last for years.

Power-on reset and startup

The chip waits for the supply to stabilize and only then executes the first instruction, which is always at address 0. That delay is configurable and should be left enabled: without it, the micro starts before the rest of the circuit.

08In the lab

Lab 1 · The minimal circuit

Build on a breadboard the bare minimum for the micro to live: power supply with a 100 nF capacitor, MCLR with its 10 kΩ resistor, crystal with its two capacitors and a programming connector. Program something that just turns on an LED. Then remove the decoupling capacitor and observe that the micro resets or runs erratically. It is the quickest demonstration of why it is there.

Lab 2 · Registers by hand

Without using any library, write the direction and level configuration of a whole port and build an 8-LED binary counter. Then read the datasheet and add the configuration of the analog pins so the ones that were missing work too. Write down which register solved each problem.

Lab 3 · Measuring the clock

Write a loop that toggles a pin as fast as possible and measure the frequency with the oscilloscope. From that measurement and the number of instructions in the loop, calculate the instruction time and compare it with the crystal. Repeat after changing the fuses to the internal oscillator and compare the stability.

Lab 4 · Watchdog and low power

Enable the watchdog and deliberately cause an infinite loop: the equipment must restart. Then measure the micro’s current while running and with SLEEP, waking it with a pushbutton. The difference —from tens of milliamperes to microamperes— explains by itself the design of any battery-powered device.

Lab 5 · EEPROM

Store a power-up counter in EEPROM and display it at startup. Cut and restore power several times. Discuss how many times per day it would be written if the counter were in the main loop, and how long it would take to exhaust the 100,000 cycles of that cell.

09Common mistakes

SymptomUsual cause
The micro won’t start and can’t be programmed eitherFuses set for an external oscillator and no crystal on the circuit board. It is recovered with a programmer that injects a clock, or with high voltage.
It resets by itself, especially when a relay is activatedThe 100 nF capacitor is missing, or the flyback diode, or the ground is badly distributed.
A digital input always reads 0The pin was left configured as analog by default.
A pushbutton reads random valuesFloating input: the pull-up (internal or external) or the debouncing is missing.
When writing one bit of a port, another pin changes by itselfRead-modify-write on PORT with a load. Use LAT.
The program compiles but behaves erraticallySRAM has run out: the stack overwrites the variables. Check the memory map the compiler reports.
It works powered by the programmer but not from its own power supplyInsufficient or poorly filtered supply, or not all the VDD/VSS pairs are connected.
The EEPROM filled up with corrupted dataWrites during a voltage dip. Enable brown-out.
The equipment hangs once a weekNo watchdog. With a watchdog it restarts by itself and there is also a record that it happened.

10Self-assessment

What is the difference between TRIS on a PIC and DDR on an AVR?

The convention is opposite: on a PIC, TRIS set to 1 configures the pin as an input; on an AVR, DDR set to 1 configures it as an output. Mixing them up can destroy a pin that ends up as an output against a pushbutton to ground.

Why is it better to use LAT instead of PORT for writing?

Because writing to PORT involves first reading the actual state of the pins. If a pin is loaded, what is read doesn’t match what was written and that pin changes state. LAT returns the last value written, without looking at the pin.

A PIC with a 4 MHz crystal: how long does an instruction cycle last?

The clock is divided by four: 4 MHz/4 = 1 MHz, that is, 1 µs per instruction. Jump instructions take 2 µs.

What are fuses or configuration bits and why are they dangerous?

They define how the chip starts up —clock, watchdog, brown-out, MCLR function, code protection— and are programmed along with the program. If you select a clock that the circuit board doesn’t have, the micro doesn’t start and can’t be reprogrammed the usual way.

How much current can a pin deliver and what do you do if you need more?

On the order of 20 to 25 mA, with a total limit per chip of about 200 mA. For more, use a transistor or a MOSFET as a switch, with its base resistor and the flyback diode if the load is inductive.

What is the watchdog for, and where must it NOT be refreshed?

It resets the chip if the program stops refreshing it, getting it out of a hang. It must not be refreshed inside an interrupt: if the main program hangs and the interrupt keeps running, the watchdog would never act.

What does the brown-out reset protect against?

It prevents the micro from executing with the supply below its minimum, a situation in which it can corrupt the EEPROM and activate outputs at random. It holds the micro in reset until the voltage recovers.

A 16F877A has 368 bytes of RAM. Does an array of 100 16-bit integers fit?

No: 100 × 2 = 200 bytes for that array alone, plus the other variables and the stack. Even though numerically it looks like it fits, in practice it leaves the program with no margin and it ends up failing.

Why can a digital input always read zero even though the circuit is fine?

Because the pin is configured as an analog input, which is the default state of many pins after reset. You have to configure the corresponding registers (ANSEL, ADCON1) to switch them to digital.

What concrete advantage is there in bringing the programming connector out on the final circuit board?

It lets you reprogram the equipment without desoldering the micro, update the program at the installation site and, during development, load dozens of versions per day. It costs one five-pin connector.

Development of the topic “The microcontroller family” of Digital Electronics III (Year 6), based on the “Curriculum Proposal – Second Cycle of the Technical-Vocational Track, Secondary Education – Electronics,” Ministry of Education of the Province of Córdoba, DGETyFP. Back to the Topic Map · catto.ar