goo blog サービス終了のお知らせ 

忘備録-備忘録

技術的な備忘録

RX210でPWM波形を出力する

2016-09-29 17:59:54 | RX210
ルネサスエレクトロニクス社のマイコンRX210を使用してPWM波形を出力するサンプルです。MTU3を使用してMTIOC3AとMTIOC3Cから信号を出力します。HighになるタイミングとLowになるタイミングをMTIOC3AではTGRA,TGRBで決め、MTIOC3CはTGRC,TGRDで決めます。このサンプルでは、カウンタのクリアはTGRBで行っています。

  1. #include "iodefine.h"
  2. #include <machine.h>
  3. #define PCLK 125 // 周辺機器のクロック設定 125kHz
  4. /*
  5. タイマの設定 MTU3
  6. */
  7. void initMTU3pwm(void)
  8. {
  9.     SYSTEM.PRCR.WORD = 0x0A502;
  10.     MSTP(MTU3) = 0; //MTU3 モジュールスタンバイ解除
  11.     SYSTEM.PRCR.WORD = 0x0A500;
  12. /* 端子の設定 */
  13.     PORTC.PODR.BIT.B7 = 0;        // PC7 MTIOC3A 出力初期値
  14.     PORTC.PDR.BIT.B7 = 1;        // PC7 出力設定
  15.     PORTC.PMR.BIT.B7 = 0;        // PC7ポートとして使用
  16.     PORTC.PODR.BIT.B6 = 0;        // PC6 MTIOC3A 出力初期値
  17.     PORTC.PDR.BIT.B6 = 1;        // PC6 出力設定
  18.     PORTC.PMR.BIT.B6 = 0;        // PC6ポートとして使用
  19.     MPC.PWPR.BIT.B0WI = 0;        // PFSWE書き込み可
  20.     MPC.PWPR.BIT.PFSWE = 1;        // PFSレジスタへの書き込み可
  21.     MPC.PC7PFS.BIT.PSEL = 1;    // PC7をMTIOC3Aとして使用
  22.     MPC.PC6PFS.BIT.PSEL = 1;    // PC6をMTIOC3Cとして使用
  23.     MPC.PWPR.BIT.PFSWE = 0;        // PFSレジスタへの書き込み禁止
  24.     PORTC.PMR.BIT.B7 = 1;        // PC7周辺機器として使用
  25.     PORTC.PMR.BIT.B6 = 1;        // PC6周辺機器として使用
  26. /* MTUタイマの設定 */
  27.     MTU.TSTR.BIT.CST3 = 0x00;    //MTUカウント停止
  28.     MTU3.TCR.BIT.TPSC = 0x00;    // CLK PCLK/1 でカウント
  29.     MTU3.TCR.BIT.CCLR = 0x02;    //TCNT3はTGRBのコンペアマッチでクリア
  30.     MTU3.TMDR.BIT.MD = 0x02;    //タイマーPWMモード1
  31.     // 出力波形の設定
  32.     MTU3.TIORH.BIT.IOA = 0x05;    // MTIOC3A 初期出力はHigh出力コンペアマッチでLow出力
  33.     MTU3.TIORH.BIT.IOB = 0x06;    // MTIOC3B 初期出力はHigh出力コンペアマッチでHigh出力
  34.     MTU3.TIORL.BIT.IOC = 0x05;    // MTIOC3C 初期出力はHigh出力コンペアマッチでLow出力
  35.     MTU3.TIORL.BIT.IOD = 0x06;    // MTIOC3D 初期出力はHigh出力コンペアマッチでHigh出力
  36.     MTU3.TGRA = 0;                // MTIOC3Aデューティー比
  37.     MTU3.TGRB = 256;            // MTU3 周波数
  38.     MTU3.TGRC = 0;                // MTIOC3Cデューティー比
  39.     MTU3.TGRD = 256;            // MTU3 周波数 MTU3.TGRBと同じ値に
  40.     MTU3.TCNT = 0;                //カウンタクリア
  41.     MTU.TSTR.BIT.CST3 = 0x01;    //タイマ動作
  42. }
  43. void main(void)
  44. {
  45.     initMTU3pwm();
  46.     MTU3.TGRA = 5;        //LED D8の明るさ 0〜255
  47.     MTU3.TGRC = 254;    //LED D7の明るさ 0〜255
  48.     while(1) {
  49. /* ハードウェアで波形出力するのでプログラムでは何もしなくてもよい */
  50.     }
  51. }

