タイマRB2

     T.タイマモード

     U.プログラマブル波形発生モード


T.タイマモード
 R8C/M12Aにはタイマ機能が備わっています。ここでは、タイマRB2を使ってみます。メニュー2でLEDを一定時間毎に点滅させるプログラムを作成しましたが、一定時間を作りりだす部分は、以下の部分です。while命令を使って、usecで指定した回数を空回りさせて時間を作り出しています。正確に時計で計っているわけではありません。いわば、見当をつけておよその時間を作り出しているだけです。それに比べR8C/M12Aのタイマモードは正確に時間を刻むことができます。ここでは、タイマRB2のタイマモードを使って一定時間毎に割り込みをかけるクロックカウントを作ってみます。

/* タイマ本体 us単位のwait関数*/
void wait_us(unsigned long usec) {
    usec = (usec * CLOCK) / 45000;
    while(usec --);{ }
}

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

 タイマRB2、タイマRJ2、タイマRC、A/Dコンバータ、UART0などの周辺機能は初期状態では全て無効になっています。有効にするためには、モジュールスタンバイ制御レジスタの関係するビットをあらかじめアクテイィブにしておかないと使用できません。
ビット シンボル ビット名 機能
  7      0に設定 
  6  MSTUART  UART0スタンバイビット  0:アクティブ
 1:スタンバイ
  5  MSTTRC  タイマRCスタンバイビット  0:アクティブ
 1:スタンバイ
  4  MSTAD  A/Dコンバータスタンバイビット  0:アクティブ
 1:スタンバイ
  3  0に設定
  2  0に設定
  1  MSTTRB  タイマRB2スタンバイビット  0:アクティブ
 1:スタンバイ
  0  MSTTRJ  タイマRJ2スタンバイビット  0;アクティブ
 1:スタンバイ

    タイマRB2スタンバイビットを有効にします。
    msttrb = 0;(または、mstcr=0x00;でも良い)

(2)タイマRB制御レジスタ(TRBCR)

ビット シンボル ビット名 機能
  7  −−−              
  6  −−−  
  5  −−−  
  4  −−−  
  3  −−−
  2  TSTOP  タイマRBカウンタ強制停止ビット  1を書くと、カウント強制停止。読んだ場合、その値は0
  1  TCSTF    タイマRBカウンタステータスフラグ  TRBMRレジスタのTMOD1ビットが0のとき
   0:カウント停止
   1:カウント中
 TRBMRレジスタのTMOD1ビットが1のとき
   0:カウント停止
   1:カウント許可状態
  0  TSTART    タイマRBカウンタ開始ビット  TRBMRレジスタのTMOD1ビットが0のとき
   0:カウント停止
   1:カウント開始
 TRBMRレジスタのTMOD1ビットが1のとき
   0:カウント停止
   1:カウント許可


(3)タイマRB I/O制御レジスタ(TRBIOC)
ビット シンボル ビット名 機能
  7  −−−             
  6  −−−  
  5  −−−  
  4  −−−  
  3  INOSEG  ワンショットトリガ極性選択ビット   0:立ち下がりエッジ
 1:立ち上がりエッジ 
  2  INOSTG  ワンショットトリガ制御ビット   0:INT0端子ワンショットトリガが無効
 1:INT0端子ワンショットトリガが有効 
  1  TCSTF    タイマRB出力切り換えビット  0:波形出力
 1:固定値出力
  0  TOPL    タイマRB出力レベル選択ビット  タイマRB出力レベル選択ビットの機能表
 









◎タイマRB出力レベル選択ビットの機能表
動 作 モ ー ド 機      能
 タイマモード  タイマモードでは0にする
 プログラマブル波形発生モード  0  プライマリ期間H出力
 セカンダリ期間L出力
 タイマ停止時L出力
 1  プライマリ期間L出力
 セカンダリ期間H出力
 タイマ停止時H出力 
 プログラマブルワンショット発生モード  0  ワンショットパルスH出力
 タイマ停止時L出力
 1  ワンショットパルスL出力
 タイマ停止時H出力 
 プログラマブルウエイトワンショット発生モード  0  ワンショットパルスH出力
 タイマ停止時およびウエイト期間にL出力
 1  ワンショットパルスL出力
 タイマ停止時およびウエイト期間にH出力 
