RXマイコンのソフト開発(5)ADCでバッテリーの電圧測定

RXマイコン(RX631)のソフト開発の5回目です。今回は、ADCでバッテリーの電圧を測定して、TeraTermで値を確認したいと思います。

図1:AD変換の模式図
図1:AD変換の模式図

今回の記事は、以下の資料を主に参考にしました。

環境

  • パソコン: Windows10 64 bit
    • 統合開発環境: e2studio 2021-01をインストール
    • コンパイラ: Renesas CCRX v3.03.00をインストール
    • 書き込みソフト: Renesas Flash Programmer V3.08.01(無償版) をインストール
  • ターゲットデバイス: R5F5631PDDFL(RX631 48ピン)

バッテリーチェックの回路

作成したバッテリーチェックの回路図は図2です。

図2:バッテリーチェックの回路
図2:バッテリーチェックの回路

SEN_BAT のポートは PE1/AN009 です。Lipoバッテリーの電圧を抵抗によって半分に分圧しています。その半分になった電圧をADCで測定します。

プログラムフロー

プログラムの処理の流れは図3です。

図3:プログラムのフローチャート
図3:プログラムのフローチャート

クロックの初期化とCMT0とSCI1の初期化を行って、ADCを初期化します。その後、メインルーチンに入り、スイッチの押し込みを検知したら バッテリーの電圧値 を UART 送信します。

プログラム

重要なプログラム部分だけ示します。sci.csci.h を除いた全てのソースコードGitHubの「5_adc」フォルダの中にソースコードがありますので、詳細を知りたい場合はご覧ください。

メイン関数

main.c:メイン関数のソースコード

#include "interface.h"
#include "sci.h"
#include "init_rx631.h"
#include "iodefine.h"

void main(void){
    unsigned short voltage;

    init_rx631();       // Overall Initialization

    while(1){
        if(g_sw_chg){   // Enter when SW is pressed
            g_sw_chg = 0;
            S12AD.ADCSR.BIT.ADST = 1;         // ADC start
            while(S12AD.ADCSR.BIT.ADST==1);   // wait for ADC completion
            voltage = S12AD.ADDR9*330*2/4095; // Convert to voltage
            sci_printf("voltage = %u.%u\n\r",voltage/100,voltage%100);
        }
    }
}

メイン関数では、RX631の初期化を行い、割り込み関数によってスイッチの押し込みフラグが立ったら、フラグを下げて、AD変換を行います。AD変換を開始したら、AD変換が完了するまで待ち、AD変換が完了したら、AD変換値から電圧値に変換します。その電圧値をsci_printfでUART送信します。

ADCの初期化

初期化関数のソースコードが以下です。ADC に関してはユーザーズマニュアルの p.1769「42. 12 ビット A/D コンバータ(S12ADa)」に記述があります。

init_rx631.c:初期化関数のソースコード

#include "init_rx631.h"
#include "iodefine.h"

/*** Function Declaration ***/
static void init_clock(void);
static void init_cmt0(void);
static void init_sci1(void);
static void init_adc(void);

/*---- RX631 Initialization ----*/
void init_rx631(void){
    SYSTEM.PRCR.WORD = 0xA503;  // Unprotect

    // MainCLK, SUBCLK and RTC Initialization
    init_clock();

    // CMT0 Initialization
    init_cmt0();

    // SCI1 Initialization
    init_sci1();

    // ADC Initialization
    init_adc();

    SYSTEM.PRCR.WORD = 0xA500;  // Reprotect
}

~略~

static void init_adc(void){

    MSTP(S12AD) = 0;               // S12AD Module Stop Release

    MPC.PWPR.BIT.B0WI     = 0;     // PFSWE bit write enable
    MPC.PWPR.BIT.PFSWE    = 1;     // PmnPFS Register write enable
    MPC.PE1PFS.BIT.ASEL   = 1;     // Used as an analog port
    MPC.PWPR.BYTE         = 0x80;  // Reprotect
    //PORTE.PMR.BIT.B1    = 1;     // set to Peripheral (2021/9/15 comment out)

    S12AD.ADCSR.BIT.CKS   = 3;     // PCLK/1
    S12AD.ADANS0.WORD     = 0x200; // conversion target:AN009
    S12AD.ADCSR.BIT.ADCS  = 0;     // single scan mode
}

ADCの初期化では、UARTの初期化と同様にモジュールストップ状態の解除と端子機能の変更を行います。端子機能の変更でUARTのときと少し違う点はアナログ端子として使用するので、PmnPFSレジスタのPSELではなく、ASELを変更している点です。

その後、以下のADCの設定を行います。

  • ADCSRレジスタのCKSビットを3にして、分周比を1とする。
  • ADANS0レジスタを0x200にして、AN009を変換対象とする。
  • ADCSRレジスタのADCSビットを0にして、シングルスキャンモードにする。

連続スキャンモードというのもありますが、連続でAD変換する必要はないので、シングルスキャンモードにします。

また、ソフトウェアトリガでAD変換を開始するので、ADCSRレジスタのEXTRGビットやTRGEビットは”0”、”1”どちらでも構いません。

補足:はじめ、 ADCSRレジスタのCKSビットを0(分周比:8)にしていたのですが、そうするとAD変換結果が必ず4095になってしまいました。CKSビットを3にすることでこの現象が治りました。原因は不明ですが、基板のほうに問題があるのかもしれません。

追記(2021/9/15):マニュアルp.764「22.4.3 アナログ機能を使う場合の注意事項」に「アナログ機能を使用するときは、ポートモードレジスタ(PMR)の当該ビットを “0”、ポート方向レジスタ(PDR)の当該ビットを “0” にし、当該端子を汎用入力ポートにしてから、Pmn 端子機能制御レジスタの端子機能選択ビット(PmnPFS.ASEL[1:0])を “1” にしてください。」とありますので、PMRレジスタの設定はコメントアウトしました

プログラムの実行

スイッチを押すたびに、図4のようにバッテリーの電圧値が表示されるようになりました。

図4:プログラムの実行結果
図4:プログラムの実行結果

おわりに

今回でAD変換ができました。次の記事では、赤外線LEDと赤外線センサーを使ってみたいと思います。

参考文献

お問い合わせフォーム プライバシーポリシー

© 2021 Setoti All rights reserved.