UARTの出力信号をPCのターミナルソフトで確認する方法

Tera TermとかSerial Communicator とかのターミナルソフトでUARTの信号を確認する方法を調べてみました。

普通、ArduinoでもNXPマイコンでも、デバッグプローブはUART信号を内蔵していて、USBケーブルをPCにつなぐだけで、とくに意識しないでも信号をPC上で確認できます。

FRDM-K64FでUARTは、デバッグ用以外にも複数のIO(UART0-5の合計6個)があったり、AruduinoでもSoftware Serialという機能をつかえば、任意のピンをUARTの入出力として、割り当てることができるなど、デバッグ目的以外にもUART信号を利用したいと思うことは、ままあります。

が、実際にこれらの信号をPCで取り込もうとすると、電圧のレベルの違いやロジック信号の違いを考慮しないといけません。

なぜかというと、PC側は信号をRS232Cレベル(-15V~+15V)で送受信し、マイコン側はボードによって異なるが、Arduino UNO ではTTLレベル(0~5V)、FRDM-K64FはLVTTLレベル(0-3.3V)で送受信するため。論理値自体もRS232はUARTと定義が逆になってマス。

詳細は色々なサイトで説明されているので、省略。特にここがわかりやすかったです。p10-12だけ読めば事足ります。

https://www.cqpub.co.jp/toragi/TRBN/contents/2008/tr0801/0801furoku.pdf

つまり、デバッグプローブのUART信号はボード上で、その電圧変換をおこなってくれているので、特に何もする必要がなかったという訳ですが、そうではない場合は各自なんとかしなきゃいけないということです。

ちまたには、マイコンの電圧をRS232レベルに変換してくれるICがあるので、これらを使用するのが一番簡単な方法です。

これは、3V・3.3V・5V系-RS232レベル変換基板(秋月電子)

http://akizukidenshi.com/catalog/g/gK-06464/

ADM3202というレベル変換ICを利用していて、3V、3.3V、5V系からRS232レベルに変換してくれます。基板上のハンダジャンパ(下図でいうところの半円状の二つのランド)をショートすれば、3.5-12Vの外部電源でも動作させることができて、この時の出力電圧は3.3Vになります(3.3Vのレギュレータを内蔵しているため)

一個500円程度でした。

左のようにRS232のコネクタにピッタリ基盤が挿入できるような基板サイズになっている

上段の5ピンと下段の4ピンの間にボードを差し込むと、ランドとピンの位置ピッタリ揃います。メスのコネクタなら、ピン配も考えずにそのままハンダできます。

MCU側       RS232側
1- GND      2- TXD
2- TX-IN    3- RXD
3- RX-OUT   5- GND
4- VCC      1,4,6-9 NC
5- 電源      

コネクタと基板をハンダ付けします。あとは、マイコン側に線を出しておきます。今回は外部電源は使わないので、一番右側の#5には線をつなげてません。

Arduino UNOで動作検証

とりあえず、Arduino UNOにつないで動作検証をしてみました。

UNOはUARTのRX,TX用のポートが#0と#1のpinに用意されていますが、これを利用するとSketchのシリアルモニタ機能が利用できなくなったり、モデルのビルドのたびに線を外さないとエラーが発生するなど面倒なことが多いので、今回はソフトウェアシリアルで仮想的なUARTポートを用意してテストしました。

ソースコードは簡単だが、一応コピペしときます。

//ソフトウェアシリアル通信用のAPIを読み込む
#include <SoftwareSerial.h> 
// RX, TX の定義
SoftwareSerial mySerial(2, 3);
int count = 0;

void setup(){
  Serial.begin(9600);  // UART(Sketchモニタ用)
  mySerial.begin(9600); // ソフトウェアシリアル

}

void loop(){
  count++;
//Sketchのシリアルモニタに信号送信
  Serial.print("counter = "); 
  Serial.println(count);
// ソフトウェアシリアルポートから信号送信  
  mySerial.listen();            
  mySerial.print("counter = ");
  mySerial.println(count); 
  
  delay(1000);
}

テスト回路は以下のような感じ。メスのコネクタの先は、RS232とUSBの変換ケーブルが家にあったので、これを利用しています。