タイマモードでは使用しません。初期値0のままです。次のプログラマブル波形発生モードで使用します。

(4)タイマRBモードレジスタ(TRBMR)
ビット シンボル ビット名 機能
  7  TCKCUT   タイマRBカウントソース遮断ビット  0:カウントソース供給
 1:カウントソース遮断
  6  TCK2    タイマRBカウントソース選択ビット   000:f1(20MHz)
 001:f8(2.5MHz)
 010:タイマRJ2のアンダーフロー
 011:f2(10MHz)
 100:f4(5MHz)
 101;f32(0.625MHz)
 110:f64(0.3125MHz)
 111:f128(0.15625MHz) 
  
  5  TCK1  
  4  TCK0  
  3  TWRC  タイマRB書き込み制御ビット  0に設定
  2  TCNT16  タイマRBカウンタ選択ビット TRBPRE、TRBPR、TRBSCを
 8ビットタイマとして使用するときは0に設定
16ビットタイマとして使用するときは1に設定
  1  TMOD1    タイマRB動作モード選択ビット   00:タイマモード
 01:プログラマブル波形発生モード
 10:プログラマブルワンショット発生モード
 11:プログラマブルウエィトワンショット発生モード 
  0  TMOD0  

今回は、タイマRB動作モード選択ビットはタイマモード(00)を選択、タイマRBカウントソース選択ビットは、011:はf2(10MHz)。つまり、1/10MHz毎(0.1μs)にタイマプリスケーラレジスタ(TRBPRE)に設定した値をカウントダウンしていく動作をします。タイマRBプリスケールレジスタ(TRBPRE)、タイマRBプライマリレジスタ(TRBPR)、タイマRBセカンダリレジスタ(TRBSC)を全て8ビットレジスタとして使うので、タイマRBカウント選択ビットを0に設定します。

    trbmr = 0x30;


(5)タイマRBプリスケーラレジスタ(TRBPRE)

 8ビットタイマーとして使う場合、設定値は0〜255の範囲になります。ここで設定した値を、タイマRBモードレジスタで設定したカントソースでカウントダウンしていきます。ここで例えば、trbpre=199 に設定した場合について考えてみます。カウントダウンはカウントソースf2(10MHz)の場合、0.1μs毎に

         199 → 198 → ・・・3 → 2 → 1 → 0 

となり、アンダーフローになる瞬間に199に更新されます。つまり、0.1μs X 200 = 20μSでカウントソースが200に更新されることになります。

    trbpre = 199;

(6)タイマRBプライマリレジスタ(TRBPR)

 タイマRBプリスケーラレジスタで設定したカウンタソース値のアンダーフローをカウントするレジスタです。設定値は0〜255の範囲です。
ここで例えば、

    タイマRBプリスケーラレジスタ trbpre=199
    タイマRBプライマリレジスタ   trbpr = 49 

に設定した場合、プリスケーラレジスタで設定したカウンタソース値のアンダーフローが発生する毎に

     49 → 48 → ・・・ 3 → 2 → 1 → 0

とカウントダウンされ、アンダーフローになる瞬間に49に更新されます。つまり、20μS X 50 =1mS毎に割り込みがかかることになります。 以上を整理すると、

    割り込み間隔 = タイマRBカウントソース X TRBPRE X TRBPR で計算されます。

今回は、1ms毎に割り込みをかける設定としますので、以下のような設定値にします。

    trbpr  = 49;


(7)タイマRB割り込み制御レジスタ(TRBIR) 

