前回の記事では、PIC16F1938を使ってPWMを5ch制御し、
Timer・CCP・ADCを組み合わせた制御を実装しました。
今回はその次のステップとして、
「UART通信(USART)」に進みます。
・外部機器と通信したい
・ログをPCに出したい
・最終的にはDMXにつなげたい
こういった用途では、UARTは避けて通れません。
この記事では、
・UARTとは何か
・USARTの初期化方法
・実際に文字を送信するところまで
を、実機ベースで解説します。
※今回は送信のみを扱っています。受信については次回解説します。
UARTとは何か?
UART(Universal Asynchronous Receiver Transmitter)は、
マイコン同士やPCと通信するためのシリアル通信方式です。
特徴は以下の通りです。
・非同期通信(クロック線なし)
・TX/RXの2本で通信
・決めたボーレートで通信する
例えば9600bpsの場合、
1秒間に9600ビット送れる
=1ビット 約104μs
という時間でデータが流れます。
USARTとは?
PICではUART機能は「USART」と呼ばれています。
USART = Universal Synchronous Asynchronous Receiver Transmitter
つまり、
・非同期通信(UART)
・同期通信
両方に対応していますが、
今回は「非同期(UART)」のみ使います。
UARTのデータ構造
UARTでは1文字を以下の形で送ります。
スタートビット:1bit(必ず0)
データ:8bit
ストップビット:1bit(必ず1)
つまり合計10ビット(設定によっては11ビット)
例えば’A’(0x41)を送ると、
0(スタート) + 01000001 + 1(ストップ)
という形になります。
UARTのデータ構造
UARTでは1文字を以下の形で送ります。
スタートビット:1bit(必ず0)
データ:8bit
ストップビット:1bit(必ず1)
つまり合計10ビット(設定によっては11ビット)
例えば’A’(0x41)を送ると、
0(スタート) + 01000001 + 1(ストップ)
という形になります。
USART初期化
今回の設定は以下です。
・内部クロック:8MHz
・ボーレート:9600bps
・非同期モード
・送信有効
・受信有効
c
void USART_Init(void) {
OSCCON = 0b01110010; // 8MHz
TRISCbits.TRISC6 = 1; // TX
TRISCbits.TRISC7 = 1; // RX
// ボーレート設定
SPBRG = 51; // 9600bps(8MHz時)
TXSTAbits.BRGH = 1; // 高速モード
BAUDCONbits.BRG16 = 0;
RCSTAbits.SPEN = 1; // シリアル有効
TXSTAbits.TXEN = 1; // 送信有効
RCSTAbits.CREN = 1; // 受信有効
}
文字を送信する
UARTは1バイトずつ送信します。
あくまでも一文字ずつで、単語や文章を一気におくることはしてません。
c
void USART_Write(char data) {
while(!PIR1bits.TXIF);
TXREG = data;
}
動作確認
回路図は以下の通りです。

PICとUSBシリアル変換(CH340など)は以下のように接続します。
PIC TX → USBシリアル RX
PIC RX → USBシリアル TX
GND → GND
例えば以下のコードで、
c
USART_Write('A');
‘A’が送信されます。
USB-シリアル変換(CH340など)を使い、
PCのターミナルソフトで確認できます。
今回はtera termを使いました。
今回は、次のコードを使いました。
c
while (1) {
LATAbits.LATA1 = 1;
unsigned char Strings[] = "Hello!!\r\n";
unsigned int len = strlen(Strings);
for (unsigned char i = 0; i < len; i++) {
while (!PIR1bits.TXIF);
TXREG = Strings[i];
}
__delay_ms(500);
}
メインの中で、上のコードを入力し、
0.5秒間隔で、
”Hello”が表示されます。
無事に通信できていることが確認できました。
画面録画で録画のクオリティのせいなのか、
全く0.5秒間隔には見えませんが、
生で見るとちゃんと0.5秒間隔になってました。
このように一定周期でデータを送信することで、
デバッグ出力や状態監視にも応用できます。
なぜSPBRGが51なのか?
ボーレートは以下の式で決まります。
ボーレート = Fosc / (16 × (SPBRG + 1))
今回、
Fosc = 8MHz
ボーレート = 9600
なので、
SPBRG ≒ 51
になります。
PWMとの違い
PWMは「波形を作る制御」でしたが、
UARTは「情報を送る手段」です。
PWM:
→ LEDの明るさ制御
UART:
→ データ通信
つまり、
PWM → 出力制御
UART → 情報伝達
という役割になります。
よくあるミス
UARTが動かない原因として多いのは以下です。
・ボーレート設定ミス(SPBRG)
・TX/RXの配線ミス
・GND未接続
・ターミナルの設定違い
特にGNDが共通になっていないと通信できません。
今回はこのあたりでのミスは無かったのですが、
なかなか初歩的なところでつまづいてしまっていました。
書き込みは成功しているにも関わらず、
全く動かない時間が長くてかなり大変でした。
ハマったポイントはコンフィギュレーションの設定です。
c
#pragma config LVP = OFF
ただ1行、
これが無かっただけで、
ちゃんと動いてくれなくて
1~2時間ぐらい
いろいろ思考錯誤しました。
Lチカすら動かなかった…
まとめ
・UARTはシリアル通信の基本
・PICではUSARTとして実装されている
・初期化すれば簡単に送信できる
PWMで「制御」を学んだ後は、
UARTで「通信」を学ぶことで、
マイコンの世界が一気に広がります。
次回予告
今回は「送信」までを実装しました。
次回は、
・受信処理
・文字列送信
・実用的なデバッグ出力
をやっていきます。
最終的には、
DMX通信にもつながる内容になります。

コメント