MC&A Unit 4,5,6-5
MC&A Unit 4,5,6-5
6
Overview of Serial Communication in 8051
Why is serial communication important in microcontrollers?
Parallel vs Serial Communication
Types of Serial Communication in 8051
UART (Universal Asynchronous Receiver-Transmitter)
I2C (Inter-Integrated Circuit)
SPI (Serial Peripheral Interface)
Understanding Parallel vs. Serial Communication
Parallel Communication
Multiple data lines transmit data simultaneously.
Faster but requires more wires
Serial Communication in 8051 Microcontroller
Serial Communication
Data sent one bit at a time over a single wire.
Slower but longer distance and fewer connections.
Understanding Parallel vs. Serial Communication
Why do we need serial communication?
8051 uses limited GPIO pins.
Parallel communication needs too many wires.
Serial communication saves pins and allows long-distance transmission.
8051 supports multiple serial protocols.
UART (for PC interfaces, Bluetooth, GPS).
I2C (for sensors, EEPROMs, LCDs).
SPI (for high-speed devices like Flash memory and TFT displays).
Understanding Parallel vs. Serial Communication
Feature Serial Communication Parallel Communication
Definition Data is transmitted bit-by-bit over a single wire or pair of wires. Data is transmitted byte-by-byte using multiple wires.
Transmission Distance Can be used for long-distance communication. Limited to short distances due to signal degradation.
Data Transfer Mode Bit-by-bit transfer (one bit at a time). Multiple bits transferred simultaneously.
Synchronization Requires clock synchronization in some cases (e.g., SPI, I2C). No need for additional clock synchronization.
Used in communication between microcontrollers, sensors, memory Used inside computers for CPU-RAM communication,
Applications
devices (UART, I2C, SPI, CAN, USB, RS-232). LCD interfacing, and buses like PCI, PCIe.
Cost & Complexity Lower cost due to fewer wires and simpler circuits. Higher cost due to multiple wires and complex wiring.
Example:
UART is asynchronous (data is framed with start and stop bits).
I2C and SPI are synchronous (clock signal ensures synchronized data transfer).
Important Terminologies
Parity Bit (Error Detection)
Definition: A single bit used for error detection.
Types:
Even Parity: The number of 1s in data + parity bit is even.
Odd Parity: The number of 1s in data + parity bit is odd.
Example:
Data = 1010 0001
Even Parity Bit = 1
Transmitted Data = 1010 0001 1
Important Terminologies
Stop & Start Bits
Start Bit: Indicates the beginning of a data frame (Always 0).
Stop Bit: Marks the end of a frame (1 or 2 bits long).
Used in: UART communication.
Example: Start (0) + Data (10101010) + Stop (1)
Important Terminologies
Acknowledgment (ACK/NACK)
Definition: A signal sent by the receiver to confirm data reception.
Used in: I2C protocol.
ACK (Acknowledge) → Receiver successfully received data (pulls SDA LOW).
NACK (Not Acknowledge) → Receiver did not receive data correctly (pulls SDA HIGH).
Important Terminologies
Master & Slave Devices
Master: Controls the communication (sends commands & clock signal).
Slave: Responds to the master.
Used in: I2C and SPI protocols.
Example:
I2C RTC Module (DS1307) as Slave, 8051 as Master.
SPI Flash Memory (Slave) controlled by 8051 (Master).
Important Terminologies
Transmission Modes: LSB vs. MSB First
LSB (Least Significant Bit) First: Transmits the lowest bit first. - Little Endian
MSB (Most Significant Bit) First: Transmits the highest bit first - Big Endian
Used in: SPI, I2C, UART depending on settings.
Example:
Data: 11010110
MSB First: 11010110
LSB First: 01101011
Two competing kingdoms, Lilliput and Blefuscu, have different customs for breaking eggs. The inhabitants of Lilliput break their eggs at the little
end and hence are known as little endians, while the inhabitants of Blefuscu break their eggs at the big end, and hence are known as big endians.
The novel is a parody reflecting the absurdity of war over meaningless issues. The terminology is fitting, as whether a CPU is big-endian or little-
endian is of little fundamental importance."
Important Terminologies
Pull-up and Pull-down Resistors
Definition: Resistors used to keep signals at a defined logic level.
Used in: I2C (SDA, SCL lines need pull-up resistors to work correctly).
Example: 4.7kΩ resistors used in I2C communication.
Important Terminologies
Buffer & FIFO (First In, First Out)
Buffer: A temporary storage for data before processing.
FIFO: A queue-based system where the first data received is the first processed.
Used in: UART for handling multiple incoming bytes.
Signal Integrity (Crosstalk & Noise)
Crosstalk: Unwanted signals caused by electromagnetic interference.
Noise: Random electrical disturbances affecting communication.
How to Reduce: Use shielded cables, proper grounding, pull-up resistors.
UART in 8051
Universal Asynchronous Receiver-Transmitter (UART)
Asynchronous Communication → No clock signal is shared.
Uses start and stop bits to frame the data.
Common in RS-232, GPS, Bluetooth.
8051 has one built-in UART module.
UART Communication Frame Format
UART Data Frame Structure:
Start Bit (1 bit)
Data Bits (5-8 bits)
Parity Bit (Optional)
Stop Bit (1-2 bits)
Example: 9600 baud rate, 8-N-1 format
8-bit data, No parity, 1 stop bit
8051 Serial Communication Registers
Registers in 8051 for Serial Communication:
SCON (Serial Control Register): Configures UART mode.
TMOD (Timer Mode Register): Configures Timer1 for baud rate generation.
TH1 (Timer 1 High Byte): Defines baud rate settings.
SCON (Serial Control Register) – Configures UART Mode
SCON (Serial Control Register) is an 8-bit register that controls the serial communication
mode, baud rate, and interrupt flags.
Parallel communication
Mode 0 0 0 Fixed (Oscillator/12) 8-bit Shift Register
(Rarely used)
Multiprocessor
Mode 2 1 0 Fixed (Oscillator/32 or /64) 9-bit UART
Communication
Most common mode in 8051 UART is Mode 1 (SM0 = 0, SM1 = 1), which allows standard UART communication.
SM2 (Multiprocessor Mode Enable)
Used in Modes 2 & 3 only.
If SM2 = 1, the microcontroller will only receive data if the 9th bit (RB8) is 1.
This is useful in multiprocessor communication, where one device sends a special address byte to multiple
receivers.
Bit 7 GATE1 1 → Timer1 starts only if INT1 (external pin) is HIGH. 0 → Timer1 starts when TR1 = 1 (software start).
Bit 6 C/T1 0 → Timer1 counts machine cycles (Timer mode). 1 → Timer1 counts external events from T1 pin (Counter mode).
Bit 5 M11 Used with M10 to select Timer1 mode.(See Timer Mode Selection Table Below).
Bit 3 GATE0 1 → Timer0 starts only if INT0 (external pin) is HIGH. 0 → Timer0 starts when TR0 = 1 (software start).
Bit 2 C/T0 0 → Timer0 counts machine cycles (Timer mode). 1 → Timer0 counts external events from T0 pin (Counter mode).
Bit 1 M01 Used with M00 to select Timer0 mode.(See Timer Mode Selection Table Below).
The TH1 register controls the baud rate in Mode 1 and Mode 3.Formula for Baud Rate
Calculation
The baud rate is determined using the following formula:
For 11.0592 MHz Crystal, the common baud rate settings are:
SM0 = 0, SM1 = 1 → UART Mode 1 (8-bit data, start & stop bit).
REN = 1 → Enables the receiver.
TI & RI → Flags for transmission & reception.
Step 3: Enabling Serial Interrupts (Optional)
If you want automatic UART handling, enable serial interrupts.
TI = 0; // Clear TI flag }
} }
Bit 7 6 5 4 3 2 1 0
Value 0 0 1 0 0 0 0 0
The value 0xFD (Hexadecimal) is chosen specifically to generate a 9600 baud rate when using an 11.0592 MHz crystal oscillator..
3 (TB8) 9th Bit for Transmission 0 Not used in 8-bit UART Mode
2 (RB8) 9th Bit for Reception 0 Not used in 8-bit UART Mode
ORG 0000H ; Start program at address 0000H Sets up UART for 9600 baud.
Sends the letter 'A' continuously over the serial port.
SJMP MAIN ; Jump to main program
MAIN:
MOV TMOD, #20H ; Timer1 Mode 2 (Auto-reload)
MOV TH1, #0FDH ; Load TH1 for 9600 baud rate
MOV SCON, #50H ; Mode 1, 8-bit UART, Receiver Enabled
SETB TR1 ; Start Timer1
LOOP:
MOV SBUF, #'A' ; Load character 'A' into SBUF (Transmit)
JNB TI, $ ; Wait for TI flag (Transmission complete)
CLR TI ; Clear TI flag
SJMP LOOP ; Repeat forever
END
Example 2: Receiving a Single Character via UART (Assembly)
MAIN:
MOV TMOD, #20H ; Timer1 Mode 2 (Auto-reload)
MOV TH1, #0FDH ; Load TH1 for 9600 baud rate
MOV SCON, #50H ; Mode 1, 8-bit UART, Receiver Enabled
SETB TR1 ; Start Timer1
LOOP:
JNB RI, LOOP ; Wait for RI flag (Data received)
CLR RI ; Clear RI flag
MOV R0, SBUF ; Store received data in R0
SJMP LOOP ; Keep waiting for new data
END
Example 3: UART Echo Program (Receives and Sends Back the Same Character)
#include <reg51.h>
unsigned char UART_ReceiveChar() {
while (RI == 0); // Wait until data is received
void UART_Init() {
RI = 0; // Clear RI flag
TMOD = 0x20; // Timer1 Mode 2 (Auto-reload)
return SBUF; // Return received byte
TH1 = 0xFD; // Load TH1 for 9600 baud rate
}
SCON = 0x50; // 8-bit UART Mode, Receiver Enabled
TR1 = 1; // Start Timer1
void UART_SendString(char *str) {
}
while (*str) { // Loop until end of string
UART_SendChar(*str);
void UART_SendChar(unsigned char data) { str++; // Move to next character
SBUF = data; // Load data into SBUF }
while (TI == 0); // Wait until transmission complete }
TI = 0; // Clear TI flag
} void main() {
UART_Init();
while (1) {
UART_SendString("Hello, UART!\r\n"); // Send a message
for (int i = 0; i < 30000; i++); // Simple delay
}
Introduction to I2C (Inter-Integrated Circuit)
I2C
Developed by Philips Electronics NV in the 80’s
Two-wire bus
Facilitates easy interconnection of ICs on boards
Reduces IC pin count and hence footprint
Reduces PCB trace count
Reduces EMI/RFI issues
Reduces cost
Simple to use
Introduction to I2C (Inter-Integrated Circuit)
Features
Single Master
Multiple Slaves
Devices can be added or removed without affecting any other
circuit in the system
Software addressable unique address for individual devices in
the network
Two wire system
System Clock (SCL) controlled by Master
System Data (SDA) transfer initiated by Master,
Bidirectional
Introduction to I2C (Inter-Integrated Circuit)
Features
Multiple Masters possible with Collision Detection and
Arbitration
Modular hardware architecture results in
Simpler fault diagnosis and debugging
Modular software development with reusable libraries
Extremely low power consumption
High noise immunity
Wide power supply range
Wide temperature range
Introduction to I2C (Inter-Integrated Circuit)
Terminology
Transmitter: Device that sends data to the bus
Receiver: Device that receives data from the bus
Master: Device that initiates a transfer, generates clock signals and terminates a transfer
Slave: Device addressed by a master
Multi-Master: More than one masters can attempt to control the bus at the same time
without corrupting the message
Arbitration: Procedure to ensure that, if more than one masters simultaneously try to
control the bus, only one is allowed to do so and the winning message is not corrupted
Synchronization: Procedure to synchronize the clock signals of two or more devices
Introduction to I2C (Inter-Integrated Circuit)
Technical Specifications
8-bit data transfer
Four modes of data transfer
Standard ( upto 10 Kbps)
Fast ( upto 1 Mbps)
Fast Plus (upto 3.4 Mbps)
High Speed
Bus Capacitive Load 400pF max
Rise Time
1000 nsec (Standard mode)
300 nsec (Fast mode)
Introduction to I2C (Inter-Integrated Circuit)
I2C is a two-wire, synchronous serial communication protocol used to connect multiple devices (slaves) to a single
microcontroller (master).
Step Action
Since 8051 does not have hardware I2C support, we use bit-banging to manually control SDA (Serial Data) and SCL (Serial
Clock) lines.
//Start Condition
void I2C_Start() {
SDA = 1; // Ensure SDA is HIGH
SCL = 1; // Ensure SCL is HIGH
SDA = 0; // SDA goes LOW while SCL is HIGH (Start Condition)
SCL = 0; // Pull SCL LOW to begin communication
}
Generates the Start Condition required before sending data.
SDA transitions LOW while SCL remains HIGH.
I2C in 8051
//Stop Condition
void I2C_Stop() {
SDA = 0; // SDA goes LOW
SCL = 1; // SCL goes HIGH
SDA = 1; // SDA goes HIGH while SCL is HIGH (Stop Condition)
}
Ends the I2C communication session.
SDA transitions HIGH while SCL remains HIGH.
I2C in 8051
Step 1: Sending the EEPROM Device Address (0xA0) Step 3: Sending the Data Byte (0x55)
I2C_Write(0xA0); I2C_Write(0x55);
EEPROM (e.g., 24C02) has a 7-bit address. 0x55 is the actual data being stored in the EEPROM.
The last bit (LSB) in 0xA0 is 0, meaning it is a "Write" The EEPROM writes this byte into the specified memory
operation. location (0x00).
The EEPROM listens for this address on the I2C bus.
If we wanted to READ from EEPROM, we would send 0xA1
(last bit set to 1).
Step 2: Sending the Memory Address (0x00)
I2C_Write(0x00);
EEPROM has many memory locations.
The master must tell the EEPROM which memory address it
wants to write to.
Here, 0x00 means "store the data in memory location 0x00".
void I2C_Stop() {
for (int i = 0; i < 8; i++) {
SDA = 0; SCL = 1;
SCL = 1; // Clock HIGH
SDA = 1; // Stop Condition data = (data << 1) | SDA; // Read SDA bit
} SCL = 0; // Clock LOW
}
return data;
}
Example: Sending 0xA5 = 10100101
Overview
Synchronous serial data link
Two data transfer lines
Master Out Slave In (MOSI)
Master In Slave Out (MISO)
Clock line synchronizes master as well as slave
Slave Chip Select line eliminates address transfer cycle
Serial Peripheral Interface (SPI)
Features
High speed data transfer (1 Mbps upto 50Mbps)
Full Duplex Communication
Each device on the bus acts simultaneously as a Transmitter
and a Receiver
Single Master and multiple slaves possible using multiple Chip
Select signals
Master device initiates data transfer
Master device generates clock and device select control
lines
Serial Peripheral Interface (SPI)
Serial Peripheral Interface (SPI)
Specifications
Eight or Sixteen bit data transfer
Date rates upto 1 Mbps for Master and 2 Mbps for Slave
Each transaction initiated by Master
Full Duplex data transfer possible
Clock Polarity (CPOL) configurable
CPOL = 0 → Clock is LOW when idle
CPOL = 1 → Clock is HIGH when idle
Idle means the state of the clock when the bus is not actively communicating.
Clock Phase (CPHA) configurable
CPHA = 0 → Data is sampled on first clock edge (after CS goes low)
CPHA = 1 → Data is sampled on second clock edge
This determines when the receiver reads the bit: Before or after the sender changes the
bit
Serial Peripheral Interface (SPI)
Protocol
Data transfer initiated by falling edge of SS
Data is only output during the rising or falling edge of SCK
Data is latched during the opposite edge of SCK
Opposite edge is used to ensure data is valid at the time of reading
Data is shifted MSB first
Data is transferred simultaneously on MOSI and MISO
Data transfer ended by rising edge of SS
Protocol
Data transfer for CPHA=0
Serial Peripheral Interface (SPI)
Protocol
•Data transfer for CPHA=1
Serial Peripheral Interface (SPI)
Application
Interfacing Peripherals such as
Analog to Digital Converters
Digital to Analog Converters
Real Time Clocks
LCD Modules
Sensors
Interfacing Memory such as
EEPROM
Flash Memory
Serial Peripheral Interface (SPI)
Address Function
0x00 Seconds
0x01 Minutes
0x02 Hours
}
// At this point, h, m, s contain current time in decimal
// You can send to UART or display on LCD
I2C_Delay(); // Wait before next read
}
}
Explanation
We choose Port 3.2 for SDA and Port 3.3 for SCL because 8051 doesn’t have built-in I2C. So we simulate I2C using these GPIO pins.
void I2C_Delay() {
unsigned int i;
for (i = 0; i < 200; i++);
}
This is a simple delay loop to control the speed of the I2C communication. It gives time for the devices to set or read signals properly.
Explanation
Section 3: Basic I2C Signal Functions Section 4: Sending and Receiving Bytes on I2C
Tells the RTC, "Hey, I’m starting communication!" SDA = 1; SCL = 1; I2C_Delay(); SCL = 0;
This is how I2C always begins a message. }
void I2C_Stop() {
SDA = 0; SCL = 1; Explanation:
I2C_Delay(); Sends 8 bits of data, one bit at a time
SDA = 1; MSB is sent first
I2C_Delay(); Clock is pulsed to sync the data with RTC
} After sending, we release SDA for the RTC to acknowledge
Tells the RTC, "I’m done sending data. You can rest now."
Explanation
Explanation:
Receives 8 bits from RTC
Bits are stored one by one into a byte
Used to read time registers (seconds, minutes, etc.)
Explanation
Convert BCD to Decimal This is the slave address of the DS1307 RTC in write mode.
unsigned char BCDToDecimal(unsigned char bcd) { The 7-bit base address of DS1307 is 0x68 → binary 1101000
return ((bcd >> 4) * 10) + (bcd & 0x0F); Adding the write bit (0) at the end → becomes 11010000 = 0xD0
} You are telling DS1307:
"I'm going to start writing at register 0x00 (which is seconds
Example: register)"
Decimal 45 → BCD = 0x45
BCD 0x45 → Decimal = 45
Explanation
3. Infinite Loop to Continuously Check for Key Presses 4. Column Scanning + Row Checking
while (1) { Now the program scans each column one by one and checks
while(P2 == 0x0F) { which row went LOW.
P1 = 0xFF; // Wait here if no key is pressed (all columns HIGH)
} Scanning Column 1
Column 2
C2 = 0; C1 = C3 = C4 = 1;
if(R1 == 0){P0=0x86;} // B
if(R2 == 0){P0=0x88;} // A
if(R3 == 0){P0=0x82;} // 9
if(R4 == 0){P0=0xA4;} // 8
Column 3
C3 = 0; C1 = C2 = C4 = 1;
if(R1 == 0){P0=0xA1;} // 7
if(R2 == 0){P0=0x90;} // 6
if(R3 == 0){P0=0x92;} // 5
if(R4 == 0){P0=0xF9;} // 4
Column 4
C4 = 0; C1 = C2 = C3 = 1;
if(R1 == 0){P0=0xC6;} // 3
if(R2 == 0){P0=0x80;} // 2
if(R3 == 0){P0=0x99;} // 1
if(R4 == 0){P0=0xC0;} // 0
Keypad 4x4
A Watchdog Timer is like a digital supervisor for your microcontroller. Its main
job is to reset the system if the program gets stuck or doesn’t behave as
expected.
Why is it needed?
Sometimes, due to bugs, unexpected inputs, or hardware glitches, the
microcontroller might get stuck in a loop or crash. The WDT helps recover by
automatically resetting the system and starting fresh.
Watchdog Timer
How it works:
void main() {
WDTCON = 0x01; // Enable Watchdog Timer
while (1) {
// Main code
WDT_reset(); // Reset the WDT regularly
}
}
DC Motor
A DC (Direct Current) motor converts electrical
energy into mechanical energy using direct
current. It works on the principle that a current-
carrying conductor placed in a magnetic field
experiences a force (Lorentz Force).
Working:
It consists of a stator (stationary part with
magnets) and a rotor (rotating coil/armature).
When DC voltage is applied, current flows
through the armature winding.
Magnetic interaction between the stator field
and the armature current creates torque,
causing the rotor to rotate.
DC Motor
Controlling a DC Motor
1. Using Relay (ON/OFF control): P2 = 0x0A; // Motor rotates forward (IN1=1, IN2=0, EN=1)
– OUT2 (pin 6) Output to Motor Terminal B Connect to the other motor terminal
– Vcc2 (pin 8) Motor supply (9–12V) Connect to external power for motor
// Stop
IN1 = 0;
IN2 = 0;
#include <reg51.h> delay_ms(1000);
Basic Principle:
A magnetic rotor (shaft) moves when electromagnets (stator coils) are
energized in a specific sequence.
Each pulse sent to the motor causes the rotor to move by one step.
Stepper motors don’t need feedback for position — they are open-loop
controlled.
Working of a Stepper Motor (Unipolar Example):
Let’s take a 4-phase unipolar stepper motor with 4 windings: A, B, C, D.
Step A B C D Direction
1 1 0 0 0 Step 1
2 0 1 0 0 Step 2
Applications:
Printers
CNC machines
3D printers
Robotics
Cameras (pan/tilt)
Interfacing with 8051:
You can use ULN2003 or L293D as driver IC to interface a stepper motor with 8051.
P1.0 IN1 A
P1.1 IN2 B
P1.2 IN3 C
P1.3 IN4 D
Interfacing with 8051:
#include <reg51.h> while(1) {
// Rotate 50 steps clockwise
void delay_ms(unsigned int ms) { for(i = 0; i < 50; i++) {
unsigned int i, j; P1 = step_sequence[i % 4]; // output step pattern to motor
for(i = 0; i < ms; i++) delay_ms(20); // delay between steps
for(j = 0; j < 1275; j++); // ~1ms delay }
} // Stop for 1 second
P1 = 0x00;
void main() { delay_ms(1000);
// Full-step sequence for clockwise // Rotate 50 steps counter-clockwise
rotation for(i = 0; i < 50; i++) {
unsigned char step_sequence[] = {0x01, P1 = step_sequence[3 - (i % 4)];
0x02, 0x04, 0x08}; // A, B, C, D delay_ms(20);
unsigned int i; }
// Stop for 1 second
P1 = 0x00;
delay_ms(1000);
}
}
Explanation
unsigned char step_sequence[] = {0x01, 0x02, 0x04, 0x08}; // A, B, C, D // Rotate 50 steps counter-clockwise
for(i = 0; i < 50; i++) {
Each value represents which coil to energize: P1 = step_sequence[3 - (i % 4)];
0x01 = 00000001 → Coil A (P1.0 ON) delay_ms(20);
0x02 = 00000010 → Coil B (P1.1 ON) }
0x04 = 00000100 → Coil C (P1.2 ON)
0x08 = 00001000 → Coil D (P1.3 ON) Same loop as before but in reverse by using 3 - (i % 4):
This is for full-step drive (one coil at a time). Outputs sequence in this order: D → C → B → A
(opposite of before).
This makes the motor rotate in reverse direction.
i i%4 Meaning (step index)
0 0 step 0
1 1 step 1
2 2 step 2
3 3 step 3
4 0 step 0 (repeats)