ビット シンボル ビット名 機能
  7   TRBIE   タイマRB割り込み許可ビット  0:割り込み禁止
 1;割り込み許可 
  6   TRBIF  タイマRB割り込み要求フラグ  0:割り込み要求なし
 1:割り込み要求あり
  5       
  4       
  3  
  2  
  1       
  0       
 
 タイマRBがアンダーフローしたときに割り込みを発生させるので、以下のような値になります。

    trbir = 0x80;

(8)割り込み優先レベルレジスタ(ILVLi)
 割り込み優先レベルレジスタILVLiは、i=0、2〜Eがあります。どの機能の割り込みを使うかによって、割り込み優先レベルレジスタが決まっています。タイマRBの割り込み優先レベルを設定するレジスタは、ILVLC です。割り込み機能は初期状態では全て割り込み禁止の状態です。タイマRBの割り込み優先レベルは1〜2の範囲で設定できます。複数の異なる機能の割り込みを使う場合、どの割り込みの方を優先するかで優先レベルを決める必要があります。1(高い)→2(低い)です。bit0、bit1で優先レベルを設定します。今回は、優先レベル1に設定します。

    00:割り込み禁止
    01:割り込み優先レベル1
    10:割り込み優先レベル2
    11:割り込み優先レベル2

    ilvlc = 0x01;


(9)プログラム

 次のプログラムは、LEDを点滅させるプログラムの時間稼ぎの部分をタイマRBを使って変更したものです。
  #include "sfr_r8m12a.h" /* R8C/M12A SFRの定義ファイル */
  unsigned long cnt_rb;

  void init(void);
  void timer(unsigned long timer_set);

  void main(void)
  {
    unsigned char d;
    init();

    while(1){
      p1=0x55;
      timer(1000);
      p1=0xff;
      timer(1000);
    }
  }

  /* 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 = 0xff;// ポートディレクションレジスタ1全て出力ポート設定
    p1 = 0x00;
    pd3 = 0x00;// ポートディレクションレジスタ3全て入力ポート設定
    /* タイマRBの設定 1ms毎に割り込み発生 */
    msttrb = 0; // タイマRBスタンバイビット タイマRBを有効
    trbmr = 0x30; // タイマRBモードレジスタ 動作モード 分周比設定
    trbpre = 200-1; // タイマRBプリスケーラレジスタ
    trbpr = 50-1; // タイマRBプライマリレジスタ
    trbir = 0x80; // タイマRB割り込み制御レジスタ 割り込み要求
    ilvlc = 0x01; // 割り込み優先レベル設定
    trbcr = 0x01; // タイマRB制御レジスタ TSTARTビットを1 カウント開始許可
    /* 割り込み許可 */
    asm(" fset I ");
  }

  void timer(unsigned long timer_set)
  {
    cnt_rb = 0;
    while(cnt_rb<timer_set);
  }

  /* 割り込みプログラム */
  #pragma interrupt intTRB(vect=24)
  void intTRB(void)
  {
    trbif_trbir = 0; // 割り込み制御レジスタの割り込み要求フラグをクリア
    cnt_rb ++;
  }

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




