連続パルス波形の周期およびデューティ比の測定
cygwin+GCC

Copyright(C) 4Feb2004
coskx

【1】 はじめに

この文書はAKI-H8/3048を用いたクロック波形の周期およびデューティ比の測定について解説している。
使用するのはITUch4のバッファを使用したインプットキャプチャである。ここではITUch4を用いたがITUch3でも同じことが出来る。
(ITUch0,1,2はバッファの機能がないので使えない)

サンプルプログラムのダウンロード

DownLoad

【2】 AKI-H8/3048による連続パルス波形の周期およびHレベル区間長の測定

ある種のセンサはその出力を連続パルス波形(1と0が交互に出力される波形)で出力し,そのデューティ比で測定値を表現している。
デューティ比は「Hレベル区間長」/「パルス周期」であたえられる。
ここではITUch4のインプットキャプチャ機能を利用して,連続パルス波形の「Hレベル区間長」と「パルス周期」を測定している。
測定にはCPUクロックをあるいはその分周クロックを用いて,測定対象の「Hレベル区間長」と「パルス周期」が何クロックにあたるかを計測する。

このプログラムで「Hレベル区間長」と「パルス周期」を測定するには,被測定波形をTIOCA4とTIOCB4に同時に与えなければならない。

ITUch4に対応する割り込みベクトルは「int_imib4」として,ファイル「h8_3048f.x」に記述されている。

ITUch4のインプットキャプチャ機能を利用した連続パルス波形の「Hレベル区間長」と「パルス周期」の測定

/**********************************************************
ITU4でクロック信号のH区間デューティ比を測定する。

ITU4でinputcapture (周期とH区間長さを測定)

設定
ITU4のインプットキャプチャ+バッファを使用
TIOCAとTIOCBに同じ信号を入力
GRAは両エッジでインプットキャプチャ
GRBは立上りでインプットキャプチャ
インプットキャプチャBでカウンタクリア
インプットキャプチャBで割り込み
割り込み時には
 BRAにHigh区間の長さが入る
 GRBに周期が入る
この2つよりデューティ比がわかる

                   Time Chart
TIOCA  ______|~~~~~~~~~~|_____________|~~~~~~~~~~|___
             ^P1        ^Q1           ^P2        ^Q2
TCNT         CLR > > up > > > > > > > CLR > > up >
GRA          |  N at P1 |    N at Q1  |  N at P2 |
BRA          |  N at Q0 |    N at P1  |  N at Q1 |
GRB          |   N at P1              |  N at P2  
              ^interrupt               ^interrupt

**********************************************************/
#include "3048f.h"
#include "h8_3048.h"

/*clockindex   0:φ,1:φ/2,2:φ/4,3:φ/8*/
/*period      0.0625  0.125   0.250     0.5   [μsec]  */

/*
割り込みベクタ IMIB4 41 0xA4-0xA7

入力端子 測定したい波形を,以下の2つの端子に入力する
 4 TIOCA4/TP10/PB2 CN1-18
 5 TIOCB4/TP11/PB3 CN1-19
*/
/*デューティ比測定のための初期化*/
void initMeasDuty(int clockindex)
{
    ITU4.TCR.BIT.TPSC=clockindex; /*0:φ,1:φ/2,2:φ/4,3:φ/8*/
    ITU4.TCR.BIT.CCLR=2; /*GRBのインプットキャプチャでカウンタクリア*/
    ITU4.TIOR.BIT.IOA=7; /*GRAは立上/立下の両エッジでインプットキャプチャ*/
    ITU4.TIOR.BIT.IOB=4; /*GRBは立上のエッジでインプットキャプチャ*/
    ITU.TFCR.BIT.BFA4=1; /*GRA4とBRA4はバッファ動作*/
    ITU4.TSR.BIT.IMFB=0; /*GRBコンペアマッチフラッグクリア*/
    ITU4.TIER.BIT.IMIEB=1; /*IMFBフラグによる割込みを許可*/
    ITU.TSTR.BIT.STR4=1; /*ITU4スタート*/
}

#define readPeriod() (ITU4.GRB)
#define readHigh() (ITU4.BRA)

volatile unsigned short int period=9999;
volatile unsigned short int high=0;

main()
{
    unsigned short int oldperiod=9999;
    unsigned short int oldhigh=0;
    initSCI1();
    SCI1_printf("\n\n\nDuty Ratio Measurement Program\n");
    SCI1_printf("Connect inputline with both CN1-18 and CN1-19.\n");
    SCI1_printf("unit: 0.0005msec\n");
    SCI1_printf("Measurement Range: 0.5msec - 25msec\n");
    initMeasDuty(3); /*clock:φ/8*/
    E_INT();        /*CPU割り込み許可*/
    while(1) {
        if (period!=oldperiod||high!=oldhigh) {
            SCI1_printf("high,period= %6u/%6u\n",high,period);
            oldperiod=period;
            oldhigh=high;
        }
    }
}