RX210でIRQ割り込みを使う

2016-05-06 18:48:31 | RX210
RX210でIRQ割り込みを使用したプログラムの例です。
RX210は割り込み端子にデジタルフィルタがあるのでスイッチを直接接続してもチャタリングに悩まされることがありません。

  1. void main(void)
  2. {
  3.     int i;
  4.     int up4bit,lower4bit;
  5.     unsigned char num = 0;
  6.     PORTA.PDR.BYTE = 0xFF;    //ポートAを出力に
  7.     PORTB.PDR.BYTE = 0xFF;    //ポートBを出力に
  8.     PORTC.PDR.BYTE = 0xFF;    //ポートCを出力に
  9.     PORTC.PODR.BYTE = 0x00;    //LEDを消灯
  10.     //MTSP(ICU) = 0;
  11.     IEN(ICU,IRQ0) = 0;                //IRQ0禁止
  12.     IPR(ICU,IRQ0) = 0x0F;            //割り込み優先順位を最大に設定
  13.     ICU.IRQFLTE0.BIT.FLTEN0 = 0;    //デジタルフィルタ禁止
  14.     ICU.IRQFLTC0.BIT.FCLKSEL0 = 3;    //デジタルフィルタ PCLK/64
  15.     PORTH.PDR.BIT.B1 = 0;            //PH1入力
  16.     MPC.PWPR.BIT.B0WI = 0;            // PFSWE書き込み可
  17.     MPC.PWPR.BIT.PFSWE = 1;            // PFSレジスタへの書き込み可
  18.     MPC.PH1PFS.BIT.ISEL = 1;        //PH1をIRQ0として使用
  19.     MPC.PWPR.BIT.PFSWE = 0;            // PFSレジスタへの書き込み禁止
  20.     PORTH.PMR.BIT.B1 = 1;            //PH1内蔵機能に使用
  21.     ICU.IRQCR[0].BIT.IRQMD = 1;        //立ち下がりエッジ
  22.     IR(ICU,IRQ0) = 0;                //フラグを下げる
  23.     ICU.IRQFLTE0.BIT.FLTEN0 = 1;    //デジタルフィルタ許可
  24.     IEN(ICU,IRQ0) = 1;                //IRQ0許可
  25. //    set_ipl(2);
  26.     setpsw_i();                            // 割込み許可 割込み禁止はclrpsw_i()
  27.     while(1) {
  28.         up4bit = num >> 4;        //上位4bitの計算
  29.         lower4bit = num & 0x0F;    //下位4bitの計算
  30.         PORTB.PODR.BYTE = seg7pat[ up4bit ] | 0x80; // <--上位4bit パターンで数字を表示できるように
  31.         PORTA.PODR.BYTE = seg7pat[ lower4bit ]; // <--下位4bit パターンで数字を表示できるように
  32.         num++;    //カウントアップ unsigned char形なので255を過ぎると0に戻る
  33.         //if(num >99) num =0;
  34.         for(i=0;i<50000;i++) { //一定時間待つ
  35.             nop(); //何もしない
  36.         }
  37.     }
  38. }

割り込みプログラムは

  1. // ICU IRQ0
  2. void Excep_ICU_IRQ0(void)
  3. {
  4.     PORTC.PODR.BYTE = ~ PORTC.PODR.BYTE;
  5. }

RX210のリアルタイムクロック機能を使う