U.プログラマブル波形発生モード

 タイマRB2のプログラマブル波形発生モード使ってみます。ルネサスアプロケーションノート の例を参考にしています。プログラマブル波形発生モードは、任意のパルス幅のH出力(プライマリ期間)、L出力(セカンダリ期間)をTRBO端子(p1_3またはp4_2)から連続して出力します。

 関係するレジスタは、モジュールスタンバイ制御レジスタ(MSTCR)、タイマRB制御レジスタ(TRBCR)、タイマRB I/O制御レジスタ(TRBIOC)、タイマRBモードレジスタ(TRBMR)、タイマRBプリスケーラレジスタ(TRBPRE)、タイマRBプライマリレジスタ(TRBPR)、タイマRBセカンダリレジスタ(TRBSC)、タイマRB割り込み制御レジスタ(TRBIR)、割り込み優先レベルレジスタ(ILVLC)、の他に、ポート1機能マッピングレジスタがあります。(T)で説明済みのレジスタについては、設定値のみを下に記載します。

    mstrb      = 0;
    tstartt_trbcr = 0;
    trbcr       = 0x04;
    trbir        = 0x00;



    trbmr= 0x39;    タイマRBモードレジスタ 0011 1001に設定
                     カウントソースをf2(10MHz)に設定
                     プログラマブル波形発生モード

    trbioc= 0x00;    trbioc=0x01に設定すると、HとLの波形が反転します
 
    trbpre= 0xfa;    タイマRBプリスケーラレジスタ。
                     8ビットレジスタとして使っています。
                     プリスケーラ 0xfa(249)に設定する。trbpr、trbscに設定した値が
                     アンダーフローする毎にtrbpreが(249+1)=250回カウントダウンをする

    trbsc = 0x4f;    タイマRBセカンダリレジスタ。
                     8ビットレジスタとして使っています。
                     出力パルスのL出力の長さを指定するレジスタ。
                     セカンダリ間隔0x4f(79+1)、出力パルスのL出力の長さを、
                     250*80*1/10MHz=2msに初期設定

    trbpr = 0xc7;    タイマRBプライマリレジスタ。
                     8ビットレジスタとして使っています。
                     出力パルスのH出力の長さを指定するレジスタ。
                     プライマリ間隔0xc7(199+1) 出力パルスのH出力の長さを、
                     250*200*1/10MHz=5msに初期設定

    上記の、タイマRBセカンダリレジスタ(trbsc)、タイマRBプライマリレジスタ(trbpr)はこの順に設定する
    必要があります。また、これらのレジスタをプログラム実行中に可変させることによってH幅、L幅を可変
    させることができます。更新タイミング等は、マニアル表14.6「8ビットプリスケーラ付き8ビットタイマ時の
    TRBPR、TRBSCレジスタのリロードレジスタ更新タイミング」に詳しく書かれています。


    asm(”nop”);     安定するまで2サイクルの時間待ちをする
    asm(”nop”);     安定するまで2サイクルの時間待ちをする


    trbif_trbir=0;     割り込み要求フラグをクリャーする


    trbie_trbir=1;     割り込み許可


    pml1=0xc0;       ポート1機能マッピングレジスタ p1_3をTRBO端子に指定する。
    または p13sel0=1;
         p13sel1=1

    p4_2を出力端子にする場合は、
    pml4=0x10; 
    または、p42sel0=0;
         p42sel1=1;   に設定する。




◎プログラム
 
 p1_3から、初期設定値、H出力長さ5ms、L出力長さ2msのパルスを出力します。
 プログラムの中で、p1_7からボリュームの抵抗値を読み込みAD変換した値を使っ
 てtrbsc、trbprの値を変更してパルスのデューティー比を変更しています。AD変換
 値を確認するためにLCDに出力してオシロスコープに表示させています。LCDの表
 示に時間がかかるのでリアルタイムにはほど遠いのですが、実際のモータの回転ス
 ピードをデューティ比で制御するときにはLCDの表示はさせていません。


1)メイン関数

