MSP430のI2CでLCD表示

このソフトは…

USI を持ったMSP430G2を使って、ST7032i 搭載の LCDモジュールを 制御するものです。 I2Cを使う際の参考にどうぞ。 ちなみにMSP430がマスタになって LCD モジュールに一方的にデータを 送りつけているだけです。

ハードウェア

MSP430 and LCD module

基本的にそれだけです。うまく動けば画面に文字が表示されます。 通信に失敗している場合は(Launch Padの場合)P1.0のLEDが光るように なってるので、光ったら回路を確認してください。

ソース

// i2c_lcd.c  by Yagshi 2011
#include <io.h>
#include <msp430/usi.h>
#include <signal.h>

#define kPeriod      12       // 12000 / 12 = 1000 [Hz]

#define kSlaveAddr 0x3e

char buf[] = {
  0x80, 0x38,  // normal instruction set
  0x80, 0x39,  // extension instruction set
  0x80, 0x14,  // freq.
  0x80, 0x78,  // contrast
  0x80, 0x5f,  // power/icon/contrast
  0x80, 0x6a,  // follower control
}; 

char buf2[] = {
  0x80, 0x0f, // display=on, cursor=on, blink=on
  0x80, 0x01, // CLS
  0x80, 0x06,
};

char buf3[] = {0x40, 'T', 'e', 's', 't', 'Y', 'o', 'u', '!' };

void initializeMCU(void)
{
  WDTCTL = WDTPW + WDTHOLD;     // shut up the dog
  BCSCTL3 |= LFXT1S_2;          // Select VLO for ACLK
  P1DIR |= BIT0;
  // setup TIMER_A
  TACTL = TASSEL__ACLK + ID_0 + MC__UP;
  TACCR0 = kPeriod;
  TACCTL0 |= CCIE;              // enable interrupt
  // setup clock (DCO = 15 MHz)
  DCOCTL |= DCO1 + DCO0;
  BCSCTL1 |= RSEL3 + RSEL2 + RSEL1 + RSEL0;
  // setup USI
  P1SEL |= BIT6 + BIT7;
  USICTL0 |= USISWRST;
  USICTL0 &= ~USISWRST;     // start USI
  USICTL0  |= USIPE7 + USIPE6 + USIMST;
  USICTL1  = USII2C;                          // I2C mode
  USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL;  // div = 128, SMCLK, 
}

interrupt(TIMERA0_VECTOR) interruptTimerA0(void)
{
  _BIC_SR_IRQ(SCG1 | SCG0 | CPUOFF);
}

void waitMs(int aMs)
{
  while(aMs--){
    _BIS_SR(SCG1 | SCG0 | CPUOFF);
   };
}

void i2cMakeStartCondition(void)
{
  while(!(P1IN & BIT6));
  USISRL = 0;
  USICTL0 |= USIGE + USIOE;
  USICTL0 &= ~USIGE;
}

void i2cMakeStopCondition(void)
{
  USICTL0 |= USIOE;
  USISRL = 0;
  USICNT = 1;
  while(!(USICTL1 & USIIFG));
  USISRL = 0xff;
  USICTL0 |= USIGE;
  USICTL0 &= ~(USIGE + USIOE);
}

/**
 * @brief  I2C transmission (1 byte)
 * @params aData the data byte
 * @return 1 if NACK, 0 if ACK
 */
int i2cTransmit(int aData)
{
  while(!(P1IN & BIT6));
  USISRL = aData;
  USICTL0 |= USIOE;
  USICNT = 8;
  while(!(USICTL1 & USIIFG));
  // receive ACK
  USICTL0 &= ~USIOE;
  USICNT = 1;
  while(!(USICTL1 & USIIFG));
  return USISRL & 1;
}


int main(void)
{
  int i;

  initializeMCU();
  _BIS_SR(GIE);

  P1OUT &= ~BIT0;
  i2cMakeStopCondition();
  waitMs(40);

  i2cMakeStartCondition();
  i2cTransmit(kSlaveAddr << 1);

  for(i = 0; i < sizeof(buf); i ++){
    if(i2cTransmit(buf[i])) P1OUT |= BIT0;
  }

  waitMs(200);

  for(i = 0; i < sizeof(buf2); i ++){
    if(i2cTransmit(buf2[i])) P1OUT |= BIT0;
  }

  waitMs(200);

  for(i = 0; i < sizeof(buf3); i ++){
    if(i2cTransmit(buf3[i])) P1OUT |= BIT0;
  }

  i2cMakeStopCondition();

  for(;;) _BIS_SR(SCG1 | SCG0 | CPUOFF); // goes into LPM3
  return 0;
}


『マイコンを使った開発について』に戻る

Valid XHTML 1.0!