タ イ マ R C

ルネサスアプロケーションノートR8C/M12A技術情報 マイコンカーラリーネットにタイマRCの使用例が豊富に載っていますが、説明を読んだだけでは理解不足です。タイマRCはアウトプットコンペア機能、インプットキャプチャ機能を内蔵した16ビットタイマです。外部イベントのカウントや、タイマRCカウンタと4本のジェネラルレジスタのコンペアマッチによる任意のデューティー比のパルス出力など多機能なタイマです。

     T.タイマモード(アウトプットコンペア機能)
     U.タイマモード(インプットキャプチャ機能)
     V.PWM出力モード


T.タイマモード(アウトプットコンペア機能)

 タイマモード(アウトプットコンペア機能)を使用して、TRCIOA端子(p1_1)からコンペアマッチによるトグル出力をさせてみます。

(1)モジュールスタンバイ制御レジスタ

タイマRCを有効にするためには、モジュールスタンバイ制御レジスタ(MSTRC)のタイマRCスタンバイビット(MSTTRC)をアクティブ(=0)にしなければなりません。
    msttrc = 0;

(2)ポート機能マッピングレジスタ0(PML1)
 
bit シンボル ビ ッ ト 名  機  能 
 7  P13SEL1 P1_3機能選択ビット b7  b6    
0   0:I/Oポート又はAN3入力
0   1:TRCIOC
0   0:KI3
1   1:禁止
 6  P13SEL0
 5  P12SEL1 P1_2機能選択ビット b5  b4    
0   0:I/Oポート又はAN2入力
0   1:TRCIOB
1   0:KI2
1   1:禁止
 4  P12SEL0
 3  P11SEL1 P1_1機能選択ビット b3  b2    
0   0:I/Oポート又はAN1入力
0   1:TRCIOA/TRCTRG
1   0:KI1
1   1:禁止
 2  P11SEL0
 1  P10SEL1 P1_0機能選択ビット b1  b0    
0   0:I/Oポート又はAN0入力
0   1:TRCIOD
1   0:KI0
1   1:禁止
 0  P10SEL0


    ポート1機能マッピングレジスタ0(PML1)関係ビットを以下のように設定します。

    p11sel1 = 0;
    p11sel0 = 1;


(3)タイマRCモードレジスタ(TRCMR)

 PWM2モード選択ビットを1に設定してタイマモードにします。
 最初はカウント停止にしておきますので、CTSビットを0にしておきます。各種レジスタを設定後にカウント開始にします。

bit シンボル ビ ッ ト 名 機  能
 7 CTS    TRCCNTカウント開始ビット   0:カウント停止
1:カウント開始
 6   −    
 5 BUFEB  TRCGRDレジスタ機能選択ビット 0:アウトプットコンペアレジスタまたはインプットキャプチャレジスタ
1:TRCGRDレジスタはTRCGRBレジスタのバッファレジスタ
 4 BUFEA  TRCGRCレジスタ機能選択ビット  0:アウトプットコンペアレジスタまたはインプットキャプチャレジスタ
1:TRCGRCレジスタはTRCGRAレジスタのバッファレジスタ
 3 PWM2 PWM2モード選択ビット 0:PWM2モード
1:タイマモードまたはPWMモード   
 2 PWMD  TRCIOD PWMモード選択ビット   0:タイマモード
1:PWMモード   
 1 PWMC  TRCIOC PWMモード選択ビット 
 0 PWMB  TRCIOB PWMモード選択ビット 

    pwm2_trcmr = 1;
    cts_trcmr = 0;



(4)タイマRC制御レジスタ1(TRCCR1)

コンペアマッチAでTRCCNTカウントをクリア、カウントソースをf8(2.5Mhz)で行う。

bit シンボル ビ ッ ト 名 機  能
  7  CCLR  TRCCNTカウンタクリア選択ビット  0:クリア禁止
 1:インプットキャプチャ/コンペアマッチA
   でTRCCNTカウントクリア  
  6  CKS2  カウントソース選択ビット  000:f1
 001:f2
 010:f4
 011:f8
 100:f32
 101:TRCCLK入力の立ち上がりエッジ
 110:fHOCO
 111:禁止
  5  CKS1
  4  CKS0
  3  TOD  タイマ出力レベル選択Dビット  0:出力値0
 1:出力値1
  2  TOC  タイマ出力レベル選択Cビット
  1  TOB  タイマ出力レベル選択Bビット
  0  TOA  タイマ出力レベル選択Aビット


    trccr1 = 0xb0;

    カウントソース設定後にシステムクロックを2サイクル待つ
    asm("nop");
    asm("nop");


(5)タイマRC I/O制御レジスタ0(TRCIOR0)

 コンペアマッチでTRCIOA端子からトグル出力する。

ビット シンボル ビット名 機  能
  7  −  ビットは何も記されていないので1を記入する
  6  IOB2  TRCGRB制御2ビット  0:アウトプットコンペア機能
 1:インプットキャプチャ機能
  5  IOB1  TRCGRB制御1ビット
  4  IOB0  TRCGRB制御0ビット
  3  −  予約ビット  1を記入する
  2  IOA2  TRCGRA制御A2ビット  0:アウトプットコンペア機能
 1:インプットキャプチャ機能
  1  IOA1  TRCGRA制御A1ビット  11:コンペア一致AでTRCIOA端子へトグル出力
  0  IOA0  TRCGRA制御A0ビット


    trcior0 = 0x8b;


(6)タイマRC制御レジスタ2(TRCCR2)

 関係するのはビット5のカウント停止ビットだけです。TRCGRAレジスタとのコンペア一致後もカウントを継続します。

