忘備録-備忘録

技術的な備忘録

i2c通信関数

2015-03-26 07:37:56 | RX62N
RX62N用のi2c通信プログラムです。割り込みを利用しません。

  1. /*
  2.    Interface 2011年6月号を参考にして作成したIIC通信プログラム
  3.      割込みを使用しない
  4. */
  5. #include "iodefine.h"
  6. /*
  7.    RIICの初期化
  8.    引数  無し
  9.    戻り値 無し
  10. */
  11. void initRIIC0(void)
  12. {
  13.     MSTP(RIIC0) = 0;            // モジュールスタンバイ解除
  14.     RIIC0.ICCR1.BIT.ICE = 0;
  15.     /* set port direction to input */
  16.     PORT1.DDR.BIT.B3 = 0;            // SDA0
  17.     PORT1.DDR.BIT.B2 = 0;            // SCL0
  18.     /* enable input buffer */
  19.     PORT1.ICR.BIT.B3 = 1;            // SDA0
  20.     PORT1.ICR.BIT.B2 = 1;            // SCL0
  21.     /* オープンドレイン設定 いらない?*/
  22.     PORT1.ODR.BIT.B3 = 1;
  23.     PORT1.ODR.BIT.B2 = 1;
  24.     /* RIIC disable for RIIC initial */
  25.     RIIC0.ICCR1.BIT.ICE = 0;
  26.     RIIC0.ICCR1.BIT.IICRST = 1;        // リセットパルス発生
  27.     RIIC0.ICCR1.BIT.IICRST = 0;
  28.     
  29.     /* Set baud rate */
  30.     RIIC0.ICMR1.BIT.CKS = 4;        // IIC phi = PCLK/8 clock
  31.     RIIC0.ICBRH.BIT.BRH = 25;        // 100kbps (PCLK = 48MHz)
  32.     RIIC0.ICBRL.BIT.BRL = 25;
  33.     /* disable all address detection. Master mode only. */
  34.     RIIC0.ICSER.BYTE = 0x00;
  35.     /* ACKWP is protect bit for ACKBT */
  36.     RIIC0.ICMR3.BIT.ACKWP = 1;        // disable protect for ACKBT
  37.     RIIC0.ICCR1.BIT.ICE = 1;        // enable RIIC
  38. }
  39. /*
  40.    バスフリーの確認
  41.    引数  無し
  42.    戻り値 無し
  43. */
  44. inline void i2cBusFree(void)
  45. {
  46.     while(RIIC0.ICCR2.BIT.BBSY == 1);
  47. }
  48. /*
  49.    バス・スタートを実行
  50.    引数  無し
  51.    戻り値 無し
  52. */
  53. inline void i2cStart(void)
  54. {
  55.     RIIC0.ICCR2.BIT.ST = 1;
  56.     while(RIIC0.ICSR2.BIT.START != 1);
  57.     RIIC0.ICSR2.BIT.START = 0;
  58. }
  59. /*
  60.    バスがBusy中にバス・スタート
  61.    引数  無し
  62.    戻り値 無し
  63. */
  64. inline void i2cReStart(void)
  65. {
  66.     RIIC0.ICCR2.BIT.RS = 1;
  67.     while(RIIC0.ICSR2.BIT.START != 1);
  68.     RIIC0.ICSR2.BIT.START = 0;
  69. }
  70. /*
  71.    バス・ストップを実行
  72.    引数  無し
  73.    戻り値 無し
  74. */
  75. inline void i2cStop(void)
  76. {
  77.     RIIC0.ICSR2.BIT.STOP = 0;
  78.     RIIC0.ICCR2.BIT.SP = 1;
  79.     while(RIIC0.ICSR2.BIT.STOP != 1);
  80.     RIIC0.ICSR2.BIT.STOP = 0;
  81.     RIIC0.ICSR2.BIT.NACKF = 0;
  82. }
  83. /*
  84.    デバイスに1byteデータ転送
  85.    引数  送信データ
  86.    戻り値 無し
  87. */
  88. inline void i2cSendByte(unsigned char data)
  89. {
  90.     while(RIIC0.ICSR2.BIT.TDRE != 1);
  91.     RIIC0.ICDRT = data;
  92. }
  93. /*
  94.    データの転送完了を確認
  95.    引数  無し
  96.    戻り値 無し
  97. */
  98. inline void i2cCheckTEND(void)
  99. {
  100.     while(RIIC0.ICSR2.BIT.TEND != 1);
  101. }
  102. /*
  103.    デバイスから1byte読み取りバスストップを実行
  104.    引数   無し
  105.    戻り値  デバイスから読み取ったデータ
  106. */
  107. unsigned char i2cReceiveByteStop(void)
  108. {
  109.     unsigned char rdt;
  110.     while(RIIC0.ICSR2.BIT.RDRF != 1);
  111.     RIIC0.ICMR3.BIT.WAIT = 1;
  112.     RIIC0.ICMR3.BIT.ACKBT = 1;
  113.     rdt = RIIC0.ICDRR;                //dummy read
  114.     while(RIIC0.ICSR2.BIT.RDRF != 1);
  115.     RIIC0.ICSR2.BIT.STOP = 0;
  116.     RIIC0.ICCR2.BIT.SP = 1;            //stop
  117.     rdt = RIIC0.ICDRR;                //data read
  118.     RIIC0.ICMR3.BIT.WAIT = 0;
  119.     while(RIIC0.ICSR2.BIT.STOP != 1);
  120.     RIIC0.ICSR2.BIT.STOP = 0;
  121.     RIIC0.ICSR2.BIT.NACKF = 0;
  122.     return rdt;
  123. }
  124. /*
  125.    スレーブ・アドレスを指定してデバイスのレジスタ・メモリにデータを書き込む
  126.    引数   sadr : スレーブ・アドレス
  127.         madr : レジスタ・メモリアドレス
  128.         data : 書き込むデータ
  129.    戻り値  無し
  130. */
  131. void i2cDevWrite(unsigned char sadr, unsigned char madr, unsigned char data)
  132. {
  133.     i2cBusFree();
  134.     i2cStart();
  135.     i2cSendByte(sadr);
  136.     i2cSendByte(madr);
  137.     i2cSendByte(data);
  138.     i2cCheckTEND();
  139.     i2cStop();
  140. }
  141. /*
  142.   スレーブアドレスとデバイスのレジスタ・アドレスを指定してデバイスからデータを読み込む
  143.   引数   sadr : スレーブ・アドレス
  144.        madr : レジスタ・メモリアドレス
  145.   戻り値  読み込んだデバイスのデータ
  146. */
  147. unsigned char i2cDevRead(unsigned char sadr, unsigned char madr)
  148. {
  149.     unsigned char rdt;
  150.     i2cBusFree();
  151.     i2cStart();
  152.     i2cSendByte(sadr);
  153.     i2cSendByte(madr);
  154.     i2cCheckTEND();
  155.     i2cReStart();
  156.     i2cSendByte(sadr | 0x01);
  157.     rdt = i2cReceiveByteStop();
  158.     return rdt;
  159. }
  160. /*
  161.    スレーブアドレスを指定して複数byteのデータを送信する
  162.    引数  sadr : スレーブアドレス
  163.        databuff: 送信するデータの入った配列
  164.        datanum : 送信するデータ数
  165.    戻り値 0 : 送信完了  -1 : 送信エラー
  166. */
  167. int i2cSendData(unsigned char sadr, const unsigned char databuff[], int datanum)
  168. {
  169.     int senddata=-1,ret=-1;
  170.     
  171.     i2cBusFree();
  172.     i2cStart();
  173.     while(senddata<datanum) {
  174.         if(RIIC0.ICSR2.BIT.NACKF != 0) goto sendstop;    //送信エラー
  175.         if(RIIC0.ICSR2.BIT.TDRE != 1) continue;
  176.         if(senddata < 0) {
  177.             RIIC0.ICDRT = sadr;            //最初にアドレスを送信
  178.         } else {
  179.             RIIC0.ICDRT = databuff[senddata];
  180.         }
  181.         senddata++;
  182.     }
  183.     i2cCheckTEND();
  184.     ret = 0;        //送信完了
  185. sendstop:
  186.     i2cStop();
  187.     return ret;
  188. }
  189. /*
  190.    スレーブアドレスを指定して複数byteのデータを受信する
  191.    引数  sadr : スレーブアドレス
  192.        databuff: 受信したデータを入れる配列
  193.        datanum : 受信するデータ数
  194.    戻り値 0 : 受信完了  -1 : 受信エラー
  195. */
  196. int i2cReceiveData(unsigned char sadr, unsigned char databuff[], int datanum)
  197. {
  198.     int recvdata=0,ret=-1;
  199.     unsigned char dummy;
  200.     
  201.     i2cBusFree();
  202.     i2cStart();
  203.     i2cSendByte(sadr | 0x01);        // アドレス送信 受信設定(|0x01)
  204.     i2cCheckTEND();
  205.     if(datanum == 1 ) {
  206.         databuff[0] = i2cReceiveByteStop();
  207.         return 0;
  208.     }
  209.     if(RIIC0.ICSR2.BIT.NACKF == 0) {
  210.     /* データ受信処理 */
  211.         dummy = RIIC0.ICDRR;                //dummy read
  212.         while(recvdata < datanum) {
  213.             if(RIIC0.ICSR2.BIT.RDRF != 1) continue;
  214.             if(recvdata == (datanum-2) ) break;
  215.             if(recvdata == (datanum-3) ) {
  216.                 RIIC0.ICMR3.BIT.WAIT = 1;
  217.             }
  218.             databuff[recvdata++] = RIIC0.ICDRR;
  219.         }
  220.         RIIC0.ICMR3.BIT.ACKBT = 1;
  221.         databuff[recvdata++] = RIIC0.ICDRR;
  222.         while(RIIC0.ICSR2.BIT.RDRF != 1);
  223.         RIIC0.ICSR2.BIT.STOP = 0;
  224.         RIIC0.ICCR2.BIT.SP = 1;
  225.         databuff[recvdata++] = RIIC0.ICDRR;
  226.         RIIC0.ICMR3.BIT.WAIT = 0;
  227.         ret = 0;
  228.     } else {
  229.     /* 受信エラー */
  230.         RIIC0.ICSR2.BIT.STOP = 0;
  231.         RIIC0.ICCR2.BIT.SP = 1;
  232.         dummy = RIIC0.ICDRR;        //dummy read
  233.     }    
  234.     while(RIIC0.ICSR2.BIT.STOP != 1);
  235.     RIIC0.ICSR2.BIT.STOP = 0;
  236.     RIIC0.ICSR2.BIT.NACKF = 0;
  237.     
  238.     return ret;
  239. }


最新の画像もっと見る

コメントを投稿