2016-02-15 18:01:40 | RX210
RX210のRTC機能を使えるようにプログラムしてみました。時刻と日付はGPSより取得するようにしました。

  1. /*
  2.  * RX Family RTC Module Using Firmware Integrated Technology
  3.  * http://japan.renesas.com/support/downloads/download_results/C1000000-C9999999/mpumcu/rx/an_r01an1817eu_rx_rtc.jsp
  4.  */
  5.                                                                            
  6. #include <stdio.h>
  7. #include <machine.h>
  8. #include "iodefine.h"
  9. #include <string.h>
  10. #include "gps.h"
  11. /*
  12.  * RTCの初期化
  13.  */
  14. void initRTC(void)
  15. {
  16.     /* Set subclock drive capacity */
  17.     RTC.RCR3.BIT.RTCDV = 0x06;    //標準CL用ドライブ能力
  18.     while(RTC.RCR3.BIT.RTCDV != 0x06); //Confirm that it has changed, it's slow.
  19.     /* Enable the subclock for RTC */
  20.     RTC.RCR3.BIT.RTCEN = 1; // enable subclock
  21.     while(RTC.RCR3.BIT.RTCEN != 1);
  22.     /* Disable RTC interrupts */
  23.     RTC.RCR1.BYTE = 0x00u;
  24.     /* Stop RTC counter */
  25.     RTC.RCR2.BIT.START = 0;
  26.     while(RTC.RCR2.BIT.RESET != 0) ;
  27.     /*RCR2レジスタのb7を“0”にする*/
  28.     RTC.RCR2.BYTE &= 0x7F;
  29.     /* RTCは24時間モードで動作 */
  30.     RTC.RCR2.BIT.HR24 = 1;
  31.     /* Clear alarms, capture regs, adjustment regs, and output enable */
  32.     RTC.RCR2.BIT.RESET = 1;
  33.     /* Wait for reset to happen before continuing.*/
  34.     while(RTC.RCR2.BIT.RESET != 0) ;
  35.     /* Insure ICU RTC interrupts disabled */
  36.     IEN(RTC,PRD) = 0;
  37.     IEN(RTC,ALM) = 0;
  38.     IEN(RTC,CUP) = 0;
  39.     /* Enable RTC interrupts (PIE, CIE and AIE), not ICU yet */
  40.     RTC.RCR1.BYTE = 0x07u;
  41.     while (RTC.RCR1.BYTE != 0x07u) ;
  42. }
  43. /*
  44.  * BCDコードへの変換
  45.  */
  46. unsigned char dec2bcd(unsigned char data)
  47. {
  48.     unsigned char ans = 0;
  49.     ans = ((data / 10) & 0x0F) << 4 | ((data % 10) & 0x0F);
  50.     return ans;
  51. }
  52. /*
  53.  * BINコードへの変換
  54.  */
  55. unsigned char bcd2dec(unsigned char data)
  56. {
  57.     unsigned char ans = 0;
  58.     ans = ((data >> 4) & 0x0F) * 10 + (data & 0x0F);
  59.     return ans;
  60. }
  61. /*
  62.  * 曜日の計算
  63.  */
  64. int Zeller(int y,int mo, int d)
  65. {
  66.     int C,Y,G;
  67.     C=y/100;
  68.     Y= y % 100;
  69.     G=5*C+C/4;
  70.     return (d+((26*(mo+1))/10)+Y+Y/4+G + 6) % 7;
  71. }
  72. /*
  73.  * RTCへの時間の設定
  74.  */
  75. void RTCsetTime (int *y,int *mo,int *d,int *w,int *h,int *m,int *s)
  76. {
  77.     /* Stop RTC counter */
  78.     RTC.RCR2.BIT.START = 0;
  79.     while(RTC.RCR2.BIT.START != 0);
  80.     /* Set time */
  81.     /* Set seconds. (0-59) */
  82.     RTC.RSECCNT.BYTE = dec2bcd(*s);
  83.     /* Set minutes (0-59) */
  84.     RTC.RMINCNT.BYTE = dec2bcd(*m);
  85.     /* Set hours. (0-23) */
  86.     RTC.RHRCNT.BYTE = dec2bcd(*h);
  87.     /* Set the date */
  88.     /* Day of the week (0-6, 0=Sunday) */
  89.     RTC.RWKCNT.BYTE = dec2bcd(*w);
  90.     /* Day of the month (1-31) */
  91.     RTC.RDAYCNT.BYTE = dec2bcd(*d);
  92.     /* Month. (1-12, 1=January) */
  93.     RTC.RMONCNT.BYTE = dec2bcd(*mo);
  94.     /* Year. (00-99) */
  95.     RTC.RYRCNT.WORD = (unsigned short)(dec2bcd(*y));
  96.     /* start RTC counter */
  97.     RTC.RCR2.BIT.START = 1;
  98.     while(RTC.RCR2.BIT.START != 1);
  99. }
  100. /*
  101.  * RTCのデータを読み出す
  102.  */
  103. void RTCread(int *y,int *mo,int *d,int *w,int *h,int *m,int *s)
  104. {
  105.     unsigned short bcd_years; // Used for converting year.
  106.     do
  107.     {
  108.         /* Clear carry flag in ICU */
  109.     IR(RTC,CUP) = 0;
  110.         /* Read and convert RTC registers; mask off unknown bits and hour am/pm. */
  111.         /* Seconds. (0-59) */
  112.         *s = bcd2dec((RTC.RSECCNT.BYTE & 0x7fu));
  113.         /* Minutes. (0-59) */
  114.         *m = bcd2dec((RTC.RMINCNT.BYTE & 0x7fu));
  115.         /* Hours. (0-23) */
  116.         *h = bcd2dec((RTC.RHRCNT.BYTE & 0x3fu));
  117.         /* Day of the month (1-31) */
  118.         *d = bcd2dec(RTC.RDAYCNT.BYTE);
  119.         /* Months since January (0-11) */
  120.         *mo = bcd2dec(RTC.RMONCNT.BYTE);
  121.         /* Years since 2000 */
  122.         bcd_years = (unsigned short)RTC.RYRCNT.WORD;
  123.         /* years years since 1900 */
  124.         *y = bcd2dec((bcd_years & 0xFF));
  125.         /* Days since Sunday (0-6) */
  126.         *w = RTC.RWKCNT.BYTE & 0x07u;
  127.     }
  128.     while (IR(RTC,CUP) == 1); //Reread if carry occurs during read
  129. }
  130. void main(void)
  131. {
  132.     int h,m,s,d,mo,y,w,flag=0;
  133.     volatile unsigned int i;
  134.     change_oscillation_PLL();            //クロックソースPLL
  135.     SCI6_Init (9600);                    // SCI6-->GPSユニット
  136.     initRTC();
  137.     setpsw_i();                            // 割込み許可 clrpsw_i()割込み禁止
  138.     printf("\nhello world!\n");
  139.     while(flag==0) {
  140.         if(getJST(&y,&mo,&d,&h,&m,&s)) {
  141.             printf("\n\n\n\ny=%d m=%d d=%d h=%d m=%d s=%d\n",y,mo,d,h,m,s);
  142.             w = Zeller(y,mo,d);
  143.             RTCsetTime (&y,&mo,&d,&w,&h,&m,&s);
  144.             flag =1;
  145.         }
  146.     }
  147.     while(1) {
  148.         RTCread(&y,&mo,&d,&w,&h,&m,&s);
  149.         printf("y=%d m=%d d=%d h=%d m=%d s=%d w=%d\n",y,mo,d,h,m,s,w);
  150.         for(i=0;i<9000000;i++)nop();
  151.     }
  152.             //printf("> %s\n",buf);
  153. }