bit シンボル ビット名 機能
  7
  6
  5  CTSP  カウント停止ビット  0:TRCGRAレジスタとのコンペア一致後もカウント継続
 1:TRCGRAレジスタとのコンペア一致でカウント停止
  4  −  ビットは何も記されていないので1を記入する
  3  −  ビットは何も記されていないので1を記入する
  2
  1
  0


   trccr2 = 0x18;


(7)タイマRCカウンタ(TCCNT)

 16ビットの読み出し書き込み可能なアップカウンタです。タイマRCジェネラルレジスタ(TRCGRA)にコンペア値を設定します。

 開始時に  trccnt = 0; としてイニシャライズしておきます。



(8)タイマRCジェネラルレジスタA(TRCGRA)

   trcgra = 2000 - 1;

  ここでは、f8(2.5MHz)でカウントを行っていますので、 1/2.5MHz = 400μs 毎にカウントアップしていくので、

  400μs * 2000 = 0.8ms毎にTRCIOA端子(p1_1)からトグル出力されます。



(9)タイマRC A/D変換トリガ制御レジスタ(TRACADCR)

 TRACADCRレジスタを設定することで、コンペア一致A〜DによってA/D変換開始トリガを発生できます。b0〜b3です。
ここではビット0のTRCGRAに関係するビットだけですが、他も全てdisableにしておきます。

    trcadcr = 0xf0;



(10)タイマRC波形出力操作レジスタ(TRCOPR)

 TRCOPRレジスタを設定することによって、タイマRCの波形出力を操作できます。
今回は、全て波形出力操作機能は全て無効にします。

    trcopr = 0x00;



(11)タイマRC割り込み許可レジスタ(TRCIER)

bit b7 b6 b5 b4 b3 b2 b1 b0
シンボル  OVIE IMIED IMIEC IMEB IMIEA
設定値   0  1  1  1    0    0    0    0

 ここでは割り込みは使用していないので、インプットキャプチャ/コンペア一致割り込み許可は全て禁止に設定します。

    trcier = 0x70;



(12)タイマRCステータスレジスタ(TRCSR)

 割り込みは使っていないので、 

bit b7 b6 b5 b4 b3 b2 b1 b0
シンボル  OVF IMFD IMFC IMFB IMFA
設定値   0  1  1  1    0    0    0    0

    trcsr = 0x70;



(13)タイマRC出力許可レジスタ(TRCOER)

 b0がTRCIOAの出力に関係するビットです。出力許可=0に設定する。

bit b7 b6 b5 b4 b3 b2 b1 b0
シンボル  PTO ED EC EB EA
設定値   0  1  1  1    1    1    1    0


    trcoer = 0x7e;



◎プログラム M12_RC2_EM.c

 #include "sfr_r8m12a.h"

 void init(void);
 void timer_rc_init(void);

 void main(void)
 {

  init();
  timer_rc_init();
  while(1);
 }
 /* I/O初期化関数 */
 void init(void)
 {
  int i;
  /**** 高速オンチップオシレータで動作する場合 ****/
  prc0 = 1;// プロテクトレジスタ解除
  hocoe = 1;// 高速オンチップオシレータ発振開始
  for(i=0;i<50;i++);//発振安定まで待つ
  hscksel =1;// 高速オンチップオシレータ選択ビットを1にする
  scksel =1;// システム基準クロックを高速にする
  prc0 = 0;// プロテクトレジスタ禁止
  pd1 = 0x7f;// ポートディレクションレジスタ1全て出力ポート設定
 }

 /* タイマRC初期化関数 */
 void timer_rc_init(void)
 {
  msttrc = 0; // モジュールスタンバイ制御レジスタ タイマRCを有効にする
  p11sel0 = 1; // ポート1機能マッピングレジスタ0(PML1)
  p11sel1 = 0; // p1_1をTRCIOA端子に設定
  ilvl3 = 0x00; // 割り込み優先レベルレジスタ:0 割り込み禁止

  pwm2_trcmr = 1; // タイマRCモードレジスタをタイマモードに設定
  cts_trcmr = 0; // タイマRCモードレジスタ TRCCNTカウント停止
  trccr1 = 0xb0; // タイマRC制御レジスタ1 コンペアマッチAでカウントクリャー カウントソース=f8(2.5MHz)
  asm("nop"); // wait
  asm("nop"); // wait
  trcior0 = 0x8b; // タイマRC I/O制御レジスタ0 コンペアマッチでTRCIOA端子トグルアウトプット
  trccr2 = 0x18; // タイマRC制御レジスタ2 Count continues after the compare match
  trccnt = 0; // TRCCNT カウント値イニシャライズ
  trcgra = 2000-1;// 0.8ms=800us = 400ns * 2000
  trcadcr = 0xf0; // タイマRC A/D変換トリガ制御レジスタ disable
  trcopr = 0x00; // タイマRC 波形出力操作レジスタ disable
  trcier = 0x70; // タイマRC 割り込み許可レジスタ disable
  trcsr &=0x70; // タイマRC ステータスレジスタ ステータスフラグクリャー
  trcoer = 0x7e; // タイマRC 出力許可レジスタ TRCIOA Pin:enabled
  cts_trcmr = 1; // タイマRCモードレジスタ TRCCNTカウント開始
 }





実行画面

TRCIOA端子(p1_1)から800μsのトグル出力


プロジェクトファイルのダウンロード




