[MSP430]/MSP430F20132009. 3. 18. 21:34

MSP430 I2C 전송 속도 테스트

MSP430 I2C 전송 속도 테스트




MSP430F2013 보드는 UART가 없어 I2C로 데이터를 수집테스트 정리

구성도
MSP430F2013 (I2C Slave) ->AVR (I2C Master) -> USB2Serial -> PC Host



AVR - > 8Mhz 구동
MSP430F2013 -> 16Mhz구동

2Byte 데이터 수집 속도 측정


H/W 구동시

100Khz
구동시 450us 소요된다.

150Khz 까지 구동 가능하고 이때는 300us 소요된다. (200Khz 이상부터 깨지기 시작한다.)

->메인클럭을 16Mhz까지 올리니 400khz도 문제 없이 잘 동작한다.
 

S/W I2C 구현시
AVR 8Mhz클럭에서  600us 소요된다.

 


H/W I2C
구현 예제

unsigned char ReadByte8( unsigned char add)

{

           unsigned char data_in = 0;

          

           i2c_start_wait(add);

           data_in = i2c_readAck(); 

           i2c_stop();

 

           return (data_in);

}

 

S/W I2C 구현 예제

unsigned char ReadByte8( unsigned char add)

{

           unsigned char data_in = 0;

          

           I2C_Start();

           #if _USE_I2C_DELAY

           Delay_us(I2C_DELAY);

           #endif

 

           I2C_PutByte(add);

           #if _USE_I2C_DELAY

           Delay_us(I2C_DELAY+10);

           #endif  

           I2C_Nack();

 

           #if _USE_I2C_DELAY       

           Delay_us(I2C_DELAY);

           #endif

 

           data_in = I2C_GetByte();

           #if _USE_I2C_DELAY

           Delay_us(I2C_DELAY);

           #endif

           I2C_Nack();

 

           //Delay_us(100);

           I2C_Stop();

 

           return (data_in);

}

Posted by nexp

댓글을 달아 주세요

[SENSOR]/Gyro2009. 3. 12. 22:35

센서모듈 제작 - MSP430F2013 + 2축 GyroSensor

센서모듈 제작 - MSP430F2013 + 2축 GyroSensor



2축 자이로 센서와 MSP430을 이용한 소형 센서모듈을 제작 하였다.
테스트 중...
Posted by nexp

댓글을 달아 주세요

[MSP430]/MSP430F20132009. 3. 11. 17:02

[MSP430F2013 EVM] 클럭 시스템 및 속도 측정

MSP430 GPIO 토글 해서 클럭 설정에 따른 CPU속도를 측정했다.

프로그램 코드
while(1)
{
    P1OUT ^=  LED1_BIT;
}

ASM코드



측정 결과
1Mhz DCO : 6us

8Mhz DCO: 740ns 665Khz

16Mhz DCO : 360ns 1.4Mhz
(AVR속도 측정 참고)

클럭 설정부분 코드 수정

//Set range :1, 8, 12, 16Mhz
#if (__SYS_CLK__ == SYS_CLK_1MHZ)
 #define CALBC1_FREQ     CALBC1_1MHZ
 #define CALDC0_FREQ     CALDCO_1MHZ
#elif (__SYS_CLK__ == SYS_CLK_8MHZ)
 #define CALBC1_FREQ     CALBC1_8MHZ
 #define CALDC0_FREQ     CALDCO_8MHZ 
#elif (__SYS_CLK__ == SYS_AVR_CLK_12MHZ)
 #define CALBC1_FREQ     CALBC1_12MHZ
 #define CALDC0_FREQ     CALDCO_12MHZ 
#elif (__SYS_CLK__ == SYS_AVR_CLK_16MHZ)
 #define CALBC1_FREQ     CALBC1_16MHZ
 #define CALDC0_FREQ     CALDCO_16MHZ 
#endif
void SystemInit(void)
{
    WDTCTL = WDTPW + WDTHOLD;            // Stop watchdog

    #if __SYS_CLK__
    if (CALBC1_FREQ ==0xFF || CALDC0_FREQ == 0xFF)
    { 
        while(1);    // If calibration constants erased
                     // do not load, trap CPU!!
    }  

    // Set DCO
    BCSCTL1 = CALBC1_FREQ; 
    DCOCTL = CALDC0_FREQ;
    #endif
}


MSP430의 동작 클럭을 보려면 P2.1의 SMCLK핀으로 출력하여 볼수 있다.(물론 SMCLK출력을 하려면 P2SEL비트를 세트해야 한다.)
시스템 클럭을 16Mhz로 설정해도 최대 GPIO toggle 클럭은 MCLK/10 이다. 페리가 느린건지...? 데이터시트에는 없는데 문서를 좀더 찾아볼 필요가 있다.

