RX64M 마이크로 컴퓨터로 I2C 통신

15667 단어 RX64ArduinoI2Crenesas

소개



RX64M 마이크로 컴퓨터로 I2C 통신을 시도했을 때의 포인트를 정리한 기사입니다.

구성


  • RX 마이크로 컴퓨터에 설치된 SCI0을 I2C 마스터로 설정
  • RX는 3.3V 신호이므로 3.3V에서 풀업
  • Arduino가 5V 신호이므로 케이블 중간에 I2C 레벨 시프터



    SCI0 설정


  • 스마트 구성기를 사용하여 SCI0을 I2C 마스터로 만듭니다.
  • 설정은 아래 그림과 같이(대향 디바이스가 바뀌는 경우는 최적화 필요)


  • 생성되는 코드



    스마트 컨피그레이터가 토출한 코드의 프로토타입 선언은 아래와 같습니다.
    선두의 「R_rx64m_SCI0」의 부분은, 컴퍼넌트 추가 다이얼로그로 입력한 이름이 반영되기 때문에
    기본 이름이란 의미입니다.

    헤더 파일
    void R_rx64m_SCI0_I2C_Create(void);
    void R_rx64m_SCI0_I2C_Start(void);
    void R_rx64m_SCI0_I2C_Stop(void);
    void R_rx64m_SCI0_I2C_Create_UserInit(void);
    void R_rx64m_SCI0_I2C_IIC_Master_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num);
    void R_rx64m_SCI0_I2C_IIC_Master_Receive(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num);
    void R_rx64m_SCI0_I2C_IIC_StartCondition(void);
    void R_rx64m_SCI0_I2C_IIC_StopCondition(void);
    void r_rx64m_SCI0_I2C_transmitend_interrupt(void);
    static void r_rx64m_SCI0_I2C_callback_transmitend(void);
    static void r_rx64m_SCI0_I2C_callback_receiveend(void);
    

    이 중 사용하는 것은


    기능
    설명


    R_rx64m_SCI0_I2C_Create
    각종 레지스터의 설정, 기동시 초기화로 1회 콜합니다.

    R_rx64m_SCI0_I2C_Start
    사용 시작 전에 한 번 호출합니다.

    R_rx64m_SCI0_I2C_IIC_Master_Send
    라이트용 함수. 마스터 (CPU)에서 슬레이브 (Arduino)로 데이터를 보냅니다.

    R_rx64m_SCI0_I2C_IIC_Master_Receive
    리드용 함수. 마스터(CPU)로부터 어드레스와 R/W비트를 Read로 한 내용을 송신하여 슬레이브로부터의 응답을 받습니다.


    테스트 코드



    RX 마이크로 컴퓨터 측



    R_rx64m_SCI0_I2C_IIC_Master_Send 와 R_rx64m_SCI0_I2C_IIC_Master_Receive 의 2 개의 함수의 제일 인수인 adr 에는 I2C 의 주소를 넣습니다.

    I2C의 규격에서는 최초의 1Byte는 어드레스 7bit + 방향 1bit (0이 Write 1이 Read)로 되어 있습니다.
    Send 와 Receive 2개의 함수가 있으므로 방향을 나타내는 bit는 함수 내에서 처리하고 있다고 예상했지만, 실제로는 제1 인수가 그대로 나와 있는 모습이었습니다. (오시로에서 확인했습니다)

    따라서

  • R_rx64m_SCI0_I2C_IIC_Master_Send의 첫 번째 인수의 LSB는 항상 0입니다.

  • R_rx64m_SCI0_I2C_IIC_Master_Receive의 첫 번째 인수의 LSB는 항상 1입니다.

  • 그러면 잘 작동합니다. . .

    3Byte 송신, 3Byte 수신, 송신 데이터를 수신 데이터로 재기록하는 동작을 합니다.

    main.c
    void main(void){
        uint8_t     adr         =0      ;//7bit address
        uint8_t     dir         =0      ;//0:Write 1:Read
        uint8_t     tx_buf[4]   ={}     ;//
        uint8_t     rx_buf[4]   ={}     ;//
    
        R_rx64m_SCI0_I2C_Create();
        R_rx64m_SCI0_I2C_Start();
    
        while(1){
        //---- I2C Send RX to Arduino ----
            adr     =0x08    ;//7bit address
            dir     =0x00    ;//0:Write 1:Read
            adr     =(adr << 1) | (dir & 0x00);
            R_rx64m_SCI0_I2C_IIC_Master_Send(adr,&tx_buf[0],3);
            delay_ms(10);
    
            //---- I2C Send RX to Arduino ----
            adr     =0x08    ;//7bit address
            dir     =0x01    ;//0:Write 1:Read
            adr     =(adr << 1) | (dir & 0x01);
            R_rx64m_SCI0_I2C_IIC_Master_Receive(adr,rx_buf,3);
    
            printf("[0]=%02x , [1]=%02x , [2]=%02x\n" , rx_buf[0] , rx_buf[1] , rx_buf[2]);
            tx_buf[0] = rx_buf[0];
            tx_buf[1] = rx_buf[1];
            tx_buf[2] = rx_buf[2];
        delay_ms(10);
        }
    }
    

    Arduino 측 코드



    받은 3 바이트 데이터
    * 1Byte 눈은 +1하여 리드시 반환
    * 2Byte눈은 +2하고 리드시 돌려준다
    * 3Byte 눈은 +3하여 리드시 반환
    #include <Wire.h>
    
    byte dt[4]={};
    
    //-----------------------------------------------
    // データを受信時の処理
    //-----------------------------------------------
    void I2C_ReceiveHandler(int howMany) {
        int i=0;
        Serial.print("Receive :") ;
        while( Wire.available() ){
             dt[i] = Wire.read();
             i++;
        }
        Serial.print(dt[0] , HEX);
        Serial.print(" ");
        Serial.print(dt[1] , HEX);
        Serial.print(" ");
        Serial.println(dt[2] , HEX);
    }
    //-----------------------------------------------
    //リクエスト受付時の処理
    //-----------------------------------------------
    void I2C_RequestHandler(){
        Serial.println("Responce :") ;
        Wire.write(dt[0] + 1) ;
        Wire.write(dt[1] + 2) ;
        Wire.write(dt[2] + 3) ;
        }
    //-----------------------------------------------
    //初期化
    //-----------------------------------------------
    void setup(){
        Serial.begin(9600); 
        Wire.begin(0x08);  //I2C Address set
        Wire.onRequest(I2C_RequestHandler);
        Wire.onReceive(I2C_ReceiveHandler);
        Serial.println(" Start");
    }
    //-----------------------------------------------
    // main loop
    //-----------------------------------------------
    void loop(){
      delay(10);
      // no operate
    }
    

    동작 확인



    Arduino의 추가 결과가 반영되어 RX 마이크로 컴퓨터로 돌아왔습니다.


    주소 후에 3Byte 보내고 있는 모습

    좋은 웹페이지 즐겨찾기