#include "sfr_r8m12a.h"
#include "i2clcd_ctrl.h"
#define CLOCK 20000

 void main(void)
 {
  int ad;
  unsigned char d;
  unsigned int i,j;
  unsigned int rd[4];
  unsigned char str0[8];
  unsigned char str1[8];

  init();
  I2C_LCD_init(); // LCD初期化
  I2C_SDA_OUT; // SDAピン出力に設定
  for(i=0;i<8;i++){
   str0[i] = ' ';
   str1[i] = ' ';
  }
  wait_ms(100);

  asm("FCLR I"); /* Interrupt disabled */
  timer_rb2_init(); /* Timer RB2 initialized */
  asm("FSET I"); /* Interrupt enabled */

  while(1){
   ad=Get_AD7()>>2; // ボリューム値PWM
   d=(unsigned char)ad/2;// 0〜127
   trbsc = 0xc7-d; // 8ビットタイマ:secondary period 5ms〜2ms
   asm("nop");  // wait for at least two cycles
   asm("nop");  // wait for at least two cycles
   trbpr = 0x4f+d;// 8ビットタイマ:primary period 2ms〜5ms
   asm("nop");  // wait for at least two cycles
   asm("nop");  // wait for at least two cycles
   /* LCDに表示する */
   for(i=0;i<4;i++){ // 0〜255を各桁に分解する
    rd[i] = d%10;
    d = d/10;
   }
   str1[0]='A';str1[1]='M';str1[2]='P';str1[3]='=';
   str1[7]=rd[0]+0x30;
   str1[6]=rd[1]+0x30;
   str1[5]=rd[2]+0x30;
   str1[4]=rd[3]+0x30;
   I2C_SDA_OUT; // SDAピン出力に設定
   I2C_LCD_cursor(1,0); // 1行目0より表示
   I2C_LCD_str(str0); // 表示文字列出力
   wait_ms(1000);
   I2C_LCD_cursor(2,0); // 2行目0より表示
   I2C_LCD_str(str1);
   wait_ms(100);
  }
 }

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

 /* RB2初期化 */
 void timer_rb2_init(void)
 {
  msttrb = 0; // msttrb=0タイマRBスタンバイビット タイマRBを有効
  tstart_trbcr=0; // タイマRBカウント停止
  while(tcstf_trbcr==1);// timer RB count stop waiting
  tstop_trbcr = 1; // タイマRB制御レジスタ:レジスタ,カウンタ初期化
  trbir = 0x00; // タイマRB割り込み制御レジスタ 割り込み禁止
  trbmr = 0x31; // タイマRBモードレジスタ:プログラマブル波形発生モード01:f1 31:f2 0011 0001
  trbioc = 0x00; // タイマRB I/O 制御レジスタ

  /* 8ビットタイマ時の設定 */
  trbpre= 0xf9; // 8ビットタイマ:prescaler 0xf9:249
  trbsc = 0xc7; // 8ビットタイマ:secondary period c7:1/10MHz * 250 * 200=5ms
  asm("nop"); // wait for at least two cycles
  asm("nop"); // wait for at least two cycles
  trbpr = 0x4f; // 8ビットタイマ:primary period 4f: 1/10MHz * 250 * 80 =2ms
  asm("nop"); // wait for at least two cycles
  asm("nop"); // wait for at least two cycles
  trbif_trbir=0; // タイマRB割り込み要求フラグ clear
  trbie_trbir=1; // タイマRB割り込み許可
  ilvlc = 0x01; // 割り込み優先レベル設定 Level=1
  pml1 = 0xc0; // ポート1機能マッピングレジスタ P1_3:TRBO
  tstart_trbcr=1; // タイマRBカウントstart
  while(tcstf_trbcr == 0);// タイマRB count start waiting
 }
 #pragma interrupt _timer_rb2(vect=24)
 void _timer_rb2(void)
 {
  trbif_trbir = 0; /* interrupt request flag clear */
 }



