トップ画像
Mbed LPC1768でUSB経由のシリアル(UART)通信をする

執筆者: 瀕死

最終更新: 2024/06/25

Mbed LPC1768でUSB経由のシリアル(UART)通信をする

はじめに

はじめまして、瀕死(ひんし)と申します。
現在私は部内のポップンコントローラーを修理しているのですが、その過程でつまずいた点などをしばらくの間は記事にしていこうと思っています。

初めての記事作成で至らぬ点などあるかもしれませんが、よろしくお願いいたします。

目的

Mbed LPC1768においてWindows11とUSB経由でシリアル通信する方法について解説する。

MbedがWindows10以降においてシリアルポートとして認識されない問題は、公式サイトやフォーラム等に様々な情報が存在する。

情報源

| 内容

公式サイト

| ドライバはWindows7のみ必要である

公式フォーラム1

| Windows7以外でもドライバが必要である

| これが当たり

公式フォーラム2

| ST-LINKのドライバが必要である

フォーラム

| ファームウェアアップデートが必要である

他にも、Windows11のとあるサービスが原因であるという主張があったり、Windows11のレガシーデバイスとしてドライバを割り当てたりした。

そのため、かなりの時間と労力がかかった。本稿の読者がこのような苦労をしないことを願って執筆した。

目次

  • Mbed LPC1768でUSB経由のシリアル(UART)通信をする
    • はじめに
    • 目的
    • 目次
    • TL;DR
    • ドライバのインストール
    • OSによる差異
    • UARTとは
    • 実践
    • ロジックアナライザで解析してみる
    • おわりに
    • 参考文献

TL;DR

  1. 公式サイトにアクセスする。
  2. 手順1のArm Mbed Windows serial port driverを右クリックして、名前を付けてリンク先を保存
  3. あとは手順通りにすれば準備完了。
  4. シリアル通信のクラスを使わずprintfを用いる。
  5. Mbed StudioやTera Termで等で確認する。

ドライバのインストール

公式サイトのドライバをインストールすると私の環境ではうまくいった。

  1. 公式サイトにアクセスする。
  2. Windows 7 only無視してArm Mbed Windows serial port driverを右クリックして、名前を付けてリンク先を保存する。Chromeにダウンロードをブロックされるからである。
  3. MbedをPCにUSBで接続し、Mbedを開いているエクスプローラーは閉じる。
  4. ダウンロードしたmbedWinSerial_16466.exeを実行する。

以上の操作でシリアル通信できるようになっているはずである。

適切に認識された場合、デバイスマネージャーのポート(COMとLPT)の中にmbed serial portができる。

デバイスマネージャーのポート(COMとLPT)の中のmbed serial port
デバイスマネージャーのポート(COMとLPT)の中のmbed serial port

OSによる差異

MbedのOSによってシリアル通信のためのクラスが異なる。

  • OS2
    • Serial
  • OS5
    • Serial
    • RawSerial
  • OS6
    • BufferedSerial
    • UnbufferedSerial

これからMbedでの開発を行う場合OS2は標準では使えないため、OS5かOS6を採用する必要がある。今回はOS6のBufferedSerialクラスを用いた。UnbufferedSerialは一般的な用途向きではないので注意しよう。

実は、Mbedはシリアル通信のクラスを使っていない場合はprintfがUSBシリアルにリダイレクトされるので、これを使うと機能は少ないが簡単に実装できる。

UARTとは

UART(Universal Asynchronous Receiver/Transmitter, ユーアート)とは非同期にシリアル通信する方法の1つである。シリアル通信でほかに有名な方式としては、I2C(アイ・スクエアド・シー)やSPIなどがあるがどちらも同期式シリアル通信の方式である。

  • UART通信は非同期の通信のため、クロック用の信号線はない。
    • ケーブルが2本で済む
    • 比較的低速
  • マスタ/スレーブといった役割がない。
    • 通信の構成が簡単