Arduino側     Connector側
 #2 RX  ----    #3 RX
 #3 TX  ----    #2 TX
  GND    ----    #1 GND
  Vcc    ----    #4 Vcc

プログラムを開始して、ターミナルソフトと今回作成したデバイスのUSBとを接続して、信号を見た結果は以下のとおり、参考に右側はSketchのシリアルモニタの画面をだしました。これは#0,#1のUARTポートからデバッガを介して、受信したものです。

カウント信号がちゃんと表示されている!

Arduinoのマイコン電圧は5Vなので、0-5VのUART信号は無事変換できました。

3.3V系のマイコンはどうだろうか?FRDM-K64Fは3.3V系なので、同じようにテストしてみます。

FRDM-K64Fで動作検証

FRDM-K64FでのUARTの詳細な使用方法は別記事でまとめるとして、今回は、UART3を利用する。UART3は下図のPTC16が受信側のRX、PTC17が送信側のTXにアサインされてます。

回路図から遡っていくと、CPU #90,#91ピンにつながっている

ピンアサインは別途、コンフィグツールか直接<pin_mux.c>を編集します。これは別記事で説明するとして、メインのソースコード側は以下のとおりです。

/*
	UART TEST PROGRAM
 */
#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_uart.h" //これUARTのドライバ
#include "pin_mux.h"
#include "clock_config.h"

/*******************************
Definitions
*******************************/
/*********** Define UART *******/
//Clock source
//クロックの指定、UART3はバスクロックで駆動される
#define TEST_UART_CLKSRC UART3_CLK_SRC 

//Frequency macro
//マクロ、クロック周波数をAPIで算出
#define TEST_UART_CLK_FREQ CLOCK_GetFreq(UART3_CLK_SRC) 

/*********** UART *****************/
//module instance
// UART3をTEST_UARTとして定義している
#define TEST_UART UART3
/*******************************
Variables
*******************************/
//ターミナルソフトで表示する用の文字列
uint8_t count_string[]   = "\r\nCounter = "; 
//上に同じ、カウンタを数値文字列にしたもの
uint8_t num_string[3];                       
volatile uint32_t g_systickCounter;
uint8_t counter;
/*******************************
Code
*******************************/
void SysTick_Handler(void)
{
    if (g_systickCounter != 0U)
    {
        g_systickCounter--;
    }
}
void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while (g_systickCounter != 0U)
    }
}

/*!
 * @brief Main function
 */
int main(void)
{
    // Board definition
    BOARD_InitPins();
    BOARD_BootClockRUN();

	// UART parameters definition
    uart_config_t config;

    // UART Configuration loads default value
    UART_GetDefaultConfig(&config);

    // UART DEBUG PROBE Baudrate
    config.baudRate_Bps = 9600;
    config.enableTx     = true;
    config.enableRx     = true;

    // UART initialization
    UART_Init(TEST_UART, &config, TEST_UART_CLK_FREQ);

    /* Set systick reload value to generate 1ms interrupt */
    if (SysTick_Config(SystemCoreClock / 1000U))
    {
        while (1)
        {
        }
    }
    while (1)
    {
    	counter++;
        /* Delay 1000 ms */
        SysTick_DelayTicks(1000U);
//itoa関数、数値counterを渡し、文字列num_stringを受け取る
        itoa(counter,num_string,10U); 
        PRINTF(num_string);
//UARTのWrite文
        UART_WriteBlocking
         (TEST_UART,count_string,sizeof(count_string)-1); 
        UART_WriteBlocking
         (TEST_UART,num_string,sizeof(num_string)-1);
    }
    }

テスト回路は以下のような感じになります。

 K64F側           Connector側
 J3-4  3.3V  ---- #4 Vcc
 J3-14 GND   ---- #1 GND
 J1-16 RX    ---- #3 RX
 J1-17 TX    ---- #2 TX

結果は、以下のとおり。3.3Vでも問題なく通信できました。

まとめ

UARTでPCと通信するにはマイコンの電圧レベルをRS232のレベルに合わせることが必要ですが、レベル変換ICを搭載したモジュールを利用すれば、3.3Vでも5Vでも簡単にPCへつなぐことが可能でした。

1セットもっておくと、プログラムのデバッグや信号のチェックに重宝するかもしれません。

それでわ、Happy レベル変換🙌

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です