UNIT 1: INTRODUCTION TO MICROCONTROLLER & EMBEDDED SYSTEM LAB
A. INTRODUCTION & FUNDAMENTALS
Microcontroller (MCU) vs. Microprocessor (MPU):
| Feature | Microcontroller (MCU) | Microprocessor (MPU) |
|---|---|---|
| Core | CPU + integrated peripherals on single chip | CPU only (requires external chips) |
| Cost & Size | Low cost, small footprint | Higher cost, larger system |
| Power | Low power consumption | Higher power consumption |
| Application | Dedicated, embedded control tasks | General-purpose computing (PCs, servers) |
| Example | 8051, AVR, PIC, ARM Cortex-M | Intel Core, AMD Ryzen |
Embedded System Definition:
A dedicated computer system designed for specific control functions within a larger mechanical/electrical system, often with real-time constraints. It is typically resource-constrained and programmed for a fixed purpose.
Typical Applications: Automotive (engine control), Consumer electronics (remote), Industrial (PLC), IoT devices.
Key Components of a Microcontroller:
-
CPU/Core: Executes instructions (e.g., 8-bit, 32-bit).
-
Memory:
-
ROM/Flash: Non-volatile, stores program code.
-
RAM: Volatile, stores runtime data/variables.
-
EEPROM: Non-volatile, stores configuration/data (small).
-
-
I/O Ports: Pins configurable as digital input/output (GPIO).
-
Timers/Counters: Generate precise time delays, count events, or produce PWM signals.
-
Interrupt System: Allows peripheral/event to pause normal execution for urgent service.
-
Communication Peripherals:
-
UART/Serial: Asynchronous serial communication (e.g., RS-232).
-
SPI: Synchronous serial (master-slave, full-duplex).
-
I²C: Synchronous serial (multi-master, multi-slave, 2-wire).
-
-
Analog Peripherals:
-
ADC (Analog-to-Digital Converter): Converts analog voltage to digital value.
-
DAC (Digital-to-Analog Converter): Converts digital value to analog voltage (less common).
-
B. DEVELOPMENT TOOLCHAIN & HARDWARE SETUP
Integrated Development Environment (IDE):
-
Purpose: Single application for writing, compiling, debugging, and programming.
-
Common Examples: Keil µVision (8051/ARM), MPLAB X (PIC), Arduino IDE (AVR/ARM), STM32CubeIDE (ARM).
-
Key Tasks: Code editor, project management, compiler/linker control, debugger interface, programmer interface.
Compiler/Assembler & Linker Toolchain Process:
Source Code (.c/.s)
→ [Compiler/Assembler]
→ Object File (.obj/.o)
→ [Linker]
→ Executable/Hex File (.hex/.elf)
-
Compiler: Translates high-level C code to assembly/machine code.
-
Assembler: Translates assembly code to machine code (object file).
-
Linker: Combines multiple object files and libraries, resolves addresses, produces final executable image.
Hardware Components:
-
Microcontroller Development Board/Kit:
- Key Parts: Power connector (USB/barrel jack), Reset button, I/O headers (rows of pins), Communication ports (USB-UART, USB), Programming interface header (JTAG/SWD).
-
Programmer/Debugger/ICE:
-
Purpose: Loads hex file into MCU flash and/or provides real-time debugging.
-
Types: Dedicated hardware (USBasp, AVRISP), On-board debugger (via USB), Standard interfaces (JTAG, SWD).
-
-
Basic External Components: LEDs (with current-limiting resistors ~330Ω), push-button switches, breadboard, jumper wires (male-to-male, male-to-female).
First Connection & Setup:
-
Connect programmer/debugger to PC (usually via USB).
-
Connect programmer to board's programming header (correct orientation!).
-
Connect board to power source (USB or external).
-
Open IDE, create/select project for correct target MCU.
-
Build project → generate hex file.
-
Use IDE's "Download" or "Program" function to flash hex file.
-
Verify: IDE should confirm successful programming; board may reset and run new code.
[!TIP] Common Pitfall: Always verify target device selection in IDE matches your physical MCU. A mismatch causes programming failures or erratic behavior.
C. BASIC PROGRAMMING & I/O OPERATIONS
"Hello World": Blinking an LED Concept: GPIO (General Purpose Input/Output) pin configured as output. Steps:
-
Identify MCU pin connected to LED (e.g.,
P1.0on 8051,PB5on ATmega). -
In code, configure that pin's port direction register as output (set corresponding bit to
1). -
In infinite loop:
-
Set pin high (
1) → LED ON. -
Software Delay: Execute empty loops for approx. time.
-
Set pin low (
0) → LED OFF. -
Repeat delay. Critical: Delays must be calibrated based on MCU clock frequency.
-
Reading Digital Input: Push-button Switch Concept: Configure pin as input. Use pull-up/pull-down resistor to define default state.
-
Internal Pull-up: Many MCUs have internal resistors. Configure pin as input, enable internal pull-up. Button connects pin to GND when pressed (active-low logic: pressed =
0). -
External Pull-up: 10kΩ resistor from pin to Vcc. Button connects pin to GND. Steps:
-
Configure port pin as input.
-
Read port input register.
-
Use
ifstatement:if (PIN_state == 0) { // Button pressed }. Simple Application: Toggle LED state on each button press (requires state change detection, not just level check).
Introduction to Registers & Bit Manipulation:
-
Special Function Registers (SFRs): Memory-mapped locations controlling MCU hardware (e.g.,
PORTB,DDRB,TCCR0). -
Bitwise Operations (Essential):
-
Set a bit:
REG |= (1 << bit_number);// OR with 1 -
Clear a bit:
REG &= ~(1 << bit_number);// AND with 0 -
Toggle a bit:
REG ^= (1 << bit_number);// XOR -
Read a bit:
(REG >> bit_number) & 0x01;
-
-
Using
#defineor Header Files:#define LED_PIN PB5 #define LED_DDR DDRB #define LED_PORT PORTB // Usage: LED_DDR |= (1 << LED_PIN); // Set as output LED_PORT |= (1 << LED_PIN); // LED ON
[!TIP] Golden Rule: Never assign a value directly to a whole port register if you only want to change one bit (e.g.,
PORTB = 0x20;). This will override all other pin states. Always use bitwise operations.
D. DEBUGGING & TROUBLESHOOTING FUNDAMENTALS
Debugger/Breakpoint Basics:
-
Breakpoint: Pauses execution at a specific line. Allows inspection of register values, memory, and variables.
-
Single-Step (Step Into/Over): Executes one instruction/line at a time.
-
Watch Window: Monitor variable/register values in real-time.
-
Run to Cursor: Executes until a specific line is reached.
Common First-Program Errors:
| Error Category | Symptom | Likely Cause |
|---|---|---|
| Configuration | MCU doesn't run, resets constantly | Wrong fuse bits/clock settings (e.g., expecting external crystal but none present). |
| Pin Mapping | LED doesn't blink, button not read | Wrong pin number in code vs. board schematic. |
| Logic | LED always ON/OFF, no delay | Missing/infinite delay loop, pin direction configured incorrectly. |
| Hardware | Nothing works | Loose wires, reversed polarity on LED/resistor, dead component, insufficient power. |
Using the Serial Monitor/Console (UART):
-
Initialization: Configure baud rate, data bits, stop bits, parity in UART peripheral registers. Connect MCU's TX (Transmit) pin to PC's RX (via USB-UART converter).
-
Sending Data: Use function like
printf()(requiresstdio.hand proper retargeting) or low-levelputchar()/UART_Write().printf("System Initialized. Counter = %d\n", count); -
PC Terminal: Open Serial Terminal software (e.g., PuTTY, Tera Term, Arduino Serial Monitor) at the configured baud rate. Purpose: Print debug messages, variable values, program state without a debugger.
[!TIP] Debugging Strategy: 1) Verify hardware (connections, power). 2) Simplify (blink LED with no button). 3) Add serial prints to trace execution flow. 4) Use debugger to inspect registers if stuck.
E. INTRODUCTION TO INTERRUPTS & TIMERS (Conceptual & Simple Application)
Polling vs. Interrupt-Driven Programming:
| Polling | Interrupt-Driven |
|---|---|
| MCU actively checks status of events/peripherals in main loop. | Hardware signals MCU when an event occurs. MCU pauses main code to service it. |
| Wastes CPU cycles checking when no event. | Efficient – CPU sleeps or does other tasks until needed. |
| Poor response time – event detected only when polled. | Deterministic, fast response to critical events. |
| Simple for trivial systems. | Essential for real-time systems (e.g., communication, precise timing). |
Timer/Counter Module Basics:
-
Purpose: Generate precise time intervals, count external pulses, create PWM.
-
Basic Configuration:
-
Clock Source: Internal (system clock) or external (pin).
-
Prescaler: Divides clock source to slow counting (e.g.,
/8,/64,/256). -
Mode: Normal (count up to TOP), CTC (Clear Timer on Compare), PWM.
-
Initial Count Value: Load starting value into timer register (e.g.,
TCNT0). -
Compare/Match Value: Value to trigger an event/interrupt (e.g.,
OCR0).
-
-
Period Calculation (Normal Mode):
$$ T_{period} = \frac{Prescaler \times (TOP - Initial + 1)}{F_{cpu}} $$
Where `TOP` is max value (e.g., 255 for 8-bit, 65535 for 16-bit).
Simple Interrupt Service Routine (ISR):
-
Writing a Minimal ISR:
// For AVR (GCC) #include <avr/interrupt.h> volatile uint8_t flag = 0; // Shared variable MUST be volatile ISR(TIMER0_OVF_vect) { // ISR for Timer0 Overflow flag = 1; // Set a flag in ISR // Toggle LED directly (short ISR best practice) PORTB ^= (1 << PB0); } -
Interrupt Enable/disable Sequence:
-
Configure Timer (prescaler, mode).
-
Enable Timer Interrupt (set bit in
TIMSKregister). -
Enable Global Interrupts (
sei();in AVR,__enable_irq();in ARM). -
Main Loop: Can now be empty or do other tasks. ISR runs automatically on overflow.
-
-
volatileKeyword: Tells compiler that a variable (flag) can change asynchronously (in ISR), preventing compiler optimizations that cache its value in a register.
[!TIP] ISR Best Practice: Keep ISRs short and fast. Do minimal work (e.g., set a flag, toggle a pin). Defer complex processing to the main loop. Never use
delay()or blocking functions inside an ISR.