といった特徴がある。

ケーブルが2本で済むことは重要である。USB2.0TypeAにおけるピンは4つしかなく、2つはVBUS(+5V)とGNDで使用済みであるため、残りの2つで通信する必要があるからである。

UART接続図 TX-RXの2組
UART接続図

シリアル通信の方式の比較として、以下の表を作成した。

通信方式

| 同期/非同期

| 全二重通信*-半二重通信

| 構成

| 相対的な通信速度

SPI

| 同期

| 全二重通信

| 1マスタ-多スレーブ

| 速い

I2C

| 同期

| 半二重通信

| 多マスタ-多スレーブ

| 中間

UART

| 非同期

| 全二重通信

| 1-1(方式上は対等)

| 遅い

(*電子回路部分の構成等で半二重通信にもできる)

同期であればクロック用の信号線が必要であり、全二重通信であればデータ線は2本必要である。

通信の波形は以下のようになる。

UART波形
UART波形注釈付き

上の表の何ビット目か

| 名前

| 説明

1

| スタートビット

| 1bit の長さのLOWの信号を送信する

2-9

| データビット

| 指定された長さのbit列を送信する

無し

| パリティビット

| 誤り訂正のためのbitで設定によってはないこともある

10-11

| ストップビット

| 1, 1.5, 2bitの指定されたいずれかの長さのHIGH信号を送信する

I2CやSPIと違い同期式シリアル通信ではないので、データ線にも通信開始等の制御用データが入っていることがわかる。

実践

#include "mbed.h"

// バッファサイズの設定
const size_t BUF_SIZE = 32;

// LEDのピン設定
static DigitalOut led(LED1);

// UARTのピンを設定 USBの場合は以下の定数を使う
static BufferedSerial serial_port(USBTX, USBRX);

int main(void)
{
    serial_port.set_baud(9600);   // 通信速度の設定

    // 前の引数から、1回の通信のサイズ 単位:bit, パリティの有無, ストップビットの長さ
    serial_port.set_format(8, BufferedSerial::None, 1);

    // 入力用のバッファを宣言+初期化
    char buf[BUF_SIZE] = {0};

    // int write(char[] data, size_t data_size);で送信
    serial_port.write("start\n", sizeof("start\n"));

    while (true) {
        // int read(char[] rx_buf, size_t buf_size);で受信
        if (uint32_t read_size = serial_port.read(buf, sizeof(buf))) {
            led = !led; // ledの状態を変更

            serial_port.write("led: ", sizeof("led"));
            if (led) serial_port.write("ON\n", sizeof("ON\n"));
            else serial_port.write("OFF\n", sizeof("OFF\n"));
        }
    }
}

以上のコードをビルドして、LPC1768上で実行する。シリアルモニターでキーを打つたびに、LEDの発光状態が切り替わり、シリアルモニターにLEDの状態が表示される。

Mbed Studio シリアルモニターの様子
Mbed Studio シリアルモニター
LEDの光ったLPC1768
LEDの光ったLPC1768

ロジックアナライザで解析してみる

"A"をUARTで送信したときの波形を観察する。

#include "mbed.h"

// UARTのピンを設定
static BufferedSerial serial_port(p9, p10);

int main(void)
{
    serial_port.set_baud(9600); 

    serial_port.set_format(8, BufferedSerial::None, 2);

    while (true) {
        serial_port.write("A", sizeof("A"));
    }
}

目視で確認しやすいようにストップビットの長さを2bitに設定した。

Aだけを送信しているように見えて、Aと文字列終端として\0を送信していることに注意する。

波形は以下のとおりである。

UART波形
UART波形

0x00はASCIIコードにおいて\0であるから、正しく送信できていることがわかる。

おわりに

読んでいただきありがとうございました。

次回はESP32 WROOM-32開発ボードをSPI Slaveとして用いる方法になる予定です。

参考文献

取得に失敗しました

2024年度 入部