2)LCDコントロール関数 i2clcd_ctrl.c

 /* インクルード */
 #include "sfr_r8m12a.h" /* R8C/M12A SFRの定義ファイル */
 #include "i2clcd_ctrl.h"

 /* 液晶初期化関数 */
 void I2C_LCD_init(void)
 {
  wait_ms(100);
  I2C_LCD_cmd(0x38); // Function set 8bit 21Line Normal mode
  wait_us(30);
  I2C_LCD_cmd(0x39); // Function set 8bit 21Line Extended mode
  wait_us(30);
  I2C_LCD_cmd(0x14); // Internal OSC Frequency 183Hz BIAS 1/5
  wait_us(30);
  I2C_LCD_cmd(0x35); // Contrast set 0x70:2.7V 〜 0x30:3.0v 0x35
  wait_us(30);
  I2C_LCD_cmd(0x56); // Power Icon Contrast control
  wait_us(30);
  I2C_LCD_cmd(0x6c); // Follow control 3.3v
  wait_ms(400);
  I2C_LCD_cmd(0x38); // Set normal mode
  wait_us(30);
  I2C_LCD_cmd(0x0c); // Display ON
  wait_us(30);
  I2C_LCD_cmd(0x01); // Clear Display
  wait_ms(10);
 }

 /* 開始条件 */
 void I2C_start(void)
 {
  I2C_SDA_OUT;
  I2C_H_CLK();
  I2C_S_SDA;
  delay();
  I2C_C_SDA;
  delay();
  I2C_L_CLK();
  delay();
 }
 /* 終了条件 */
 void I2C_stop(void)
 {
  I2C_SDA_OUT;
  I2C_L_CLK();
  I2C_C_SDA;
  delay();
  I2C_H_CLK();
  delay();
  I2C_S_SDA;
  delay();
 }
 /* クロックをHighにする */
 void I2C_H_CLK(void)
 {
  I2C_S_SCL;
  delay();
 }
 /* クロックをLowにする */
 void I2C_L_CLK(void)
 {
  I2C_C_SCL;
  delay();
 }
 /* ACKNOWLEDGE */
 void ack(void)
 {
  I2C_SDA_IN;
  I2C_S_SCL;
  delay();
  I2C_C_SCL;
  delay();
  I2C_SDA_OUT;
 }
 /* 書き込みの基本関数 */
 /* 引数 data 8ビットデータ */
 /* 戻り値 ack */
 int I2C_write(unsigned char data)
 {
  int i;
  int ack;
  I2C_SDA_OUT;
  for(i=0;i<8;i++){ // 1ビト毎にクロックと共に送信
   if(data & 0x80){
    I2C_S_SDA;
   }
   else{
    I2C_C_SDA;
   }
   delay();
   I2C_H_CLK();
   I2C_L_CLK();
   data<<=1;
  }
  I2C_SDA_IN;
  I2C_H_CLK();
  I2C_L_CLK();
  ack=I2C_SDA_data;
  I2C_SDA_OUT;
  delay();
  return ack;
 }
 /* 読み込み基本関数 */
 /* 引数 なし */
 /* 戻り値 読み込んだ8ビットデータ */
 static unsigned char I2C_read(void)
 {
  int i;
  unsigned char data;

  data=0;
  I2C_SDA_IN;
  for(i=0;i<8;i++){
   data<<=1;
   I2C_S_SCL;
   delay();
   data |=(I2C_SDA_data);
   I2C_C_SCL;
   delay();
  }
  I2C_S_SCL;
  delay();
  I2C_S_SDA;
  delay();
  I2C_C_SDA;
  delay();
  I2C_C_SCL;
  delay();
  return data;
 }
 /* 液晶へのコマンド出力関数 */
 void I2C_LCD_cmd(unsigned char cmd)
 {
  I2C_start(); // スタートコンディ゙ション
  I2C_write(ADD); // アドレス指定
  // C0+RS+000000 C0=1:連続で通信可 C0=0:stopコンディションで終了
  // RS=0:次のバイトでコントロールコード送信可能
  // I2C_write(0x80); // 次はコマンド出力を指定 連続
  I2C_write(0x00); // 次はコマンド出力を指定 連続ではない
  I2C_write(cmd); // コマンド送信出力
  I2C_stop(); // ストップコンディション
  wait_us(50);
  // delay();
 }
 /* 液晶への1文字出力関数 */
 void I2C_LCD_data(unsigned char data)
 {
  I2C_start(); // スタートコンディ゙ション
  I2C_write(ADD); // アドレス指定
  // C0+RS+000000 C0=1:連続で通信可 C0=0:stopコンディションで終了
  // RS=1:次のバイトでデータ出力を指定
  // I2C_write(0xc0); // 次はデータ出力を指定 連続
  I2C_write(0x40); // 次はデータ出力を指定 連続ではない
  I2C_write(data); // 1文字データ出力
  I2C_stop(); // ストップコンディション
  wait_us(50);
  // delay();
 }
 /* 液晶への文字列表示関数 */
 void I2C_LCD_str(char* ptr)
 {
  while(*ptr !=0){
   I2C_LCD_data(*ptr++);
  }
 }
 /* 液晶画面のクリャー関数 */
 void I2C_LCD_clear(void)
 {
  I2C_LCD_cmd(0x01);
 }
 /* 液晶のカーソル位置設定関数 */
 void I2C_LCD_cursor(unsigned char line,unsigned char cursor)
 {
  if(line == 1){
   I2C_LCD_cmd(0x80 | cursor);
  }
  else{
   I2C_LCD_cmd(0xc0 | cursor);
  }
 }
 /* タイマ本体 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);
  }
 }
 /* 6usの遅れ関数 */
 void delay(void)
 {
  unsigned char i;
  for(i=0;i<5;i++){}
 }
 /* AN7端子AD変換関数 */
 int Get_AD7(void)
 {
  int data;
  p17sel0 = 0;// ポート1機能マッピングレジスタ1 AN7入力
  p17sel1 = 0;
  mstad = 0; // モジュールスタンバイ制御レジスタをアクティブ
  mstcr = 0x00;// モジュールスタンバイ制御レジスタをアクティブ
  admod = 0x03;// A/D動作 0x0b:繰り返しモード 0x03:単発モード f1(20MHz)
  adinsel = 0x81;// A/D入選択レジスタ AN7
  adcon0 = 0x01;// AD変換スタート
  while(adcon0 && 0x01); // A/D変換終了待ち(単発モード)
  data = ad1;
  return data;
 }