U.タイマモード(インプットキャプチャ機能)

 タイマRCのタイマモード(インプットキャプチャ機能)を使って、TRIOA端子(p1_1)に入力される外部からの信号のパルス幅を測定してLCDに表示してみます。外部信号には同じタイマRCのPWDモードを使って0.5msのPWMパルス(H幅、L幅共に0.5ms)を発生させた別のCPUボードからの信号を入力値として使います。測定原理の説明はルネサスアプリケーションノートに詳しく解説されているのでここでは省略します。

レジスタ設定は以下のようにします。

(1)ポート1機能マッピングレジスタ0(PML1)

 ここでは、p1_1をTRCIOA端子に設定します。ポート1機能マッピングレジスタ0(PML1)を以下のように設定します。

    p11sel1 = 0;
    p11sel0 = 1;

(2)割り込み優先レベル(ILVL3)
  
  タマRCの初期化関数の設定の最初には

    ilvl3 = 0x00; として割り込み禁止にしておいて、
            タイマRCの初期化関数の最後に
    ilvl3 = 0x01; として割り込み優先レベル1に設定します。

(3)モジュールスタンバイ制御レジスタ(MSTCR)

    msttrc = 0;


(4)タイマRCモードレジスタ(TRCMR)
 

bit シンボル ビ ッ ト 名 機  能
 7  CTS     TRCCNTカウント開始ビット    0:カウント停止
 1:カウント開始
 6    −   機能なし  1を記入
 5  BUFEB   TRCGRDレジスタ機能選択ビット  0:アウトプットコンペアレジスタ
   またはインプットキャプチャレジスタ
 1:TRCGRDレジスタはTRCGRBレジスタのバッファレジスタ
 4  BUFEA   TRCGRCレジスタ機能選択ビット   0:アウトプットコンペアレジスタ
   またはインプットキャプチャレジスタ
 1:TRCGRCレジスタはTRCGRAレジスタのバッファレジスタ: 
 3  PWM2  PWM2モード選択ビット  0:PWM2モード
 1:タイマモードまたはPWMモード   
 2  PWMD   TRCIOD PWMモード選択ビット    0:タイマモード
 1:PWMモード   
 1  PWMC   TRCIOC PWMモード選択ビット 
 0  PWMB   TRCIOB PWMモード選択ビット 

  b7:0 最初はカウント停止にしておきますので、CTSビットを0にしておき、
       各種レジスタを設定後にカウント開始に設定
  b6:1
  b5:0
  b4:1 TRCGRCレジスタをTRCGRAレジスタのバッファレジスタに設定します
  b3:1 PWM2モード選択ビットを1に設定してタイマモードにします
  b2:0
  b1:0
  b0:0


    trcmr = 0x58;


(5)タイマRC制御レジスタ1(TRCCR1)

   b7:0 TCCNTカウントクリア選択ビットを0にしてクリア禁止に設定(フリーランニング動作)
   b6 〜 b4:カウントソース選択ビット 000:f1(20MHz)に設定
   b3 〜 b0:タイマ出力レベル選択ビット(A〜D)は全て0に設定

    trccr1 = 0x00;

  カウントソース設定後にシステムクロックを2サイクル待つ

    asm("nop"); 
    asm("nop"); 



(6)タイマRC I/O制御レジスタ0(TRCIOR0)

bit シンボル ビット名 機  能
  7  −  ビットは何も記されていないので1を記入する
  6  IOB2  TRCGRB制御2ビット  0:アウトプットコンペア機能
 1:インプットキャプチャ機能
  5  IOB1  TRCGRB制御1ビット
  4  IOB0  TRCGRB制御0ビット
  3  −  予約ビット  1を記入する
  2  IOA2  TRCGRA制御A2ビット  0:アウトプットコンペア機能
 1:インプットキャプチャ機能
  1  IOA1  TRCGRA制御A1ビット  IOA2=1のとき
 00:TRCIOA端子の立ち上がりエッジ
 01:TRCIOA端子の立ち下がりエッジ
 10:TRCIOA端子の両エッジ
  0  IOA0  TRCGRA制御A0ビット

  b7:1
  b6〜b4:0
  b3:1
  b2:1 TRCGRA制御A2ビット インプットキャプチャ機能
  b1 〜 b0:TRCGRA制御A1、A0ビット TRCGRA端子の両エッジでキャプチャ:10に設定
    trcior0 = 0x8e;


(7)タイマRC I/O制御レジスタ1(TRCIOR1)(TRCIOR1)

bit シンボル ビット名 機  能
  7  IOD3  TRCGRD制御D3ビット
  6  IOD2  TRCGRD制御D2ビット  
  5  IOD1  TRCGRD制御D1ビット
  4  IOD0  TRCGRD制御D0ビット
  3  IOC3  TRCGRC制御C3ビット  TRCIOA、TRCIOC端子には出力しない。
 IOC2=1のとき、 IOC3ビットは1に設定
  2  IOC2  TRCGRC制御C2ビット  0:アウトプットコンペア機能
 1:インプットキャプチャ機能
  1  IOC1  TRCGRC制御C1ビット  IOC2=1、IOC3=1のとき
 00:TRCIOC端子の立ち上がりエッジでインプットキャプチャ
 01:TRCIOC端子の立ち下がりエッジでインプットキャプチャ
 10:TRCIOC端子の両エッジでインプットキャプチャ
  0  IOC0  TRCGRC制御C0ビット

  b7〜b4:0
  b3:1 TRCGRC制御C3ビット
  b2:1 TRCGRC制御C2ビット インプットキャプチャ機能
  b1〜b0:10 TRCGRC制御C1、C0ビット 両エッジでキャプチャ

    trcior1 = 0x0e;