void main(void)
{
    SystemInit();
   
    Led1Init();
    Led1On();

    Sbi(P2DIR, BIT1);
    Sbi(P2SEL, BIT1);                         // P2.1 = SMCLK
 
    while(1)
    {
        Led1Toggle();
    }
Posted by nexp

댓글을 달아 주세요

[MSP430]/MSP430F20132009. 3. 7. 21:47

[MSP430F2013-SS EVM] 초소형 MSP430F2013 보드 제작


[MSP430F2013-SS EVM] 초소형 MSP430F2013 보드 제작



초소형, 초 저전력 MSP430F2013 보드를 제작해 보았다.
테스트용도로 가끔 소형 모듈이 필요한데... 간단한 마이컴이 필요한 상황에서 유용하게 사용할 수 있다.






확장 테스트 보드

Posted by nexp

댓글을 달아 주세요

[MSP430]/MSP430F20132009. 3. 6. 18:27

MSP430 I2C 테스트 - USCI(H/W SM) vs USI (MSP430F2013 S/W SM I2C)

Universal Serial Interface
MSP430F2013은 USI모듈로 SPI, I2C인터페이스를 제공한다. I2C는 USCI를 지원하는 상위 MSP430과 같은 풀 하드웨어로 동작하는것은 아니고 소프트웨어 State Machine를 구현해야 한다. 이때문에 약간 귀찮은 작업을 해 주어야 한다. 물론 속도도 느려지지만 그나마 소형 모듈에서 쉽게 구현할 수 있다는 장점이 있다.



소프트웨어 SM 구조


Slave 구현
1)Master에서 Start + (7bit+1bit)Address를 전송하고  NACK를 기다린다.
2)Slave에서 Address가 맞으면 NACK를 전송한다.
3)Slave에서 Data 전송한다.
4)Master에서 Data수신후 NACK를 송신
5)Slave에서 NACK수신
6)Slave에서 STOP수신(옵션)



MSP430F2013 I2C Slave SM소스코드
//******************************************************
// USI interrupt service routine
//******************************************************
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
  if (USICTL1 & USISTTIFG)             // Start entry?
  {
    I2C_State = 2;                     // Enter 1st state on start
  }

  switch(I2C_State)
    {
      case 0: //Idle, should not get here
              break;

      case 2: //RX Address
              USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX Address
              USICTL1 &= ~USISTTIFG;   // Clear start flag
              I2C_State = 4;           // Go to next state: check address
              break;

      case 4: // Process Address and send (N)Ack
              if (USISRL & 0x01)       // If read...
                SLV_Addr++;            // Save R/W bit
              USICTL0 |= USIOE;        // SDA = output
              if (USISRL == SLV_Addr)  // Address match?
              {
                USISRL = 0x00;         // Send Ack
                I2C_State = 8;         // Go to next state: TX data
              }
              else
              {
                USISRL = 0xFF;         // Send NAck
                P1OUT |= 0x01;         // LED on: error
                I2C_State = 6;         // Go to next state: prep for next Start
              }
              USICNT |= 0x01;          // Bit counter = 1, send (N)Ack bit
              break;

      case 6: // Prep for Start condition
              USICTL0 &= ~USIOE;       // SDA = input
              SLV_Addr = 0x90;         // Reset slave address
              I2C_State = 0;           // Reset state machine
              break;

      case 8: // Send Data byte
              USICTL0 |= USIOE;        // SDA = output
              USISRL = SLV_Data;       // Send data byte
              USICNT |=  0x08;         // Bit counter = 8, TX data
              I2C_State = 10;          // Go to next state: receive (N)Ack
              break;

      case 10:// Receive Data (N)Ack
              USICTL0 &= ~USIOE;       // SDA = input
              USICNT |= 0x01;          // Bit counter = 1, receive (N)Ack
              I2C_State = 12;          // Go to next state: check (N)Ack
              break;

      case 12:// Process Data Ack/NAck
              if (USISRL & 0x01)       // If Nack received...
              {
              }
              else                     // Ack received
              {
                SLV_Data++;            // Increment Slave data
              }
              // Prep for Start condition
              USICTL0 &= ~USIOE;       // SDA = input
              SLV_Addr = 0x90;         // Reset slave address
              I2C_State = 0;           // Reset state machine
              break;
    }

  USICTL1 &= ~USIIFG;                  // Clear pending flags
}



참고로 USCI를 제공하는 MSP430F16x의 I2C구조이다. 외쪽 중앙에 하드웨어 I2C SM모듈이 들어가 있다.



실제 코드를 보면 I2C를 상당히 간단하게 제어할 수 있다.
// Common ISR for I2C Module
#pragma vector=USART0TX_VECTOR
__interrupt void I2C_ISR(void)
{
 switch(I2CIV)
 {
   case  0: break;                          // No interrupt
   case  2: break;                          // Arbitration lost
   case  4: break;                          // No Acknowledge
   case  6: break;                          // Own Address
   case  8: break;                          // Register Access Ready
   case 10:                                 // Receive Ready
     RXData = I2CDRB;                       // RX data
     _BIC_SR_IRQ(CPUOFF);                   // Clear LPM0
     break;
   case 12: break;                          // Transmit Ready
   case 14: break;                          // General Call
   case 16: break;                          // Start Condition
 }
}
Posted by nexp

댓글을 달아 주세요