Thông báo

Collapse
No announcement yet.

Giao tiếp SPI

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Giao tiếp SPI

    Chào mọi người,

    Em đang làm giao tiếp SPI giữa con vi điều khiển CC1110 ( nó lập trình thanh ghi giống AVR thôi ạ) với con ADXL345Z (cảm biến gia tốc-chuyển dộng đấy ạ) bằng giao tiếp SPI.
    - Đầu tiên, em làm cái project giao tiếp giữa CC1110 và ADXL345 thông qua 4 dây : MOSI, MISO, SCL, CS. Cái project đấy đã chạy rồi ạ, em có thể dùng con CC1110 đọc dữ liệu từ con ADXL345 rồi.
    - Thầy giáo em bắt nối chân CS của ADXL345 xuống đất, vì theo nguyên tắc là chỉ có 1 vi điều khiển và một Vi xử lý thì nối chân CS của ADXL345 xuống đất thì nó luôn được chọn là slave của CC1110. Nhưng mà khi em nối chân CS xuống đất thì em không thể nào giao tiếp lại được với con ADXL345 nữa. Mặc dù khi cấu hình SPI cho CC1110 em đã không cấu hình chân CS để điều khiển con Slave (ADXL345) nữa. Em không biết tại sao chân CS chỉ là chân chọn chip, mà sao khi nối xuống đất nó lại không thể hoạt động được nữa.
    Mọi người có thể giúp em trả lời thắc mắc, với gợi ý cho em hướng để giải quyết ván đề này không ạ.
    Cám ơn mọi người nhiều ạ

    Đây là hàm em dùng để giao tiếp với ADXL345:
    void SPI_init(void)
    {
    /************************************************** *************************
    * Setup I/O ports
    *
    * Port and pins used by USART0 operating in SPI-mode are
    * MISO (MI): P0_2
    * MOSI (MO): P0_3
    * SSN (SS) : P0_4
    * SCK (C) : P0_5
    */


    // Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0)
    // To avoid potential I/O conflict with USART1:
    // configure USART1 for Alternative 2 => Port P1 (PERCFG.U1CFG = 1)
    PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG;
    //
    // Give priority to USART 0 over USART 1 for port 0 pins
    P2DIR = (P2DIR & ~P2DIR_PRIP0) | P2DIR_PRIP0_0;

    // Set pins 2, 3 and 5 as peripheral I/O and pin 4 as GPIO output
    P0SEL = P0SEL | BIT5 | BIT3 | BIT2;
    //P0DIR |= BIT4;// không dùng BIT4 để cấu hình chân CS điều khiển nữa.
    // P0_4=0;
    // Set clock for SPI protocol,
    SLEEP &= ~(0x04); // Power up both oscillator
    while( !(SLEEP & 0x40)); // Wait until XOSC is stable
    CLKCON = (CLKCON & ~(0x00 | 0x40)) | 0x00;
    while (CLKCON & 0x40);
    SLEEP |= 0x04; // Oscillator not selected by CLKCON.OSC bit is powered down

    // Set USART to SPI mode and Master mode
    U0CSR &= ~(0x80 | 0x20);

    U0BAUD = SPI_BAUD_M;
    U0GCR = (U0GCR & ~(U0GCR_BAUD_E))| SPI_BAUD_E | U0GCR_CPOL | U0GCR_CPHA | U0GCR_ORDER;
    }
    //---------------------------------------------------------
    void ADXL345_Init()
    {
    //by writing the value 0x01 to the DATA_FORMAT register.
    // SPI_Write_byte(POWER_CTL, 0x00);
    halWait(50);
    SPI_Write_byte(DATA_FORMAT, 0x0B);
    halWait(50);
    //SPI_Write_byte(INT_ENABLE1, 0x80);
    // halWait(50);
    SPI_Write_byte(BW_RATE, 0x0A);
    halWait(50);
    SPI_Write_byte(POWER_CTL, 0x08); //Measurement mode
    halWait(50);
    }
    //----------------------------------------------------------
    void halWait(uint8_t wait){
    uint32_t largeWait;

    if(wait == 0)
    {return;}

    largeWait = ((uint16_t) (wait << 7));
    largeWait += 59*wait;

    largeWait = (largeWait >> CLKSPD);
    while(largeWait--);

    return;
    }

    //--------------------------------
    uint8_t SPI_Write_Read_Byte( uint8_t data)
    {
    uint32_t timeout = 0x30000;
    INT8U received_data=0;

    U0DBUF= data;
    while(!(U0CSR & U0CSR_TX_BYTE)&& (--timeout!=0))
    if(timeout==0) return 2;
    U0CSR &= ~U0CSR_TX_BYTE; // Wait for byte to be received from slave
    halWait(10);
    received_data=U0DBUF;
    return received_data;

    }
    void SPI_Write_byte(uint8_t res_adr, uint8_t data)
    {
    SPI_Write_Read_Byte(res_adr);
    SPI_Write_Read_Byte(data);
    }
    //----- read a 8-bit data ------------------
    uint8_t SPI_Read_byte(uint8_t res_adr)
    {
    uint8_t data;
    uint8_t address=0;
    address=res_adr|RD;
    SPI_Write_Read_Byte(address);
    data=SPI_Write_Read_Byte(0);
    return data;
    }
    void ADXL345_Read_Buf(uint8_t reg, INT8U *pBuf, uint8_t Len)
    {
    uint8_t i;
    uint8_t address;
    address = reg|RD;
    if (Len>1)//multiple bytes reading
    {
    address=address|MB;
    } // Set CSN low, init SPI tranaction
    SPI_Write_Read_Byte(address); // Select register to write to and read status unsigned char
    for(i=0;i<Len;i++)
    {
    pBuf[i] = SPI_Write_Read_Byte(0x00); //cach nay cung dung)
    halWait(5);
    }
    }

    Và đây là chương trình chính:

    void main( void )
    {
    INT8U Buffer[1]={0};
    uint8_t Bufferx[6]={0,0,0,0,0,0};

    SPI_init();
    __display(_DBG_Main, "Start \0", EOL );
    ADXL345_Init();

    //SPI_Write_byte(INT_ENABLE1, 0x27);
    Buffer[0]=SPI_Read_byte(DEVID);
    halWait(50);
    __display(_DBG_Main, "data= \0", x,1,Buffer[0], EOL );
    halWait(10);

    while(1)

    {
    ADXL345_Read_Buf(DATAX0, Bufferx, 6);

    //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
    //The X value is stored in values[0] and values[1].
    acc_x = ((INT8U)Bufferx[1]<<8)|(INT8U)Bufferx[0];
    //The Y value is stored in values[2] and values[3].
    acc_y = ((INT8U)Bufferx[3]<<8)|(INT8U)Bufferx[2];
    //The Z value is stored in values[4] and values[5].
    acc_z = ((INT8U)Bufferx[5]<<8)|(INT8U)Bufferx[4];

    __display(_DBG_Main, "X:Y:Z= \0", x , 1, acc_x, c, 1, ':', x ,1, acc_y, c, 1, ':', x ,1, acc_z, EOL);

    }
    }

  • #2
    Cũng ko có gì khó hiểu. Có nhiều chip SPI nhất thiết phải có xung sường xuống để chip đó hoạt động. Theo nguyên tắc thì kéo logic low nếu chỉ có 1 slave là đúng rồi nhưng ko đúng cho tất cả.

    Comment


    • #3
      Có thể bạn đã cấu hình SPI ở chuẩn 4 dây. Khi đó bắt buộc phải có 1 chân cs nối từ master sang slave. Bác xem lại phần cấu hình các thanh ghi SPI nhé.
      QTCP

      Comment


      • #4
        Check datasheet Rev D trang 16 thì thấy bắt đầu của 1 transmission là 1 xung sường xuống của CS pin và cả SCLK, kết thúc là sườn lên của CS. SCLK thì idle high sau đó.
        ====> nếu nối CS với ground thì chả biết lúc nào bắt đầu gửi nhận ===> ko có data là chuẩn

        Comment


        • #5
          thank các bác nhiều, phải dùng chân CS là chuẩn đấy. Thầy giáo em thay đổi ý kiến, lại cho dùng chân CS rồi

          Comment


          • #6
            Thầy bạn hiểm nhỉ, nếu ra đề như vậy mà bạn phản ứng đc luôn tại chỗ thì tức là trình độ cứng :v

            Comment

            Về tác giả

            Collapse

            ars_91 Tìm hiểu thêm về ars_91

            Bài viết mới nhất

            Collapse

            Đang tải...
            X