(8)タイマRC制御レジスタ2(TRCCR2)

 関係するのはビット5のカウント停止ビットだけです。TRCGRAレジスタとのコンペア一致後もカウントを継続します。

    trccr2 = 0x18;



(9)タイマRCデジタルフィルタ機能選択レジスタ(TRCDF)

bit シンボル ビット名 機能
  7  DFCK1  デジタルフィルタクロック選択ビット  11:TRCCR1レジスタのCKS0〜CKS2ビット
    で選択したクロック
  6  DFCK0
  5  −  何も配置されていない   0を記入する 
  4  DFTRG  TRCTRGデジタルフィルタ機能  PWM2モードの時のみ有効
  3  DFD  TRCIODデジタルフィルタ機能  0:機能なし 1:機能あり
  2  DFC  TRCIOCデジタルフィルタ機能  0:機能なし 1:機能あり
  1  DFB  TRCIOBデジタルフィルタ機能  0:機能なし 1:機能あり
  0  DFA  TRCIOAデジタルフィルタ機能  0:機能なし 1:機能あり

  b7〜b6:11 TRCCR1レジスタのCKS0〜CKS2ビットと同じ
  b5:0
  b4:0
  b3〜b1:000 機能なし
  b0:1 TRCIOAデジタルフィルタ機能あり

    trcdf = 0xc1;
  

(10)タイマRCカウント(TRCCNT)

  読み出し書き込み可能な16ビットアップカウンタです。


    trccnt = 0; 初期化しておきます。



(11)タイマRCジェネラルレジスタA(TRCGRA)

    trcgra = 0; 初期化しておきます。



(12)タイマRCジェネラルレジスタC(TRCGRC)

 ジェネラルレジスタCのバッファレジスタとして使用しています。

    trcgrc = 0; 初期化しておきます。



(13)タイマRC波形出力操作レジスタ(TRCOPR)

 TRCOPRレジスタを設定することによって、タイマRCの波形出力を操作できます。
今回は、全て波形出力操作機能は全て無効にします。

    trcopr = 0x00;


(14)タイマRC割り込み許可レジスタ(TRCIER)

ビット b7 b6 b5 b4 b3 b2 b1 b0
シンボル  OVIE IMIED IMIEC IMEB IMIEA
設定値   1   1   1   1    0    0    0     1

  b7:タイマオーバフロー割り込み許可ビットを1に設定。
  b0:インプットキャプチャ/コンペ一致A割り込み許可ビットを1に設定します。

    trcier = 0xf1;


(15)タイマRCステータスレジスタ(TRCSR)

ビット b7 b6 b5 b4 b3 b2 b1 b0
シンボル  OVF IMFD IMFC IMFB IMFA
設定値   0   1   1   1    0    0    0    0

  b7:タイマオーバフローフラグを初期化

    trcsr = 0x70;


(16)タイマRC出力許可レジスタ(TRCOER)
 

bit b7 b6 b5 b4 b3 b2 b1 b0
シンボル   PTO ED EC EB EA
設定値    0   1   1   1    1    1    1    1

  b0がTRCIOAの出力に関係するビットですが、全て出力禁止=1に設定する。

    trcoer = 0x7f;



(17)タイマRCモードレジスタ(TRCMR)
  最初は、b7=0 としてカウント停止にしておいたCTSビットを各種レジスタを設定後に1に設定してカウントを開始します。
    cts_trcmr = 1;