e2 studioのデバック仮想コンソールを使う

2016-02-01 18:00:16 | RX210
RXシリーズにはE1デバッガ経由でデータを交換できる機能があるようです。この機能を使ってprintf(),scanf()などの標準入出力を動作させることができます。
e2 studio上で[Renesas デバッグ仮想コンソール]をクリックするとコンソールが開きターゲットと通信できます。


ターゲット側にも仕掛けが必要です。次のファイルをルネサスエレクトロニクス社のサンプルプログラムから手に入れます。ファイルが入っているのは「RX ファミリ ボードサポートパッケージモジュール Firmware Integration Technology」です。
  • lowlvl.c
  • lowsrc.c

各ファイは少し書き直さないとビルドできません。
lowlvl.c抜粋
/***********************************************************************************************************************
Includes   <System Includes> , "Project Includes"
***********************************************************************************************************************/
/* r_bsp access. */
//#include "platform.h" コメントアウト

typedef unsigned int uint32_t; //追加

/***********************************************************************************************************************
Macro definitions
***********************************************************************************************************************/
#define E1_DBG_PORT (*(volatile struct st_dbg     __evenaccess *)0x84080)
#define TXFL0EN     0x00000100          // debug tx flow control bit
#define RXFL0EN     0x00001000          // debug RX flow control bit

