UART Serial Communication Configuration and Data Transfer Techniques
Key UART Communication Registers
Two primary registers manage serial communication: the Power Control Register (PCON) and the Serial Control Registre (SCON).
PCON Register
SMOD (bit 7): Baud rate doubling control for modes 1, 2, 3. 1 = double rate, 0 = default rate.
SMOD0 (bit 6): Frame error detection control. 1 = SCON.SM0 used for error checking; 0 = SM0/SM1 for mode selection.
SCON Register
SM0/SM1 (bits 7/6): Mode selectors when SMOD0 = 0:
00 = Mode 0 (Shift register mode)
01 = Mode 1 (8-bit async, variable baud)
10 = Mode 2 (9-bit async, fixed baud)
11 = Mode 3 (9-bit async, variable baud)
SM2 (bit 5): Multi-processor control enable for modes 2, 3
REN (bit 4): Receive enable. 1 = allow receive, 0 = disable receive.
TB8/RB8 (bits 3/2): 9th data/parity bits (unused in basic scenarios)
TI (bit 1): Transmit interrupt request flag (auto-set after send completion)
RI (bit 0): Receive interrupt request flag (auto-set after receive completion)
Baud Rate Calculations
- Mode 0:
Fosc / 12(fixed, e.g., 11.0592MHz → 921,600 bps) - Mode 1/3:
(2^SMOD / 32) × Timer 1 overflow rate - Mode 2:
(2^SMOD / 64) × Fosc
Timer 1 overflow rate:
- 12T (normal mode):
Fosc / 12 / (256 - TH1) - 6T (fast mode):
Fosc / 6 / (256 - TH1)
UART Enitialization Code (9600 bps @ 11.0592MHz)
#include <REGX52.H>
#define FOSC_110592 1
void UART_Init(void) {
PCON &= 0x7F; // Disable baud rate doubling
SCON = 0x50; // Mode 1 (8-bit, variable), receive enabled
AUXR &= 0xBF; // Timer 1 clock = Fosc/12 (12T)
AUXR &= 0xFE; // UART1 uses Timer 1 as baud generator
TMOD &= 0x0F; // Clear Timer 1 mode bits
TMOD |= 0x20; // Timer 1: 8-bit auto-reload
TL1 = 0xFD; // Timer initial value
TH1 = 0xFD; // Auto-reload value
ET1 = 0; // Disable Timer 1 interrupt
TR1 = 1; // Start Timer 1
}
Transmit a String to a PC
#include <REGX52.H>
#include "intrins.h"
sfr AUXR = 0x8E;
void Delay_1s(void) {
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do { do { while(--k); } while(--j); } while(--i);
}
void UART_Init(void) {
PCON &= 0x7F;
SCON = 0x40;
AUXR = 0x01;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
TR1 = 1;
}
void SendByte(char dataByte) {
SBUF = dataByte;
while(!TI); // Wait for transmit completion
TI = 0; // Clear interrupt flag
}
void SendString(char *str) {
while(*str != '\0') {
SendByte(*str++);
}
}
void main(void) {
UART_Init();
while(1) {
SendString("helloworld");
Delay_1s();
}
}
Control an LED via PC Commmand
#include <REGX52.H>
#include "intrins.h"
sfr AUXR = 0x8E;
sbit LED1 = P3^7;
void Delay_300ms(void) {
unsigned char i, j, k;
_nop_();
i = 3;
j = 26;
k = 223;
do { do { while(--k); } while(--j); } while(--i);
}
void UART_Init(void) {
PCON &= 0x7F;
SCON = 0x40;
REN = 1;
AUXR = 0x01;
TMOD &= 0x0F;
TMOD |= 0x20;
TL1 = 0xFD;
TH1 = 0xFD;
TR1 = 1;
}
void main(void) {
char cmd;
LED1 = 1;
UART_Init();
while(1) {
Delay_300ms();
if(RI == 1) {
RI = 0;
cmd = SBUF;
if(cmd == 'o') LED1 = 0;
if(cmd == 'c') LED1 = 1;
}
}
}