#pragma interrupt
void int_imib4() /*インプットキャプチャB割り込みルーチン*/
{
    ITU4.TSR.BIT.IMFB=0; /*GRBコンペアマッチフラッグクリア*/
    period=readPeriod();
    high=readHigh();
}

 

【3】 AKI-H8/3048による連続パルス波形の周期およびHレベル区間長の測定テストプログラム

「【2】」のプログラムの妥当性を検証するため,ITUch3からPWM連続波形を発生し,これの「Hレベル区間長」と「パルス周期」を測定することとした。測定中にシリアル接続されたPCのターミナルソフト(ここではハイパーターミナルを使用してテストした)でキー'D','U'の操作でITUch3のPWM信号のHレベル区間長を変更して,動作確認を行なった。プログラムリストの後半は,実行結果である。
実行結果の測定値では,周期およびHレベル区間長ともに,ITUch3が発生しているそれらと同じ値が得られている。

このプログラムを実行するときには次の3つの端子を結合する必要がある
(1)TIOCA4 測定用入力
(2)TIOCB4 測定用入力
(3)TIOCA3 PWM出力

ITUch4のインプットキャプチャ機能を利用した連続パルス波形の「Hレベル区間長」と「パルス周期」の測定
ITUch3で擬似的なPWMを発生している

/**********************************************************
ITU4でクロック信号のH区間デューティ比を測定する。
またITU3で任意のデューティ比をつくり検証する

ITU4でinputcapture (周期とH区間長さを測定)
ITU3でPWM(for debug)

設定
ITU4のインプットキャプチャ+バッファを使用
TIOCAとTIOCBに同じ信号を入力
GRAは両エッジでインプットキャプチャ
GRBは立上りでインプットキャプチャ
インプットキャプチャBでカウンタクリア
インプットキャプチャBで割り込み
割り込み時には
 BRAにHigh区間の長さが入る
 GRBに周期が入る
この2つよりデューティ比がわかる

                   Time Chart
TIOCA  ______|~~~~~~~~~~|_____________|~~~~~~~~~~|___
             ^P1        ^Q1           ^P2        ^Q2
TCNT         CLR > > up > > > > > > > CLR > > up >
GRA          |  N at P1 |    N at Q1  |  N at P2 |
BRA          |  N at Q0 |    N at P1  |  N at Q1 |
GRB          |   N at P1              |  N at P2  
              ^interrupt               ^interrupt

**********************************************************/
#include "3048f.h"
#include "h8_3048.h"

/*clockindex   0:φ,1:φ/2,2:φ/4,3:φ/8*/
/*pwmmax                                   */
/*    10      0.625    1.25     2.5     5  [μsec]*/
/*    20      1.25     2.5      5      10  */
/*    50      3.125    6.25    12.5    25  */
/*   100      6.25    12.5     25      50  */
/*   200     12.5     25       50     100  */
/*   500     31.25    62.5    125     250  */
/*  1000     62.5    125      250     500  */
/*  2000    125      250      500    1000  */
/*  5000    312.5    625     1250    2500  */
/* 10000    625     1250     2500    5000  */
/* 20000   1250     2500     5000   10000  */
/* 50000   3125     6250    12500   25000  */

/*
割り込みベクタ IMIB4 41 0xA4-0xA7

入力端子 測定したい波形を,以下の2つの端子に入力する
 4 TIOCA4/TP10/PB2 CN1-18
 5 TIOCB4/TP11/PB3 CN1-19
*/
/*デューティ比測定のための初期化*/
void initMeasDuty(int clockindex)
{
    ITU4.TCR.BIT.TPSC=clockindex; /*0:φ,1:φ/2,2:φ/4,3:φ/8*/
    ITU4.TCR.BIT.CCLR=2; /*GRBのインプットキャプチャでカウンタクリア*/
    ITU4.TIOR.BIT.IOA=7; /*GRAは立上/立下の両エッジでインプットキャプチャ*/
    ITU4.TIOR.BIT.IOB=4; /*GRBは立上のエッジでインプットキャプチャ*/
    ITU.TFCR.BIT.BFA4=1; /*GRA4とBRA4はバッファ動作*/
    ITU4.TSR.BIT.IMFB=0; /*GRBコンペアマッチフラッグクリア*/
    ITU4.TIER.BIT.IMIEB=1; /*IMFBフラグによる割込みを許可*/
    ITU.TSTR.BIT.STR4=1; /*ITU4スタート*/
}

#define readPeriod() (ITU4.GRB)
#define readHigh() (ITU4.BRA)

