RL78/G13で2.5μsec毎に100回連続A/D変換させてDMAでデータを取り込むコードをコード生成させてシミュレータと実デバイスで試してみた

がじぇるねの方へGR-CITRUS(RX631)で簡易オシロスコープを作ろうとして投稿中ですが、RL78/G13ではどうだろうと思いデバイスのマニュアルを見てみるとVDDが3.6V以上であれば時間軸的に切りの良い2.5μsec毎での連続A/D変換が出来るようでした。都合の良いことに、CS+のコード生成機能のGUIを触ってみるとタイマとDMAを使って連続A/D変換結果を取り込むコードも生成出来るようでした。そこで、ひとまず下調べとしてCS+で以下のようなことをして実際に確認してみました。

(1)スマートブラウザウィンドウでアプリケーションノートを探す
(2)コード生成機能を利用してプログラムを作る
(3)シミュレータで試す
(4)実デバイスで試す

rl78g13_timer_adc_dmac_study_20170321.zip

RL78/G13デバイスのマニュアルより抜粋


シミュレータGUIとCS+デバッガの画面


[画面コピー色々]

(1)スマートブラウザウィンドウでアプリケーションノートを探す

見つけた以下のアプリケーションノートにはざっと目を通しておきました。

R01AN2576JJ0200 タイマ・アレイ・ユニット
R01AN2581JJ0200 A/Dコンバータ
R01AN2803JJ0100 DMAコントローラ



(2)コード生成機能を利用してプログラムを作る

上のアプリケーションノートを見ていて気付いたのですが、DMAコントローラに関しては生成されたコードの使い方にちょっとしたコツがあるようです。







r_cg_dmac.c

コード生成によるDMAコントローラ初期化関数(GUI上でシンボル入力不可)

/***********************************************************************************************************************
* Function Name: R_DMAC0_Create
* Description  : This function initializes the DMA0 transfer.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void R_DMAC0_Create(void)
{
    DRC0 = _80_DMA_OPERATION_ENABLE;
    NOP();
    NOP();
    DMAMK0 = 1U; /* disable INTDMA0 interrupt */
    DMAIF0 = 0U; /* clear INTDMA0 interrupt flag */
    DMC0 = _00_DMA_TRANSFER_DIR_SFR2RAM | _00_DMA_DATA_SIZE_8 | _01_DMA_TRIGGER_AD;
    DSA0 = _1F_DMA0_SFR_ADDRESS;
    DRA0 = _FEDF_DMA0_RAM_ADDRESS; 仮の設定
    DBC0 = _0001_DMA0_BYTE_COUNT; ← 仮の設定
    DEN0 = 0U; /* disable DMA0 operation */
}

コード生成のユーザ記述部に以下の関数を追加して適宜呼び出すことにした

extern volatile uint8_t g_AdResult[1024];
/******************************************************************************
* Function Name: R_DMAC0_UserInit
* Description : This function re-initialize DMA0.
* Arguments    : None
* Return Value : None
******************************************************************************/
void R_DMAC0_UserInit(void)
{
    DEN0    = 1U;                       /* Enable DMA0 operation */
    DRA0   = (uint16_t)&g_AdResult;
    DBC0   = 100;
    DEN0    = 0U;                       /* Disable DMA0 operation */
}

(3)シミュレータで試す

実デバイスとの違いを確認してみると今回の動作確認をするには問題無しでした。

CS+ RL78/G13用シミュレータ リリースノートより抜粋





(4)実デバイスで試す

連続A/D変換を期待通りの時間で出来ているようです。

r_main.c


r_main.c


なお、printf()/scanf()は以下を投稿した時に使用したプロジェクトのものです。

チョコ様のCC-RLのUARTサンプルプログラム「RL78コード生成へのリングバッファ追加」にputchar/getcharを追加してprintf/scanfが出来るようにしてみた

  • NoMaYさま、コード生成のサポート担当の鈴木です。
    素晴らしいです!コード生成でDMAを使うお手本とさせてください。
    こちらで期待したとおりの手順が書いてあるのでびっくりしました。
    R_DMAC0_UserInit() の位置を移動することを検討しています。
    (DEN0 = 1U; DEN0 = 0U; の制御が不要になるように)

    ご要望も承っております。 今後とも宜しくお願います。