I2Cをポートで制御

おはようございます。NAKA DEATH!

先週末、RL78/I1Eを使ったボードに「I2CのLCD表示を付けて!」と急に依頼がありました。でもSAUをSDカード用にCSIとBLE無線用にUARTで使っちゃたので、もうI2Cつなぐところがなくて困ってました。I2CどころかPORTも全て使っちゃてるし..........。そこでひらめきました!表示用でLEDを2PORT使ってるので、ここをSCLとSDAで使っちゃおう!LEDは点灯しなくなるけどLCDの表示があるからまあいいか!

ということで、PORTを使ってI2CのLCDを制御しました。かふぇルネでも結構RIICやI2Cの動作で質問がありますが、PORTの動作で見直すと意外と理解が深まるかな?と思って投稿しました。(余計なお世話ですが.....汗)

こんな感じです。

#define IIC_SCL    P4_bit.no0
#define IIC_SDA    P1_bit.no7

PM4_bit.no0 = 0;       //IIC_SCL用PortをOUTにセット
PM1_bit.no7 = 0;       //IIC_SDAOUTにセット
PMC1_bit.no7 = 0;       //ポートモードコントロ-ルレジスタP17をデジタル入出力設定
/*******************************************************************************
// 関数名 : IIC_start(void)
// 動作 : IIC_スタートコンディション発行
// 引数 :
// 作成 : NAKA  17.05.29
// ****************************************************************************/
void IIC_start(void)
{
 IIC_SDA = 1;
 IIC_SCL = 1;
 weit_T(2);     //weit(1u)=10
 IIC_SDA = 0;
 weit_T(2);     //weit(1u)=10
 IIC_SCL = 0;
}
/*******************************************************************************
// 関数名 : IIC_stop(void)
// 動作 : IIC_ストップコンディション発行
// 引数 :
// 作成 : NAKA  17.05.29
// ****************************************************************************/
void IIC_stop(void)
{
 IIC_SDA = 0;
 IIC_SCL = 0;
 weit_T(2);   //weit(1u)=10
 IIC_SCL = 1;
 weit_T(2);   //weit(1u)=10
 IIC_SDA = 1;
}
/*******************************************************************************
// 関数名 : IIC_write(unsigned char dat)
// 動作 : IIC_データ書き込み
// 引数 :
// 作成 : NAKA  17.05.29
// ****************************************************************************/
unsigned char IIC_write(unsigned char dat)
{
unsigned char ii,ack;

 for(ii=0;ii<8;ii++)
 {
  if((dat & 0x80) != 0){IIC_SDA = 1;}
  else{IIC_SDA = 0;}
  __nop();
  IIC_SCL = 1;
  weit_T(2);    //weit(1us)
  IIC_SCL = 0;
  if( ii < 7){dat = dat << 1;}
 }
 //SDAを入力に設定
 PM1_bit.no7 = 1;   //P17PortをINにセット
 __nop();
 IIC_SCL = 1;
 ack = P1_bit.no7;   //ackの確認
 PM1_bit.no7 = 0;    //P17PortをOUTにセット
 IIC_SCL = 0;

 return ack;
}


/*******************************************************************************
// 関数名 : fn_LCD_write_s(char *dat)
// 動作 : LCD 文字列表示
// 引数 :
// 作成 : NAKA  17.05.29
// ****************************************************************************/
void fn_LCD_write_s(char *dat)
{
 IIC_start();                //IIC_スタートコンディション発行
 if(IIC_write(0x7C) != 1)    //スレーブアドレス書込み
 {
  IIC_write(0x40);           //コントロールバイト書込み
  while(*dat)
  {
   IIC_write(*dat);
   *dat++;
  }
 }
 IIC_stop();                 //IIC_ストップコンディション発行
 weit_T(50);                 //weit(26us)
}

 

こんな感じで関数作って

 

fn_LCD_write_s(”NAKA_METAL DEATH!”)

とかやれば表示できました。............(笑)

 

Parents
  • わわいです
    汎用ポートでIICするというのはむかしよくやりましたねー
    SCLは単なる出力ポートでいいんですが、SDAはLowは出力のLow、Highは入力ポートに切り替えてやったりしますなー
    んで、SDAをLowからHighにするとき、出力のHighを出してから入力に切り替えるようにすると転送速度をを早くできたりしますな
Reply
  • わわいです
    汎用ポートでIICするというのはむかしよくやりましたねー
    SCLは単なる出力ポートでいいんですが、SDAはLowは出力のLow、Highは入力ポートに切り替えてやったりしますなー
    んで、SDAをLowからHighにするとき、出力のHighを出してから入力に切り替えるようにすると転送速度をを早くできたりしますな
Children
No Data