/*検査用PWM出力*/
/*出力端子 2 ITOCA3/PB0    CN1-16*/

/*ITU channel3 でPWM出力*/
void initPWM3(unsigned short int pwmmax, int clockindex)
{
    ITU3.TCR.BIT.TPSC=clockindex;  /*内部クロックφでカウント*/
    ITU3.TCR.BIT.CKEG=0;  /*立ち上がりエッジでカウント*/
    ITU3.TCR.BIT.CCLR=1;  /*GRAのコンペアマッチでTCNTをクリア*/
    ITU3.GRA=pwmmax-1;    /*GRAの値(GRB=GRAのときPWMが100%)をPWM_MAXに設定*/
    ITU3.GRB=0;           /*GRBの値を0に設定(=PWM0%)パルス幅はこの値に依存*/
    ITU.TMDR.BIT.PWM3=1;  /*ITUのPWMに使うchをPWMモードに設定*/
    ITU3.TIOR.BIT.IOB=0;  /*TIOCBにPWM信号を出力しないように設定*/
    ITU.TSTR.BIT.STR3=1;  /*カウントスタート(PWM信号が出力される)*/
}

/*PWM出力*/
void outPWM3(unsigned int value)
{
    if (value) {
        ITU3.TCR.BIT.CCLR=1;  /*GRAのコンペアマッチでTCNTをクリア*/
        value--;
        if (ITU3.GRA==value) value++;
        ITU3.GRB=value;
    } else {
        ITU3.TCR.BIT.CCLR=2;  /*GRBのコンペアマッチでTCNTをクリア*/
    }
}

volatile unsigned short int period=9999;
volatile unsigned short int high=0;

main()
{
    int keyhit;
    unsigned short int pwmvalue=1000;
    unsigned short int oldperiod=9999;
    unsigned short int oldhigh=0;
    initSCI1();
    SCI1_printf("\n\n\nDuty Ratio Measurement Check Program\n");
    SCI1_printf("Connect CN1-16,18,19.\n");
    SCI1_printf("Key [D] decrease PWM duty ratio down to 10%%.\n");
    SCI1_printf("Key [U] increase PWM duty ratio up to 90%%.\n");
    SCI1_printf("pwmmax=2000\n");
    initMeasDuty(3); /*clock:φ/8*/
    initPWM3(2000, 3); /*clock:φ/8 1msec周期*/
    outPWM3(pwmvalue); /*デューティ比1000/2000(50%)*/
    E_INT();        /*CPU割り込み許可*/
    while(1) {
        if (period!=oldperiod||high!=oldhigh) {
            SCI1_printf("pwm,high,period=%6d : %6u/%6u\n",pwmvalue,high,period);
            oldperiod=period;
            oldhigh=high;
        }
        if (0<(keyhit=chkgetCharSCI1())) {
            switch (keyhit) {
            case 'D':case 'd':
                if (200<pwmvalue) pwmvalue-=200;
                break;
            case 'U':case 'u':
                if (pwmvalue<1800) pwmvalue+=200;
                break;
            }
            outPWM3(pwmvalue);
            SCI1_printf("\n");
        }
    }
}

#pragma interrupt
void int_imib4() /*インプットキャプチャB割り込みルーチン*/
{
    ITU4.TSR.BIT.IMFB=0; /*GRBコンペアマッチフラッグクリア*/
    period=readPeriod();
    high=readHigh();
}

/************************************************************
Duty Ratio Measurement Check Program
Connect CN1-16,18,19.
Key [D] decrease PWM duty ratio down to 10%.
Key [U] increase PWM duty ratio up to 90%.
pwmmax=2000
pwm,high,period=  1000 :   1000/  2000
u
pwm,high,period=  1200 :   1200/  2000
u
pwm,high,period=  1400 :   1400/  2000
u
pwm,high,period=  1600 :   1600/  2000
u
pwm,high,period=  1800 :   1800/  2000
d
pwm,high,period=  1600 :   1600/  2000
d
pwm,high,period=  1400 :   1400/  2000
d
pwm,high,period=  1200 :   1200/  2000
d
pwm,high,period=  1000 :   1000/  2000
d
pwm,high,period=   800 :    800/  2000
d
pwm,high,period=   600 :    600/  2000
d
pwm,high,period=   400 :    400/  2000
d
pwm,high,period=   200 :    200/  2000
u
pwm,high,period=   400 :    400/  2000
u
pwm,high,period=   600 :    600/  2000
u
pwm,high,period=   800 :    800/  2000
u
pwm,high,period=  1000 :   1000/  2000
u
pwm,high,period=  1200 :   1200/  2000
u
pwm,high,period=  1400 :   1400/  2000
u
pwm,high,period=  1600 :   1600/  2000
u
pwm,high,period=  1800 :   1800/  2000
************************************************************/