◎プログラム M12_RC_INCAP.c  #include "sfr_r8m12a.h"
 #include "lcd2_ctrl.h"

 unsigned char f_capture = 0; // Capture flag
 unsigned short ovf_cnt = 0; // Overflow counter
 unsigned short present_value = 0;// Present value
 unsigned short last_value = 0; // Last value
 unsigned long measurement_value = 0;// Measurement value
 unsigned long ad;

 void main(void)
 {
  unsigned int i;
  unsigned int rd1[10];
  unsigned int rd2[10];
  unsigned char str1[16]; // LCD1行目表示配列
  unsigned char str2[16]; // LCD2行目表示配列

  init();
  lcd_init();
  lcd_clear();
  for(i=0;i<16;i++){
   str1[i]=' '; // LCD1行目表示配列初期化
   str2[i]=' '; // LCD2行目表示配列初期化
  }
  lcd_cursor_off();

  asm("FCLR I"); // Interrupt disabled
  timer_rc_init();// Timer RC initialized
  asm("FSET I"); // Interrupt enabled

  while(1){
   ad=measurement_calcu();// Measurements calculation processing
   /**** LCD 16進表示 ****/
   for(i=0;i<4;i++){ // 各桁に分解する
    rd2[i] = ad % 16;// 16進4桁
    ad = ad /16;
   }
   if(rd2[3]<10) str2[2]=rd2[3]+0x30;else str2[2]=rd2[3]+0x41-0x0A;
   if(rd2[2]<10) str2[3]=rd2[2]+0x30;else str2[3]=rd2[2]+0x41-0x0A;
   if(rd2[1]<10) str2[4]=rd2[1]+0x30;else str2[4]=rd2[1]+0x41-0x0A;
   if(rd2[0]<10) str2[5]=rd2[0]+0x30;else str2[5]=rd2[0]+0x41-0x0A;
   lcd_str(str1,1);
   lcd_str(str2,2);
   wait_ms(100);
  }
 }
 /* I/O初期化関数 */
 void init(void)
 {
  int i;
  /**** 高速オンチップオシレータで動作する場合 ****/
  prc0 = 1;// プロテクトレジスタ解除
  hocoe = 1;// 高速オンチップオシレータ発振開始
  for(i=0;i<50;i++);//発振安定まで待つ
  hscksel =1;// 高速オンチップオシレータ選択ビットを1にする
  scksel =1;// システム基準クロックを高速にする
  prc0 = 0;// プロテクトレジスタ禁止
  pd1 = 0xf0;// ポートディレクションレジスタ1 1111 0000
  pd3 = 0x18;// ポート3の入出力設定
 }
 /* タイマRC初期化関数 */
 void timer_rc_init(void)
 {
  p11sel0 = 1; // P1_1: TRCIOA
  p11sel1 = 0; // 〃
  ilvl3 = 0x00; // Timer RC interrupt disabled
  mstcr = 0x00; // Timer RC Active
  trcmr = 0x58; // タイマモード,TRCGRC:バッファレジスタ TRCRGA,TRCCNT:stop
  trccr1 = 0x00; // Count Source: f1,Free-running counter
  asm("nop"); // wait for at least two cycles of the system clock
  asm("nop"); // before writing to the registers associated with timer RC
  trcior0 = 0x8e; // タイマRCI/O制御レジスタ0 IOA2:1 b1:1 b0:0 両エッジ on TRCIOA pin
  trcior1 = 0x0e; // タイマRCI/O制御レジスタ1 TRCGRC control: Input capture function
  trccr2 = 0x18; // コンペアマッチ後もカウント継続 with the TRCGRA register
  trcdf = 0xc1; // TRCIOA: Digital filter function used
  trccnt = 0; // TRCCNT initialized
  trcgra = 0; // TRCGRA initialized
  trcgrc = 0; // TRCGRC initialized
  trcopr = 0x00; // Waveform output manipulation disabled
  trcier = 0xf1; // Interrupt request (IMIA) by IMFA bit in TRCSR register is enabled
  // Interrupt request (FOVI) by OVF bit in TRCSR register is enabled
  trcsr = 0x70; // Timer RC status flags clear trcsr &= 0x70
  trcoer = 0x7f; // TRCIOA TRCIOB TRCIOC TRCIOD Pin output disabled
  // Bits EA to ED do not change even if a low level is input to the INT0 pin
  ilvl3 = 0x10; // Timer RC interrupt enabled (Level 1)
  cts_trcmr = 1; // TRCCNT count is started
 }


 unsigned long measurement_calcu(void)
 {
  if(f_capture == 1){// Captured ?
   asm("FCLR I"); // Interrupt disabled
   if(ovf_cnt == 0x0000){ // Overflowed ?
   measurement_value = (unsigned long)(present_value - last_value);
  }else{
   measurement_value = (unsigned long)((unsigned long)0x10000 * ovf_cnt - last_value + present_value);
   ovf_cnt = 0x0000; // Overflow counter cleared
  }
  f_capture = 0; // Capture flag cleared
  asm("FSET I"); // Interrupt enabled
  }
  return measurement_value;
 }

 #pragma interrupt _timer_rc(vect=7)
 void _timer_rc(void)
 {
  if(ovf_trcsr == 1){// Overflowed ?
   ovf_trcsr = 0; // Overflow flag clear
   ovf_cnt++; // Overflow counter increment
  }else{
   imfa_trcsr = 0; // Input capture/compare match A flag clear
   present_value = trcgra; // TRCGRA register read
   last_value = trcgrc; // TRCGRC register read
   f_capture = 1; // Capture flag set
  }
 }


◎LCD制御関数 lcd2_ctrl.c
 以前使用したLCD表示関数とは以下のように結線が少し異なっています。そのために、 lcd_data()関数が異なっていますが、その他基本的なプログラムはそのままです。