3)ヘッダーファイル i2clcd_ctrl.h
 #define I2C_S_SCL p1_1=1 // I2Cクロック p1_1を1にする
 #define I2C_C_SCL p1_1=0 // I2Cクロック p1_1を0にする
 #define I2C_S_SDA p1_0=1 // I2Cデータ p1_0を1にする
 #define I2C_C_SDA p1_0=0 // I2Cデータ p1_0を0にする
 #define I2C_SDA_IN pd1_0=0 // p1_0を入力ポートに設定
 #define I2C_SDA_OUT pd1_0=1 // p1_0を出力ポートに設定
 #define I2C_SDA_data p1_0 // データポートをp1_0に設定
 #define ADD 0x7c // アドレス 0B 0111 110+0(c/w)
 #define CLOCK 20000
 /* プロトタイプ宣言 */
 void init(void);
 void I2C_LCD_init(void);
 void timer_rb2_init(void); /* Initial setting of Timer RB2 SFR */
 void _timer_rb2(void); /* Timer RB2 interrupt processing */
 void wait_us(unsigned long usec);// us単位のタイマ
 void wait_ms(unsigned long msec);// ms単位のタイマ
 void delay(void);// 6usの遅延関数
 int Get_AD7(void);
 void I2C_start(void);// I2C開始
 void I2C_stop(void);// I2Cストップ
 void ack(void);// ACKNOWLEDGE信号受信
 void I2C_H_CLK(void);// クロックHigh
 void I2C_L_CLK(void);// クロックLow
 void I2C_LCD_init(void);// lcd初期化関数
 int I2C_write(unsigned char data);// 書き込みの基本関数
 static unsigned char I2C_read(void);// 読み込みの基本関数
 void I2C_LCD_cmd(unsigned char cmd);// 液晶へのコマンド出力関数
 void I2C_LCD_data(unsigned char data);// 液晶への1文字出力関数
 void I2C_LCD_str(char* ptr);// 液晶への文字列表示関数
 void I2C_LCD_clear(void);// 液晶のクリャー関数

 // カーソル位置設定関数 line(行数):1 or 2 cursor(左端からの位置):0〜f
 void I2C_LCD_cursor(unsigned char line,unsigned char cursor);

    LCDにボリュームのAD変換値を表示している

         オシロスコープ 5msと2ms

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



メニューに戻る