toilet

Vuongbk - Bài 4: Chức năng I2C Serial Interface Controller của KIT NUTINY - SDK - M051

Thảo luận trong 'Bài viết dự thi'

Đang xem chủ đề này ( Thành viên: 0, Khách: 0)

  1. Đăng 13/6/14 #1

    vuongbk Sinh viên đại học

    Số bài viết: 84
    Đã được thích: 58
    BÀI DỰ THI TÌM HIỂU KIT PHÁT TRIỂN CỦA NUVOTON


    - Họ và tên: Nguyễn Châu Vương

    - Nick diễn đàn: Vuongbk

    - Bài 4: Chức năng I2C Serial Interface Controller của KIT NUTINY - SDK - M051

    Nhìn chung, giao thức I2C standard communication bao gồm 4 bước:

    1. Bắt đầu hoặc lặp đi lặp lại tín hiệu bắt đầu

    2. Slave address and R/W bit transfer

    3. Data transfer

    4. Stop tín hiệu
    1.

    Sơ đồ cơ chế truyền và nhận dữ liệu của Master và Slave
    • Master Transmits Data to Slave:
    2.
    • Master Reads Data form Slave:
    3.
    Trên đây là phần giới thiệu chung về I2C, chúng ta bước vào phần lập trình điều khiển trên Kit. Trước khi bắt đầu lập trình, chúng ta xem sơ đồ về cơ chế hoạt động của chức năng I2C trên CoX Peripheral Library.
    4.

    Bây giờ, chúng ta viết chương trình kiểm tra cho Slave mode và Master Mode : Nháy Led P3.6 (khi chưa kết thúc trạng thái Led sáng, kết thúc trạng thái Led tắt)

    Yêu cầu:

    · Cần có 2 Kit

    · Kết nối Pin11 của Kit1 với Pin11 của Kit2

    · Kết nối Pin10 của Kit1 với Pin10 của Kit2

    Chương trình chính:
    Mã:
    void DriveI2CMaster(void);
    void DriveI2CSlave();
    int main(void)
    
    {
      //automatically added by CoIDE
      DriveI2CSlave();
      //automatically added by CoIDE
      DriveI2CMaster();
      while(1)
      {
      }
    }
    
    Chương trình con I2CSlave.c:
    Mã:
    #include"DrvGPIO.h"
    
    #include"DrvSYS.h"
    
    #include"DrvI2C.h"
    
    
    uint8_t  RecData[3];  /*The received data will be stored in it temporarily*/
    
    uint8_t  DataLen;  /*The length of data has been transmitted or received.*/
    
    /*The address has been decoded with RecData[0] and RecData[1].*/
    
    uint16_t Slave_Buff_Addr;
    
    /*The data will be store in this array,and the index will be the decoded address*/
    
    uint8_t  Slave_Buff[32];
    
    
    /***********************************************************************//**
    
     * declare function prototype
    
    ***************************************************************************/
    
    void I2C_Callback_Slave(uint32_t status);
    
    
    /*************************************************************************//*
    
     Chuong trinh I2C slave driver.
    
    
    *****************************************************************************/
    
    void DriveI2CSlave()
    
    {
    
      uint8_t i;  /*it ,an temporary variable,will be used in initializing the Slave_Buff[];*/
    
    
      UNLOCKREG();
    
      SYSCLK->PWRCON.XTL12M_EN = 1;
    
      /* Waiting for 12M Xtal stable */
    
      while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);
    
    
      DrvGPIO_InitFunction(E_FUNC_I2C);
    
      /* Open I2C and set clock = 100Kbps */
    
      DrvI2C_Open(100000);
    
    
      /* Set I2C slave addresses */
    
      DrvI2C_SetAddress(0, 0x10, 0);
    
      DrvI2C_SetAddress(1, 0x30, 0);
    
      DrvI2C_SetAddress(2, 0x50, 0);
    
      DrvI2C_SetAddress(3, 0x70, 0);
    
    
      for (i = 0; i < 32; i++)
    
      {
    
      Slave_Buff[i] = 0;
    
      }
    
    
      /* Set AA bit, I2C1 as slave (To simulate a 24LXX EEPROM) */
    
      DrvI2C_Ctrl(0, 0, 0, 1);
    
      /* Enable I2C interrupt and set corresponding NVIC bit */
    
      DrvI2C_EnableInt();
    
      /* Install I2C call back function for slave */
    
      DrvI2C_InstallCallback(I2CFUNC, I2C_Callback_Slave);
    
      while (1);  /*Wait for the interrupt*/
    
    }
    
    ////////////////////////////////////////////////////////////////////////////
    
    //  Chuong trinh con Slave's I2C CallBack function
    
    ////////////////////////////////////////////////////////////////////////////
    
    void I2C_Callback_Slave(uint32_t status)
    
    {
    
      uint32_t DelayCounter = 0x20000;  /*It used for Flashing led;*/
    
      switch (status)
    
      {
    
      case 0x60 :
    
      DataLen = 0;
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      case 0x68 :  /* SLA+W has been received and ACK has been returned */
    
      DataLen = 0;
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
       break;
    
      case 0x80 :  /* DATA has been received and ACK has been returned */
    
      /*Store the data*/
    
      RecData[DataLen++] = DrvI2C_ReadData();
    
      /*Decode address*/
    
      if (DataLen == 2)
    
       {
    
      Slave_Buff_Addr  = ((uint16_t)RecData[0] << 8) | (uint16_t)RecData[1];
    
      }
    
      /*Store data at the address*/
    
      if ((DataLen == 3) && (Slave_Buff_Addr < 32))
    
      {
    
      Slave_Buff[Slave_Buff_Addr] = RecData[2];
    
      DataLen = 0;
    
      }
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      case 0xB0 :
    
      if ((DataLen == 0) && (Slave_Buff_Addr < 32)) /*The previous status is 0xA0*/
    
      {
    
      DrvI2C_WriteData(Slave_Buff[Slave_Buff_Addr]);
    
      }
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      case 0xA8 :  /* SLA+R has been received and ACK has been returned */
    
      if ((DataLen == 0) && (Slave_Buff_Addr < 32)) /*The previous status is 0xA0*/
    
      {
    
      DrvI2C_WriteData(Slave_Buff[Slave_Buff_Addr]);
    
      DrvGPIO_Open(E_PORT3, E_PIN6, E_IO_OUTPUT);
    
      DrvGPIO_ClrBit(E_PORT3, E_PIN6);
    
      while (DelayCounter--);
    
      DelayCounter = 0x100000;
    
      DrvGPIO_SetBit(E_PORT3, E_PIN6);
    
      while (DelayCounter--);
    
      }
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      case 0xC0 :  /* DATA has been transmitted and NACK has been received */
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      case 0xA0 :  /* STOP or Repeat START has been received */
    
      DataLen = 0;
    
      DrvI2C_Ctrl(0, 0, 1, 1);
    
      break;
    
      default :
    
      break;
    
      }
    
    }
    
    Chương trình con I2CMaster.c:
    Mã:
    #include<stdio.h>
    
    #include"DrvGPIO.h"
    
    #include"DrvSYS.h"
    
    #include"DrvI2C.h"
    
    
    #define I2C_SLAVE_ADD (0x10)  /*Slave0 address */
    
    
    /*The first and second byte is address,and the third one is data.*/
    
    uint8_t Tx_Data[3];
    
    uint8_t Rx_Data;  /*The received data will be stored in it temporarily*/
    
    uint8_t DataLen;  /*The length of data has been transmitted.*/
    
    /*It will be set when the transmission or the receiving has been done.*/
    
    volatile uint8_t EndFlag = 0;
    
    
    /**************************************************************************//**
    
     * declare function prototype
    
    ******************************************************************************/
    
    void I2C_Callback_Master_Rx(uint32_t status);
    
    void I2C_Callback_Master_Tx(uint32_t status);
    
    void FlashingLed(int8_t Times,uint8_t FinalStatus);
    
    
    /*************************************************************************//**
    
     * Chuong trinh I2C Master driver.
    
    *****************************************************************************/
    
    void DriveI2CMaster(void)
    
    {
    
      uint16_t i;
    
      UNLOCKREG();
    
      SYSCLK->PWRCON.XTL12M_EN = 1;
    
      /* Waiting for 12M Xtal stable */
    
      while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);
    
    
      DrvGPIO_InitFunction(E_FUNC_I2C);
    
      /* Open I2C and set clock = 100Kbps */
    
      DrvI2C_Open(100000);
    
    
      /* Set I2C0 slave addresses, this will make no difference in this example.*/
    
      DrvI2C_SetAddress(0, 0x15, 0);
    
      DrvI2C_SetAddress(1, 0x35, 0);
    
      DrvI2C_SetAddress(2, 0x55, 0);
    
      DrvI2C_SetAddress(3, 0x75, 0);
    
    
      /* Enable I2C0 interrupt and set corresponding NVIC bit */
    
      DrvI2C_EnableInt();
    
    
      for (i = 0; i < 10; i++)
    
      { 
    
      Tx_Data[0] = (uint8_t)((uint16_t)(i & 0xFF00) >> 8);
    
      Tx_Data[1] = (uint8_t)(i & 0x00FF);
    
      /*Prepare the data and it can be any number.*/
    
      Tx_Data[2] = (uint8_t)(0x0055 ^ i);
    
    
      DataLen = 0;
    
      EndFlag = 0;
    
      /* Install I2C0 call back function for write data to slave */
    
      DrvI2C_InstallCallback(I2CFUNC, I2C_Callback_Master_Tx);
    
      /* I2C0 as master sends START signal */
    
      DrvI2C_Ctrl(1, 0, 0, 0);
    
      /* Wait I2C0 Tx Finish */
    
      while (EndFlag == 0);
    
    
      EndFlag = 0;
    
      /* Uninstall I2C0 call back function for write data to slave */
    
      DrvI2C_UninstallCallBack(I2CFUNC);
    
      /* Install I2C0 call back function for read data from slave */
    
      DrvI2C_InstallCallback(I2CFUNC, I2C_Callback_Master_Rx);
    
      DataLen= 0;
    
    
      DrvI2C_Ctrl(1, 0, 0, 0);
    
      /* Wait I2C0 Rx Finish */
    
       while (EndFlag == 0);
    
      /* Compare data */
    
      if (Rx_Data != Tx_Data[2])
    
      {
    
      FlashingLed(4,1);
    
      }
    
      else
    
      {
    
      FlashingLed(1,0);
    
      }
    
      }
    
    
      /* Disable I2C0 interrupt and clear corresponding NVIC bit */
    
      DrvI2C_DisableInt();
    
      /* Close I2C0 and I2C1 */
    
      DrvI2C_Close();
    
    }
    
    
    /**************************************************************************//**
    
     * Chuong trinh  Flashing the led
    
    ******************************************************************************/
    
    void FlashingLed(int8_t Times,uint8_t FinalStatus)
    
    { 
    
      volatile uint32_t i = 0x20000;
    
      if (Times < 0) Times = 1;
    
      DrvGPIO_Open(E_PORT3, E_PIN6, E_IO_OUTPUT); 
    
      while (Times--)
    
      {
    
      DrvGPIO_ClrBit(E_PORT3, E_PIN6);
    
      while (i--);
    
      i = 0x100000;
    
      DrvGPIO_SetBit(E_PORT3, E_PIN6);
    
      while (i--);
    
      i = 0x20000;
    
      }
    
      if (FinalStatus != 0)
    
      DrvGPIO_ClrBit(E_PORT3, E_PIN6); /*turn on led*/
    
    }
    
    
    /**************************************************************************//**
    
     * @brief  Master's I2C Rx CallBack function
    
     * @param[in]  status : the state of I2C
    
     * @return  None
    
    ******************************************************************************/
    
    void I2C_Callback_Master_Rx(uint32_t status)
    
    {
    
    
      switch (status)
    
      {
    
      case 0x08 :  /* START has been transmitted and prepare SLA+W */
    
      DrvI2C_WriteData(I2C_SLAVE_ADD << 1); /*The first bit is used for W/R*/
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x18 :  /* SLA+W has been transmitted and ACK has been received */
    
      DrvI2C_WriteData(Tx_Data[DataLen++]);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x20 :  /* SLA+W has been transmitted and NACK has been received */
    
      DrvI2C_Ctrl(1, 1, 1, 0);
    
      break;
    
      case 0x28 :  /* DATA has been transmitted and ACK has been received */
    
      if (DataLen != 2)  /*To make sure the address have been transmitted*/
    
      {
    
      DrvI2C_WriteData(Tx_Data[DataLen++]);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      }
    
      else
    
      {
    
      /*change the TX mode to RX mode.The next status is 0x10*/
    
      DrvI2C_Ctrl(1, 0, 1, 0);
    
      }
    
      break;
    
      case 0x10 :  /* Repeat START has been transmitted and prepare SLA+R */
    
      /*the I2C slave address of EEPROM for read*/
    
      DrvI2C_WriteData(I2C_SLAVE_ADD << 1 | 0x01);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x40 :  /* SLA+R has been transmitted and ACK has been received */
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x58 :  /* DATA has been received and NACK has been returned */
    
      Rx_Data = DrvI2C_ReadData();
    
      DrvI2C_Ctrl(0, 1, 1, 0);
    
      EndFlag = 1;
    
      break;
    
      default  :
    
      break;
    
      }
    
    }
    
    
    /**************************************************************************//**
    
     * Chuong trinh Master's I2C Rx CallBack function
    
    
    ******************************************************************************/
    
    void I2C_Callback_Master_Tx(uint32_t status)
    
    {
    
      switch (status)
    
      {
    
      case 0x08 :  /* START has been transmitted and prepare SLA+W */
    
      DrvI2C_WriteData(I2C_SLAVE_ADD << 1);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x18 :  /* SLA+W has been transmitted and ACK has been received */
    
      DrvI2C_WriteData(Tx_Data[DataLen++]);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      break;
    
      case 0x20 :  /* SLA+W has been transmitted and NACK has been received */
    
      DrvI2C_Ctrl(1, 1, 1, 0);
    
      break;
    
      case 0x28 :   /* DATA has been transmitted and ACK has been received */
    
      if (DataLen != 3)
    
      {
    
      DrvI2C_WriteData(Tx_Data[DataLen++]);
    
      DrvI2C_Ctrl(0, 0, 1, 0);
    
      }
    
      else
    
      {
    
      DrvI2C_Ctrl(0, 1, 1, 0);
    
      EndFlag = 1;
    
      }
    
      break;
    
      default  :
    
      break;
    
      }
    
    }
    
    Build thì Ok !

    Vì không có chương trình mô phỏng và chưa có Kit để kiểm tra nên các bạn tạm đọc Code tham khảo.

    Cảm ơn !
    daotruongproBuiBachTuanAnh thích bài này.
    #1
  2. Đăng 13/6/14 #2

    vuongbk Sinh viên đại học

    Số bài viết: 84
    Đã được thích: 58
    Sory ! Mình còn quên File PDf !

    Các file đính kèm:

    BuiBachTuanAnh thích bài này.
    #2

Chia sẻ trang này