LCD側 R8C/M12A側
 1(Vdd)     
 2(Vss)     
 3(Contrast)     
 4(RS)     p3_4
 5(R/W)     GND
 6(E)     p3_3
 7(DB0)    
 8(DB1)
 9(DB2)
 10(DB3)
 11(DB4)     p1_4
 12(DB5)     p1_5
 13(DB6)     p1_6
 14(DB7)     p1_7


 #include "sfr_r8m12a.h"
 #include "lcd2_ctrl.h"
 /**********************************************************/
 /* タイマ本体 us単位のwait関数 */
 /**********************************************************/
 void wait_us(unsigned long usec)
 {
  usec = (usec * CLOCK) / 45000;
  while(usec --);{}
 }
 /**********************************************************/
 /* タイマ本体 ms単位のwait関数 */
 /**********************************************************/
 void wait_ms(unsigned long msec)
 {
  unsigned int i;
  for(i=0;i<msec;i++){
   wait_us(1000);
  }
 }
 /* データ出力関数 */
 void lcd_out(unsigned char code,unsigned char flag)
 {
  p1=code & 0xf0;// 上位4ビット出力bit
  if( flag == 0)
   RS_High;
  else
   RS_Low;
  asm("NOP");
  E_High;
  asm("NOP");
  asm("NOP");
  asm("NOP");
  asm("NOP");
  E_Low;
 }

 /* 1文字出力関数 */
 void lcd_data(unsigned char asci)
 {
  lcd_out(asci,0); // 上位4ビット出力
  lcd_out(asci<<4,0); // 下位4ビット出力
  wait_us( 50 );
 }

 /* コマンド出力関数 */
 void lcd_cmd(unsigned char cmd)
 {
  lcd_out(cmd,1);
  lcd_out(cmd<<4,1);
  if((cmd == 0x01) || (cmd == 0x02))
   wait_us(2000);
  else
   wait_us(50);
 }

 /* 画面消去関数 */
 void lcd_clear(void)
 {
  lcd_cmd(0x01);
 }
 /* カーソル表示OFF */
 void lcd_cursor_off(void)
 {
  lcd_cmd(0x0c);
 }

 /* 文字列出力関数 */
 void lcd_str(unsigned char *str,unsigned char line)
 {
  if(line==1)
   lcd_cmd(0x02);
  else
   lcd_cmd(0xc0);

  while(*str != 0x00){
   lcd_data(*str);
   str++;
  }
 }

 /* LCD初期化関数 */
 void lcd_init(void)
 {
  wait_us(20000);
  lcd_out(0x03,1); // LCD初期化1回目 0010 0011 E=1,RS=0 8ビット転送
  wait_us(5000);
  lcd_out(0x03,1); // LCD初期化2回目 0010 0011 E=1,RS=0 8ビット転送
  wait_us(4000);
  lcd_out(0x03,1); // LCD初期化3回目 0010 0011 E=1,RS=0 8ビット転送
  wait_us(4000);
  lcd_out(0x02,1); // LCD初期化4回目 0010 0010 E=1,RS=0 8ビット転送 データ長4ビットに設定
  wait_us(4000);
  lcd_cmd(0x28); // 001 0 1000 セットファンクション b4=0:転送長4ビット,b3=1:表示数2行,b2=0:表示ドット5x7
  wait_us(4000);
  lcd_cmd(0x08); // 0000 1000 ディスプレイOFF,D=C=B=0
  wait_us(4000);
  lcd_cmd(0x0e); // 0000 1110 b2=1:ディスプレイON,b1=1:カーソルON,b0=0:ブリンクOFF
  wait_us(4000);
  lcd_cmd(0x06); // 0000 01 10 エントリーモード b1=1:カーソル移動方向インクリメント,b0=0:ディスプレイシフトしない
  wait_us(4000);
  lcd_cmd(0x01); // 0000 000 1 クリアディスプレイ
  wait_us(4000);
 }

◎ヘッダーファイル lcd2_ctrl.h
 #define CLOCK 20000
 #define LCD p1 // LCDのデータポート

 /* LCDのレジスターセレクション */
 #define RS_High (p3_4=1)
 #define RS_Low (p3_4=0)

 /* LCDのディスプレーイネーブル */
 #define E_High (p3_3=1)
 #define E_Low (p3_3=0)

 void init(void);
 void timer_rc_init(void);
 unsigned long measurement_calcu(void);/* Measurements calculation processing */
 void _timer_rc(void);/* Timer RC interrupt processing */

 void wait_ms(unsigned long msec); // ms単位のタイマ
 void wait_us(unsigned long usec);
 void delay(void); // 6usの遅延関数

 void lcd_out(unsigned char code,unsigned char flag);
 void lcd_data(unsigned char asci);
 void lcd_cmd(unsigned char cmd);
 void lcd_clear(void);
 void lcd_cursor_off(void);
 void lcd_str(unsigned char *str,unsigned char line);
 void lcd_init(void);


実行画面
 H幅、L幅共に0.5msのパルスをキャプチャしたLCD表示画面
多少変動しますが、2700(16進表示)前後の値が表示されます
0x2709=2*16*16*16+7*16*16+9=9993
 9993 * 50 ns = 約 0.5ms(10進)

プロジェクトファイルのダウンロード






V.PWM出力モード


TRIOB、TRIOC、TRIODのPWM同時出力が可能です。ただし、それぞれのデューティー比は変えることはできますが、同じ周期しか出力できません。ここでは、タイマRCを使って異なるデューティー比のPWMを3本同時に出力する実験をしてみます。

(1)モジュールスタンバイ制御レジスタ

タイマRCを有効にするためには、モジュールスタンバイ制御レジスタのタイマRCスタンバイビットをアクティブにしなければなりません。

    msttrc = 0;



(2)ポート機能マッピングレジスタ

 PWMの出力端子として使えるのは、TRCIOB、TRCIOC、TRCIODの3つがあります。端子にこの機能を与えるのが、ポート機能マッピングレジスタです。



◎TRCIOB端子の設定

 TRICIOB端子として使えるのは、p1_2、p1_4、p1_6の3つです。

 p1_2をTRCIOB端子として使う場合、ポート1機能マッピングレジスタを以下のように設定します。
    p12sel1 = 0;
    p12sel0 = 0;

    または、pml1 = 0x10;

 p1_4をTRCIOB端子として使う場合、ポート1機能マッピングレジスタを以下のように設定します。
    p14sel2 = 1;;
    p14sel1 = 0;
    p14sel0 = 0;

    または、pmh1 = 0x04;

 p1_6をTRCIOB端子として使う場合、ポート1機能マッピングレジスタを以下のように設定します。
    p16sel1 = 1;
    p16sel0 = 1;

    または、pmh1 = 0x30;


◎TRCIOC端子の設定

 TRCIOC端子として使えるのは、p1_3、p3_4の2つです。

 p1_3をTRCIOC端子として使う場合、ポート1機能マッピングレジスタを以下のように設定します。
    p13sel1 = 0;
    p13sel0 = 0;

    または、pml1 = 0x40;

 p3_4をTRCIOC端子として使う場合、
    p34sel1 = 0;
    p34sel0 = 0;

    または、pmh3 = 0x01;



