UART(Universal Asynchronous Receiver/Transmitter)は、低コストかつ高信頼性を持つ非同期シリアル通信インターフェースであり、マイコン同士、マイコンとPC、あるいは各種センサ・モジュールとの双方向データ交換を可能にします。8051アーキテクチャのマイコンには内蔵UARTが搭載されており、専用のレジスタ群を用いて送受信動作を柔軟に制御できます。
ハードウェア構成と制御レジスタ
通信動作の設定は主にSCON(Serial Control Register)およびPCON(Power Control Register)によって行われます。
- SCON(0x98):通信モード選択、受信許可、中断フラグ管理を行う。
モード1(8ビット非同期、可変ボーレート)では、REN = 1で受信を有効化。このビットが0の場合はRxDピンからの入力を無視します。 - TI(Transmit Interrupt Flag):SBUFへの書き込み完了後、送信終了時に自動的に1にセットされる。ソフトウェアで明示的に
TI = 0とリセットする必要があります。 - RI(Receive Interrupt Flag):受信バッファ(SBUF)へのデータ格納完了時に1にセットされ、割り込み要求を発行。同様に、アプリケーション側で
RI = 0としてクリアしなければならない。 - PCON(0x87):
SMOD = 1(ビット7)を設定すると、タイマー1によるボーレート生成時の分周比が2倍になり、より高い通信速度が得られます。
送信機能の実装
以下のコードは、1秒ごとにインクリメントされた値をUART経由で連続送信する例です。ボーレートは9600bps(SMOD=1時)で、タイマー1を8ビット自動再ロードモード(Mode 2)で使用しています。
#include <REGX52.H>
void UART_Init(void) {
SCON = 0x50; // モード1、REN有効
PCON |= 0x80; // SMOD = 1(ボーレート倍増)
TMOD &= 0x0F; // TMODの上位4ビットをクリア
TMOD |= 0x20; // T1: 8ビット自動再ロード
TH1 = 0xF4; // 9600bps(11.0592MHz, SMOD=1)
TL1 = 0xF4;
TR1 = 1; // タイマー1開始
}
void UART_Transmit(unsigned char data) {
SBUF = data;
while (!TI); // 送信完了待ち
TI = 0; // TIフラグクリア
}
unsigned char counter = 0;
void main(void) {
UART_Init();
while (1) {
UART_Transmit(counter++);
for (unsigned int i = 0; i < 30000; i++); // 簡易遅延(約1s)
}
}
受信とエコーバック処理
受信処理には割り込み方式が推奨されます。以下は、受信した1バイトをP2ポートに出力し、同時にPCへエコー返信する実装です。割り込みベクタ番号4(RI/TI共通)を用います。
#include <REGX52.H>
void UART_Init(void) {
SCON = 0x50;
PCON |= 0x80;
TMOD &= 0x0F;
TMOD |= 0x20;
TH1 = 0xF4;
TL1 = 0xF4;
TR1 = 1;
ES = 1; // シリアル割り込み有効化
EA = 1; // 全体割り込み有効化
}
void UART_Transmit(unsigned char data) {
SBUF = data;
while (!TI);
TI = 0;
}
void UART_ISR(void) interrupt 4 {
if (RI) {
unsigned char received = SBUF;
P2 = ~received; // 受信値のビット反転出力
UART_Transmit(received); // エコーバック
RI = 0;
}
}
void main(void) {
UART_Init();
while (1);
}