0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

e2studio RL78-G23をつかっていく

0
Last updated at Posted at 2026-05-22

概要

前回のつづき、とりあえずいろんな機能をRL78-G23で試していく
(様々違いがあるだろうが、他のRenesasマイコンでも同じように使えるだろう。)
↓セットアップ等前回

['26/05/29]winドライバーポリシー変更への対処

https://www.renesas.com/ja/software-tool/e2-emulator-lite-rte0t0002lkce00000r?srsltid=AfmBOoqLq0J9cUDJtr_VBk4JeDxCwkVIwCmpFQWlpe6vCXTPqlIdQ5n6

2026/05/29付けでwinのドライバーアップデートによってE2,E2 lite emuが使えなくなる問題発生。
お知らせ通り、配布されたドライバーを手動で当てて修正できる。

書き込み・デバッグ

RFPを使う

Renesas Flash Programmerを使うと、マイコンにプログラムを書きこんで単体動作させられる。

image.png
ツールやボードの設定を済ませたら接続。
.hex,.mot,.srecなどがプログラムファイルらしい。
{projectname}\HardwareDebug内にあるのでそれでよさそう。
書き込みが完了の後、emulatorとマイコンの配線を切断するとマイコンが動く。書き込み用のピンTOOL0がHIGHであることが動作の条件らしい。

e2studio側でやる

・デバッグなら上の虫アイコンを押せばデバッガが起動する。コードの途中で動作を止めたり、変数を観察できたりする。
・書き込み/実行をe2studioでやる方法。
(e2studioでやると言っていいのか怪しいが)外部実行からRFPを利用して書き込む。
実行>外部ツール構成を選択。以下のように設定。
image.png
ロケーション:C:\Program Files (x86)\Renesas Electronics\Programming Tools\Renesas Flash Programmer V3.22\rfp-cli.exe

作業ディレクトリー:${workspace_loc}/${project_name}

引数:-d RL78 -t e2l -run -a "${project_loc}/HardwareDebug/${project_name}.srec"

実行すると、ビルドされた.srecが書き込まれ、またTOOL0がHIGHに上がり、マイコンが自走する。

マイコン基本機能を使うためのコンフィグ類

共通

基本的にscfgで使いたい機能の設定、ピン割り当てなどを行い、コード生成された関数たちをメインコードや各ユーザー向けファイルで使っていく。
生成されたコードファイルはsmc_genフォルダ内、各モジュール名のフォルダの中にある。APIの使い方を確認できるほか、xxxxxx_user.cには直接書いたりする。

GPIO

scfgのコンポーネント > I/OポートからConfig_PORTを作成。
使いたいピンが属するPORTのチェックボックスを入れる(ピン名:PxyのときPORTxに属する。xは2桁もある。)。
image.png
image.png

端子>端子番号から使うピンにシンボリック名をつける。
image.png
あとはメインコード内からR_Config_PORT_Create();の後、PIN_WRITE(YOURoutpin) = PIN_READ(YOURinpin);などして使える。
シンボリック名を付けなかったり、↑みたいなマクロを使わず直接レジスタを叩いたりできるだろうが、こちらの方が便利で整理だろう。

softwareDelay

scfgのコンポーネント > その他からr_bspを作成。
API functions disable(R_BSP_SoftwareDelay)をEnableへ設定。
R_BSP_SoftwareDelay(10, BSP_DELAY_MICROSECS);でdelayがつかえる。

Lチカサンプルコード↓

DAC (analog出力)

scfgのコンポーネント > D/Aコンバータから使いたいDACをつくる。ピンANO0,ANO1に対応(2ピンしかない?)。
R_Config_DAC0_Create();R_Config_DAC0_Start();の後、R_Config_DAC0_Set_ConversionValue(val);で使える。
分解能は8bitで固定?

タイマー割り込み

scfgのコンポーネント > タイマ・アレイ・ユニットからインターバル・タイマを選択。動作・リソースを目的に設定してTAUを作成。
TAUコンポーネントの設定からインターバル時間を設定できる。
Config_TAU0_0_user.c内、void r_Config_TAU0_0_interrupt()内に処理内容を書く。
DAC同様、R_Config_TAU0_0_Start();で開始。
割り込みでDACなど外の関数を使いたいとき、_user.cからもincludeしないと使えない。

シリアルプリント

scfgのコンポーネント>シリアル・アレイユニットからUARTを追加。

image.png

動作クロックをfSELクロック選択fIHPにする。(外部クロック等特別なことをしたいのでなければこれで。)
転送レートを適切な値にする。
R_Config_UART1_Create();R_Config_UART1_Start();の後、R_Config_UART1_Send((uint8_t *)&txt, txtlen)で送れる。

以下、シリアルプリントのサンプルを書く。
smc_gen>Config_UART1内のConfig_UART1_user.cに送信完了用のフラグ変数をつくる。

Config_UART1_User.c
/* Start user code for global. Do not edit comment generated here */
extern volatile uint8_t g_uart1_tx_end;
/* End user code. Do not edit comment generated here */
...
static void r_Config_UART1_callback_sendend(void)
{
    /* Start user code for r_Config_UART1_callback_sendend. Do not edit comment generated here */
	g_uart1_tx_end = 1;
    /* End user code. Do not edit comment generated here */
}

main.cにSerialPrintfを実装する。送信が終わっていれば送信、未完ならスキップ。ノンブロッキング優先で。

main.c
#include <stdio.h>
#include <stdarg.h>
char log_buf[64];
volatile uint8_t g_uart1_tx_end = 1;
void SerialPrintf(const char *format, ...)
{
    // UART送信器が空いている(=1)ときだけ処理する(ビジーなら即座にスルー)
    if (g_uart1_tx_end == 1)
    {
        va_list args;
        va_start(args, format);

        // vsnprintf を使うと、可変長引数(...)をそのままバッファに展開できる
        // sizeof(log_buf) を指定することで、配列のサイズを超えてメモリを壊す心配もありません
        int len = vsnprintf(log_buf, sizeof(log_buf), format, args);

        va_end(args);

        // 文字列の組み立てに成功していれば送信
        if (len > 0)
        {
            g_uart1_tx_end = 0;                           // 送信開始(ビジー状態にする)
            R_Config_UART1_Send((uint8_t *)log_buf, len); // 割り込みに丸投げして即離脱!
        }
    }
}


int main(void)
{
    EI();
    R_Config_UART1_Create();
    R_Config_UART1_Start();

    g_uart1_tx_end = 1;
    while(1)
    {	
	SerialPrintf("%d %d\r\n", 0, 1);
    }
    return 0;
}

...自分が使っているライター(E2 lite)にはコムポート機能が無いらしい。というか、RL78-G23はTOOL0ピンという半二重なピンを用いて書き込みを行い、普通のシリアルとは少し違う?らしい?
arduino種ばかり触ってきたので、書き込み器があればシリアルできると思い込んでいたが。
適当なシリアル-USB変換器を挟んでデバッグすることにした。

SPI(CSI)

scfgのコンポーネント>シリアル・アレイユニットからSPI(CSI)を追加。
動作、リソースを目的に合わせて設定。今回は送受信、使用するのは01ポートとする。

image.png

SPIの設定。

image.png

端子タブを開くと、(今回はSAU1に)設定した通りの端子割り当てがされていることを確認できる。備考欄に「この端子を初期化するコンポーネントが割り振られていません」と書かれていないことをチェック。コンソールにscfgによる端子割り当てのログが出ていたりするので、それも参考うに。

CSpinについては普通にGPIOで設定する。

以下、SPIでMCP3204と送受信するコードのサンプル。送信内容、受信分析を変えればあらかた他のSPIモジュールにも使えるだろう。

smc_gen>Config_CSI00内のConfig_CSI00_user.cに送信完了用のフラグ変数をつくる。codegeneraterのコメント指示がある場所に以下のように書き加える。

Config_CSI00_user.c
...

/* Start user code for global. Do not edit comment generated here */
volatile uint8_t g_csi_r_end = 0;
/* End user code. Do not edit comment generated here */

...

static void r_Config_CSI00_callback_receiveend(void)
{
    /* Start user code for r_Config_CSI00_callback_receiveend. Do not edit comment generated here */
	g_csi_r_end = 1;
    /* End user code. Do not edit comment generated here */
}

main.cに送受信関数をつくる。

main.c
extern volatile uint8_t g_csi_r_end;//Config_CSI00_user.cで定義した送信完了フラグを外部参照
uint16_t MCP3204_Read(int ch) {
    uint8_t tx_data[3];
    uint8_t rx_data[3];
    uint16_t adc_result = 0;

    // 1. 送信データの準備 (引数 ch に応じてビットを生成)
    tx_data[0] = 0x06; // スタートビット(1) + SGL/DIFF(1) + D2(0)

    // 💡 ch (0〜3) の下位2ビットを取り出して、最上位(ビット7, 6)までシフトする
    tx_data[1] = (uint8_t)((ch & 0x03) << 6);

    tx_data[2] = 0x00; // ダミーデータ

    // 2. チップセレクト(CS)ピンをLOWにする (通信開始)
    g_csi_r_end = 0;
    PIN_WRITE(CSpin) = 0;

    // 3. 3バイトの送受信を実行
    R_Config_CSI00_Send_Receive(tx_data, 3, rx_data);

    // 通信完了を待つ
    while (g_csi_r_end == 0)
    {
        // 転送完了待ち(一瞬で抜けます)
    }

    // 4. CSピンをHIGHに戻す (通信終了)
    PIN_WRITE(CSpin) = 1;

    // 5. 受信データから12ビット分を抽出する
    adc_result = ((uint16_t)(rx_data[1] & 0x0F) << 8) | rx_data[2];

    return adc_result;
}

↑見ての通りブロッキングな処理になっているので注意。

main.c

int main(void)
{
    EI();
    R_Config_PORT_Create();
    R_Config_CSI00_Create();
    R_Config_CSI00_Start();

    volatile uint16_t res0=0;
    volatile uint16_t res1=0;    
    while(1)
    {
	res0=MCP3204_Read(0);
	res1=MCP3204_Read(1);
    }
    return 0;
}

あとはmain内で呼び出してやって完成。

ほかやること

・デバッグ機能深堀り
・単体動作どうするの?

ガチ余談(どうでもいい)

ずっと気になってるんだけど、コード生成で生まれるファイルのコメントアウトにRenesasのコピーライトが記載されているが、e2studioのtypo検知がRinsesに訂正しようとしてくる...。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?