◎TRCIOD端子の設定

 TRCIOD端子として使えるのは、p1_0、p3_5、p3_7の3つです。

 p1_0をTRCIOD端子として使う場合、ポート1機能マッピングレジスタを以下のように設定します。
    p10sel1 = 0;
    p10sel0 = 1;

    または、pml1 = 0x01; 

 p3_5をTRCIOD端子として使う場合、ポート3機能マッピングレジスタを以下のように設定します。
    p35sel1 = 0;
    p35sel0 = 1;

    または、pmh3 = 0x04;

 p3_7をTRCIOD端子として使う場合、ポート3機能マッピングレジスタを以下のように設定します。
    p37sel1 = 1;
    p37sel0 = 1;

    または、pmh3 = 0xc0;


タイマRCの端子が、同じポート1やポート3に複数ある場合は、設定に注意が必要です。ポート機能マッピングレジスタを1ビット毎に設定したほうが間違いがないと思います。



(3)タイマRCモードレジスタ(TRCMR)

bit シンボル ビ ッ ト 名 機  能
  7  CTS     TRCCNTカウント開始ビット    0:カウント停止
 1:カウント開始
  6        
  5  BUFEB   TRCGRDレジスタ機能選択ビット  0:アウトプットコンペアレジスタまたはイ
   ンプットキャプチャレジスタ
 1:TRCGRDレジスタはTRCGRBレジス
   タのバッファレジスタ
  4  BUFEA   TRCGRCレジスタ機能選択ビット   0:アウトプットコンペアレジスタまたはイ
   ンプットキャプチャレジスタ
 1:TRCGRCレジスタはTRCGRAレジス
   タのバッファレジスタ: 
  3  PWM2  PWM2モード選択ビット  0:PWM2モード
 1:タイマモードまたはPWMモード   
  2  PWMD   TRCIOD PWMモード選択ビット    0:タイマモード
 1:PWMモード   
  1  PWMC   TRCIOC PWMモード選択ビット 
  0  PWMB   TRCIOB PWMモード選択ビット 


 PWM2モード選択ビットを1にすると、PWMモードになります、ビット0〜2のPWMモード選択ビットを指定して、どの端子から出力するかを決めます。3端子全てを指定することも可能です。TCCNTカウント開始(CTS)ビットは、コンペアマッチになると、0になります。

    cts_trcmr = 1; ・・・   TRCCNT開始になります。


 ここでは、TRCIOD端子、TRCIOC端子、TRCIOB端子からPWMを出力しますので、設定を以下のようにします。

    pwm2_trcmr = 1; ・・・ 各端子をPWMモードにする
    pwmd_trcmr = 1; ・・・ TRCIOD端子をPWMモードにする
    pwmc_trcmr = 1; ・・・ TRCIOC端子をPWMモードにする
    pwmb_trcmr = 1; ・・・ TRCIOB端子をPWMモードにする



(4)タイマRC制御レジスタ1(TRCCR1)

bit シンボル ビ ッ ト 名 機  能
  7  CCLR  TRCCNTカウンタクリア選択ビット  0:クリア禁止
 1:インプットキャプチャ/コンペアマッチA
   でTRCCNTカウントクリア  
  6  CKS2  カウントソース選択ビット  000:f1
 001:f2
 010:f4
 011:f8
 100:f32
 101:TRCCLK入力の立ち上がりエッジ
 110:fHOCO
 110:禁止
  5  CKS1
  4  CKS0
  3  TOD  タイマ出力レベル選択Dビット  0:出力値0
 1:出力値1
  2  TOC  タイマ出力レベル選択Cビット
  1  TOB  タイマ出力レベル選択Bビット
  0  TOA  タイマ出力レベル選択Aビット


 TRCCNTカウントクリア選択ビット(CCLR)を1に設定します。カウントソース選択ビットは、f1(20MHz)を選びます。これは、1/20MHz=50ns毎にカウントアップしていくことになります。タイマ出力レベル選択ビットは、最初のコンペアマッチが発生するまでの端子の出力値を指定します。従って、コンペアマッチが発生してから1にするためには、設定値を0にしておく必要があります。以上の事から、タイマRC制御レジスタ1は、

    trccr1 = 0x80; ・・・ となります。


(5)タイマRCカウント(TRCCNT)

 16ビットの読み出し、書き込み可能なアップカウンタです。プログラム内で設定することはありません。カウントソース選択ビットで設定したクロックでカウントアップします。TRCGRAで設定した値を超えた瞬間に0になります。TRCIOB、TRCIOC、TRCIODの各端子の波形がHになります。0〜65535の値をとることが可能です。オーバーフローすると、TRCSRレジスタのOVFビットが1になります。




(6)タイマRC出力許可レジスタ(TRCOER)

ビット 機  能
  7      
  6    
  5    
  4    
  3   ED  TRCIOD出力禁止ビット  0:出力許可
 1:出力禁止   
  2   EC  TRCIOC出力禁止ビット  0:出力許可
 1:出力禁止    
  1   EB  TRCIOB出力禁止ビット  0:出力許可
 1:出力禁止   
  0   EA  TRCIOA出力禁止ビット  0:出力許可
 1:出力禁止    


    eb_trcoer = 0; ・・・ TRCIOBの出力許可レジスタを許可
    ec_trcoer = 0; ・・・ TRCIOCの出力許可レジスタを許可
    ed_trcoer = 0; ・・・ TRCIODの出力許可レジスタを許可



(7)タイマRCジェネラルレジスタTRCGRi(i=A〜D)

 ここでは、PWMモードの時、アウトプットコンペア機能時のジェネラルレジスタについてだけ説明します。