lowsrc.c抜粋
/***********************************************************************************************************************
Includes   <System Includes> , "Project Includes"
***********************************************************************************************************************/
//#include "r_bsp_config.h"   コメントアウト
#define BSP_CFG_IO_LIB_ENABLE 1 //追加
/* Do not include this file if stdio is disabled in r_bsp_config. */
#if (BSP_CFG_IO_LIB_ENABLE == 1)

reset_program.c抜粋
       略	(下の行のコメントを外す)
#ifdef __cplusplus				// Use SIM I/O
extern "C" {
#endif
extern void _INIT_IOLIB(void);
//extern void _CLOSEALL(void);
#ifdef __cplusplus
}
#endif
       略
	_INITSCT();

	_INIT_IOLIB();			// Use SIM I/O コメントを外す

//	errno=0;			// Remove the comment when you use errno
//	srand((_UINT)1);		// Remove the comment when you use rand()
       略

RX210でi2cを使う

2016-01-15 13:02:55 | RX210
ルネサスエレクトロニクス社製のマイコンRX210を使用してI2C通信を行うプログラムのサンプルです。

  1. #include "iodefine.h"
  2. #include <stdio.h>
  3. #include <machine.h>
  4. #include "rs232c.h"
  5. /*
  6.    Interface 2011年6月号を参考にして作成したIIC通信プログラム
  7.      割込みを使用しない
  8. */
  9. /*
  10.    RIICの初期化
  11.    引数  無し
  12.    戻り値 無し
  13. */
  14. void initRIIC0(void)
  15. {
  16.     SYSTEM.PRCR.WORD = 0xA502;    /* Enables writing to the registers */
  17.     MSTP(RIIC0) = 0;            // モジュールスタンバイ解除
  18.     SYSTEM.PRCR.WORD = 0xA500;    /* Disables writing to the registers */
  19.     /* Set the pins */
  20.     PORT1.PDR.BIT.B2 = 0; /* SCL: input */
  21.     PORT1.PDR.BIT.B3 = 0; /* SDA: input */
  22.     PORT1.PMR.BIT.B2 = 0; /* SCL: general I/O port */
  23.     PORT1.PMR.BIT.B3 = 0; /* SDA: general I/O port */
  24.     MPC.PWPR.BIT.B0WI = 0; /* Writing to the PFSWE bit is enabled */
  25.     MPC.PWPR.BIT.PFSWE = 1; /* Writing to the PFS register is enabled */
  26.     MPC.P12PFS.BIT.PSEL = 0x0F; /* SCL */
  27.     MPC.P13PFS.BIT.PSEL = 0x0F; /* SDA */
  28.     MPC.PWPR.BIT.PFSWE = 0; /* Writing to the PFS register is disabled */
  29.     MPC.PWPR.BIT.B0WI = 1; /* Writing to the PFSWE bit is disabled */
  30.     /* Set the pins */
  31.     PORT1.PMR.BIT.B2 = 1; /* SCL: peripheral function */
  32.     PORT1.PMR.BIT.B3 = 1; /* SDA: peripheral function */
  33.     /* RIIC disable for RIIC initial */
  34.     RIIC0.ICCR1.BIT.ICE = 0;
  35.     while(RIIC0.ICCR1.BIT.ICE != 0); /* Confirm that the ICCR1.ICE bit is 0 */
  36.     RIIC0.ICCR1.BIT.IICRST = 1;            /* RIICリセット */
  37.     RIIC0.ICCR1.BIT.ICE = 1;            /* 内部リセット */
  38.     /* Set transfer bit rate : 100kbps (PCLK = 25MHz) */
  39.     RIIC0.ICMR1.BIT.CKS = 2; /* Internal Reference Clock: PCLK/4 clock */
  40.     RIIC0.ICBRH.BIT.BRH = 24; /* Set the High-level period of SCL clock */
  41.     RIIC0.ICBRL.BIT.BRL = 29; /* Set the Low-level period of SCL clock */
  42.     /* disable all address detection. Master mode only. */
  43.     RIIC0.ICSER.BYTE = 0x00;
  44.     /* ACKWP is protect bit for ACKBT */
  45.     RIIC0.ICMR3.BIT.ACKWP = 1;        /* disable protect for ACKBT */
  46.     RIIC0.ICCR1.BIT.IICRST = 0;        /* 内部リセット解除 */
  47. }
  48. /*
  49.    バスフリーの確認
  50.    引数  無し
  51.    戻り値 無し
  52. */
  53. inline void i2cBusFree(void)
  54. {
  55.     while(RIIC0.ICCR2.BIT.BBSY == 1);
  56. }
  57. /*
  58.    バス・スタートを実行
  59.    引数  無し
  60.    戻り値 無し
  61. */
  62. inline void i2cStart(void)
  63. {
  64.     RIIC0.ICCR2.BIT.ST = 1;
  65.     while(RIIC0.ICSR2.BIT.START != 1);
  66.     RIIC0.ICSR2.BIT.START = 0;
  67. }
  68. /*
  69.    バスがBusy中にバス・スタート
  70.    引数  無し
  71.    戻り値 無し
  72. */
  73. inline void i2cReStart(void)
  74. {
  75.     RIIC0.ICCR2.BIT.RS = 1;
  76.     while(RIIC0.ICSR2.BIT.START != 1);
  77.     RIIC0.ICSR2.BIT.START = 0;
  78. }
  79. /*
  80.    バス・ストップを実行
  81.    引数  無し
  82.    戻り値 無し
  83. */
  84. inline void i2cStop(void)
  85. {
  86.     RIIC0.ICSR2.BIT.STOP = 0;
  87.     RIIC0.ICCR2.BIT.SP = 1;
  88.     while(RIIC0.ICSR2.BIT.STOP != 1);
  89.     RIIC0.ICSR2.BIT.STOP = 0;
  90.     RIIC0.ICSR2.BIT.NACKF = 0;
  91. }
  92. /*
  93.    デバイスに1byteデータ転送
  94.    引数  送信データ
  95.    戻り値 無し
  96. */
  97. inline void i2cSendByte(unsigned char data)
  98. {
  99.     while(RIIC0.ICSR2.BIT.TDRE != 1);
  100.     RIIC0.ICDRT = data;
  101. }
  102. /*
  103.    データの転送完了を確認
  104.    引数  無し
  105.    戻り値 無し
  106. */
  107. inline void i2cCheckTEND(void)
  108. {
  109.     while(RIIC0.ICSR2.BIT.TEND != 1);
  110. }
  111. /*
  112.    デバイスから1byte読み取りバスストップを実行
  113.    引数   無し
  114.    戻り値  デバイスから読み取ったデータ
  115. */
  116. unsigned char i2cReceiveByteStop(void)
  117. {
  118.     unsigned char rdt;
  119.     while(RIIC0.ICSR2.BIT.RDRF != 1);
  120.     RIIC0.ICMR3.BIT.WAIT = 1;
  121.     RIIC0.ICMR3.BIT.ACKBT = 1;
  122.     rdt = RIIC0.ICDRR;                //dummy read
  123.     while(RIIC0.ICSR2.BIT.RDRF != 1);
  124.     RIIC0.ICSR2.BIT.STOP = 0;
  125.     RIIC0.ICCR2.BIT.SP = 1;            //stop
  126.     rdt = RIIC0.ICDRR;                //data read
  127.     RIIC0.ICMR3.BIT.WAIT = 0;
  128.     while(RIIC0.ICSR2.BIT.STOP != 1);
  129.     RIIC0.ICSR2.BIT.STOP = 0;
  130.     RIIC0.ICSR2.BIT.NACKF = 0;
  131.     return rdt;
  132. }
  133. /*
  134.    スレーブ・アドレスを指定してデバイスのレジスタ・メモリにデータを書き込む
  135.    引数   sadr : スレーブ・アドレス
  136.         madr : レジスタ・メモリアドレス 8bit
  137.         data : 書き込むデータ
  138.    戻り値  無し
  139. */
  140. void i2cDevWrite8(unsigned char sadr, unsigned char madr, unsigned char data)
  141. {
  142.     i2cBusFree();
  143.     i2cStart();
  144.     i2cSendByte(sadr);
  145.     i2cSendByte(madr);
  146.     i2cSendByte(data);
  147.     i2cCheckTEND();
  148.     i2cStop();
  149. }
  150. /*
  151.   スレーブアドレスとデバイスのレジスタ・アドレスを指定してデバイスからデータを読み込む
  152.   引数   sadr : スレーブ・アドレス
  153.        madr : レジスタ・メモリアドレス 8bit
  154.   戻り値  読み込んだデバイスのデータ
  155. */
  156. unsigned char i2cDevRead8(unsigned char sadr, unsigned char madr)
  157. {
  158.     unsigned char rdt;
  159.     i2cBusFree();
  160.     i2cStart();
  161.     i2cSendByte(sadr);
  162.     i2cSendByte(madr);
  163.     i2cCheckTEND();
  164.     i2cReStart();
  165.     i2cSendByte(sadr | 0x01);
  166.     rdt = i2cReceiveByteStop();
  167.     return rdt;
  168. }
  169. /*
  170.    スレーブアドレスを指定して複数byteのデータを送信する
  171.    引数  sadr : スレーブアドレス
  172.        databuff: 送信するデータの入った配列
  173.        datanum : 送信するデータ数
  174.    戻り値 0 : 送信完了  -1 : 送信エラー
  175. */
  176. int i2cSendData(unsigned char sadr, const unsigned char databuff[], int datanum)
  177. {
  178.     int senddata=-1,ret=-1;
  179.     i2cBusFree();
  180.     i2cStart();
  181.     while(senddata<datanum) {
  182.         if(RIIC0.ICSR2.BIT.NACKF != 0) goto sendstop;    //送信エラー
  183.         if(RIIC0.ICSR2.BIT.TDRE != 1) continue;
  184.         if(senddata < 0) {
  185.             RIIC0.ICDRT = sadr;            //最初にアドレスを送信
  186.         } else {
  187.             RIIC0.ICDRT = databuff[senddata];
  188.         }
  189.         senddata++;
  190.     }
  191.     i2cCheckTEND();
  192.     ret = 0;        //送信完了
  193. sendstop:
  194.     i2cStop();
  195.     return ret;
  196. }
  197. /*
  198.    スレーブアドレスを指定して複数byteのデータを受信する
  199.    引数  sadr : スレーブアドレス
  200.        databuff: 受信したデータを入れる配列
  201.        datanum : 受信するデータ数
  202.    戻り値 0 : 受信完了  -1 : 受信エラー
  203. */
  204. int i2cReceiveData(unsigned char sadr, unsigned char databuff[], int datanum)
  205. {
  206.     int recvdata=0,ret=-1;
  207.     unsigned char dummy;
  208.     i2cBusFree();
  209.     i2cStart();
  210.     i2cSendByte(sadr | 0x01);        // アドレス送信 受信設定(|0x01)
  211.     i2cCheckTEND();
  212.     if(datanum == 1 ) {
  213.         databuff[0] = i2cReceiveByteStop();
  214.         return 0;
  215.     }
  216.     if(RIIC0.ICSR2.BIT.NACKF == 0) {
  217.     /* データ受信処理 */
  218.         dummy = RIIC0.ICDRR;                //dummy read
  219.         while(recvdata < datanum) {
  220.             if(RIIC0.ICSR2.BIT.RDRF != 1) continue;
  221.             if(recvdata == (datanum-2) ) break;
  222.             if(recvdata == (datanum-3) ) {
  223.                 RIIC0.ICMR3.BIT.WAIT = 1;
  224.             }
  225.             databuff[recvdata++] = RIIC0.ICDRR;
  226.         }
  227.         RIIC0.ICMR3.BIT.ACKBT = 1;
  228.         databuff[recvdata++] = RIIC0.ICDRR;
  229.         while(RIIC0.ICSR2.BIT.RDRF != 1);
  230.         RIIC0.ICSR2.BIT.STOP = 0;
  231.         RIIC0.ICCR2.BIT.SP = 1;
  232.         databuff[recvdata++] = RIIC0.ICDRR;
  233.         RIIC0.ICMR3.BIT.WAIT = 0;
  234.         ret = 0;
  235.     } else {
  236.     /* 受信エラー */
  237.         RIIC0.ICSR2.BIT.STOP = 0;
  238.         RIIC0.ICCR2.BIT.SP = 1;
  239.         dummy = RIIC0.ICDRR;        //dummy read
  240.     }
  241.     while(RIIC0.ICSR2.BIT.STOP != 1);
  242.     RIIC0.ICSR2.BIT.STOP = 0;
  243.     RIIC0.ICSR2.BIT.NACKF = 0;
  244.     return ret;
  245. }
  246. /*
  247.    スレーブ・アドレスを指定してデバイスのレジスタ・メモリにデータを書き込む
  248.    引数   sadr : スレーブ・アドレス
  249.         madr : レジスタ・メモリアドレス 16bit
  250.         data : 書き込むデータ
  251.    戻り値  無し
  252. */
  253. void i2cDevWrite16(unsigned char sadr, unsigned short madr, unsigned char data)
  254. {
  255.     unsigned char buf[3];
  256.     buf[0] = madr >> 8;
  257.     buf[1] = madr & 0xFF;
  258.     buf[2] = data;
  259.     i2cSendData(sadr,buf,3);
  260. /*
  261.     i2cBusFree();
  262.     i2cStart();
  263.     i2cSendByte(sadr);
  264.     i2cSendByte(madr >> 8);
  265.     i2cSendByte(madr & 0xFF);
  266.     i2cSendByte(data);
  267.     i2cCheckTEND();
  268.     i2cStop();
  269. */
  270. }
  271. /*
  272.   スレーブアドレスとデバイスのレジスタ・アドレスを指定してデバイスからデータを読み込む
  273.   引数   sadr : スレーブ・アドレス
  274.        madr : レジスタ・メモリアドレス 16bit
  275.   戻り値  読み込んだデバイスのデータ
  276. */
  277. unsigned char i2cDevRead16(unsigned char sadr, unsigned short madr)
  278. {
  279.     unsigned char rdt;
  280.     i2cBusFree();
  281.     i2cStart();
  282.     i2cSendByte(sadr);
  283.     i2cSendByte(madr >> 8);
  284.     i2cSendByte(madr & 0xFF);
  285.     i2cCheckTEND();
  286.     i2cReStart();
  287.     i2cSendByte(sadr | 0x01);
  288.     rdt = i2cReceiveByteStop();
  289.     return rdt;
  290. }