1)タイマRCジェネラルレジスタA(TRCGRA)

 全体のPWM周期を設定するレジスタです。タイマRC制御レジスタ(TRCCR1)のカウントソース選択ビットをf1(20MHz)に設定しているので、1/20MHz=50ns毎にカウントアップしていくことになります。ここでは、周期を1msにしますので、50ns * 20000 = 1msになります。タイマRCカウンタが0からカウントを開始し、19999で20000回のカウントになりますので、次のタイミングで0にクリアされるように、設定値を20000−1にします。

    trcgra = 20000 - 1; ・・・ と設定します。



2)タイマRCジェネラルレジスタB(TRCGRB)

  TRCIOB端子から出力するPWMのH幅をコンペアマッチするレジスタです。H幅0.05msにしたいので、タイマRCカウンタ値が20000で1msに相当しますから、1ms/0.05ms=20ですので、20000/20=1000になります。

    trcgrb = 1000 - 1;

3)タイマRCジェネラルレジスタC(TRCGRC)

 TRCIOC端子から出力するPWMのH幅をコンペアマッチするレジスタです。H幅0.1msにしたいので、タイマRCカウンタ値が20000で1msに相当しますから、1ms/0.1ms=10ですので、20000/10=2000になります。

    trcgrc = 2000 - 1;



4)タイマRCジェネラルレジスタD(TRCGRD)

  TRCIOD端子から出力するPWMのH幅をコンペアマッチするレジスタです。H幅0.5msにしたいので、タイマRCカウンタ値が20000で1msに相当しますから、1ms/0.5ms=2ですので、20000/2=10000になります。

    trcgrd = 10000 - 1;




◎プログラム M12_TIMER_RC_A.c

タイマRCの簡単な実験を行っています。

    trcga = 20000-1 PWM周期を 1/20MHz*20000 = 1ms に設定します。
    p1_0をTRCIOD端子にして、trcgrd = 10000 -1、H幅 0.5msのパルスを出力します。
    p1_2をTRCIOB端子にして、trcgrb = 1000 -1、H幅0.05msのパルスを出力します。
    p1_3をTRCIOC端子にして、trcgrc = 2000−1、H幅0.1msのパルスを出力します。


  #include "sfr_r8m12a.h"
  void init(void);
  void main(void)
  {
    init();
    while(1){

    }
  }
/* I/O初期化関数 */
  void init(void)
  {
    int i;
    /**** 高速オンチップオシレータで動作する場合 ****/
    prc0 = 1;// プロテクトレジスタ解除
    hocoe = 1;// 高速オンチップオシレータ発振開始
    for(i=0;i<50;i++);//発振安定まで待つ
    hscksel =1;// 高速オンチップオシレータ選択ビットを1にする
    scksel =1;// システム基準クロックを高速にする
    prc0 = 0;// プロテクトレジスタ禁止

    pd1 = 0x7f;// ポートディレクションレジスタ1全て出力ポート設定
    pd3 = 0xff;
    pd4 = 0xff;
    pda = 0xff;

    msttrc = 0; // タイマRCを有効にする
    p12sel1= 0; // TRCIOB端子の選択 pml1=0x10
    p12sel0= 1; // p1_2をTRCIOB端子にする
    //pml1=0x10;

    //p14sel2= 1;// TRCIOB端子の選択
    //p14sel1= 0;
    //p14sel0= 0;// p1_4をTRCIOB端子にする

    //p16sel1= 1;// TRCIOB端子の選択
    //p16sel0= 1;// p1_6をTRCIOB端子にする

    p13sel1 = 0;// TRCIOC端子の選択
    p13sel0 = 1;// p1_3をTRCIOC端子にする
    //pml1= 0x40;

    //p34sel1= 0;// TRCIOC端子の選択
    //p34sel0= 1;// p3_4をTRCIOC端子にする

    p10sel1 = 0;// TRCIOD端子の選択
    p10sel0 = 1;// p1_0をTRCIOD端子にする
    //pml1=0x01;
    //p35sel1= 0;// TRCIOD端子の選択
    //p35sel0=1;// p3_5をTRCIOD端子にする

    //p37sel1= 0;// TRCIOD端子の選択
    //p37sel0= 1;// p3_7をTRCIOD端子にする

    pwm2_trcmr = 1;// pwmモード
    pwmb_trcmr = 1;//TRCIOB出力 PWN出力する
    pwmc_trcmr = 1;//TRCIOC出力 PWM出力する
    pwmd_trcmr = 1;//TRCIOD出力 PWM出力する

    trccr1 = 0x80;// カウントソース=f1

    trcgra = 20000-1;//PWM周期の設定 1/20MHz*20000=1ms
    trcgrb = 1000−1;//TRCIOB端子のON幅の設定 1000:0.05ms
    trcgrc = 2000−1;//TRCIOC端子のON幅の設定 2000:0.1ms
    trcgrd = 10000−1;// TRCIOD端子のON幅の設定10000:0.5ms

    eb_trcoer =0;//TRCIOBの出力許可レジスタを許可
    ec_trcoer =0;//TRCIOCの出力許可レジスタを許可
    ed_trcoer =0;//TRCIODの出力許可レジスタを許可
    cts_trcmr = 1;//TRCCNTカウント開始
  }



















実行画面
 TRCIOB、TRCIOC、TRCIODから指定した通りのH幅のパルスが出てい
るかどうかは、前節で使ったタイマRJ2の外部パルスカウントモードを使っ
て他の1台のR8C/M12Aに入力してLCDに表示させて確認しています。
下のLCD画面にはtrcgrd=10000 TRCIODのH幅0.5msを表示






プロジェクトファイルのダウンロード


メニューに戻る