[DemoCode下载] NUC123的I2C接口使用方法

[复制链接]
3889|17
 楼主| 玛尼玛尼哄 发表于 2017-8-20 21:42 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * $Revision: 16 $
  5. * $Date: 16/06/21 7:49p $
  6. * @brief
  7. *           Demonstrate how to set I2C in slave mode to receive the data from a Master.
  8. *           This sample code is EEPROM like, only support 256 bytes.
  9. *           Needs to work with I2C_Master sample code.
  10. * @note
  11. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  12. *
  13. ******************************************************************************/
  14. #include <stdio.h>
  15. #include "NUC123.h"

  16. #define PLLCON_SETTING  CLK_PLLCON_72MHz_HXT
  17. #define PLL_CLOCK       72000000

  18. uint32_t slave_buff_addr;
  19. uint8_t g_au8SlvData[256];
  20. uint8_t g_au8SlvRxData[3];
  21. /*---------------------------------------------------------------------------------------------------------*/
  22. /* Global variables                                                                                        */
  23. /*---------------------------------------------------------------------------------------------------------*/
  24. volatile uint8_t g_u8DeviceAddr;
  25. volatile uint8_t g_u8SlvDataLen;

  26. typedef void (*I2C_FUNC)(uint32_t u32Status);

  27. static I2C_FUNC s_I2C0HandlerFn = NULL;

  28. /*---------------------------------------------------------------------------------------------------------*/
  29. /*  I2C0 IRQ Handler                                                                                       */
  30. /*---------------------------------------------------------------------------------------------------------*/
  31. void I2C0_IRQHandler(void)
  32. {
  33.     uint32_t u32Status;

  34.     u32Status = I2C0->I2CSTATUS;

  35.     if(I2C0->I2CTOC & I2C_I2CTOC_TIF_Msk)
  36.     {
  37.         /* Clear I2C0 Timeout Flag */
  38.         I2C0->I2CTOC |= I2C_I2CTOC_TIF_Msk;
  39.     }
  40.     else
  41.     {
  42.         if(s_I2C0HandlerFn != NULL)
  43.             s_I2C0HandlerFn(u32Status);
  44.     }
  45. }

  46. /*---------------------------------------------------------------------------------------------------------*/
  47. /*  I2C TRx Callback Function                                                                               */
  48. /*---------------------------------------------------------------------------------------------------------*/
  49. void I2C_SlaveTRx(uint32_t u32Status)
  50. {
  51.     uint8_t u8data;
  52.    
  53.     if(u32Status == 0x60)                       /* Own SLA+W has been receive; ACK has been return */
  54.     {
  55.         g_u8SlvDataLen = 0;
  56.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  57.     }
  58.     else if(u32Status == 0x80)                 /* Previously address with own SLA address
  59.                                                    Data has been received; ACK has been returned*/
  60.     {
  61.         u8data = (unsigned char) I2C_GET_DATA(I2C0);   
  62.         if(g_u8SlvDataLen < 2)        
  63.         {
  64.             g_au8SlvRxData[g_u8SlvDataLen++] = u8data;        
  65.             slave_buff_addr = (g_au8SlvRxData[0] << 8) + g_au8SlvRxData[1];            
  66.         }
  67.         else
  68.         {
  69.             g_au8SlvData[slave_buff_addr++] = u8data;
  70.             if(slave_buff_addr==256)
  71.             {
  72.                 slave_buff_addr = 0;
  73.             }            
  74.         }            

  75.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  76.     }
  77.     else if(u32Status == 0xA8)                  /* Own SLA+R has been receive; ACK has been return */
  78.     {

  79.         I2C0->I2CDAT = g_au8SlvData[slave_buff_addr];
  80.         slave_buff_addr++;
  81.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  82.     }
  83.     else if(u32Status == 0xB8)                  /* Data byte in I2CDAT has been transmitted ACK has been received */
  84.     {
  85.         I2C_SET_DATA(I2C0, g_au8SlvData[slave_buff_addr++]);
  86.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  87.     }     
  88.     else if(u32Status == 0xC0)                 /* Data byte or last data in I2CDAT has been transmitted
  89.                                                    Not ACK has been received */
  90.     {
  91.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  92.     }
  93.     else if(u32Status == 0x88)                 /* Previously addressed with own SLA address; NOT ACK has
  94.                                                    been returned */
  95.     {
  96.         g_u8SlvDataLen = 0;
  97.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  98.     }
  99.     else if(u32Status == 0xA0)                 /* A STOP or repeated START has been received while still
  100.                                                    addressed as Slave/Receiver*/
  101.     {
  102.         g_u8SlvDataLen = 0;
  103.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);
  104.     }
  105.     else
  106.     {
  107.         /* TO DO */
  108.         printf("Status 0x%x is NOT processed\n", u32Status);
  109.     }
  110. }

  111. void SYS_Init(void)
  112. {
  113.     /*---------------------------------------------------------------------------------------------------------*/
  114.     /* Init System Clock                                                                                       */
  115.     /*---------------------------------------------------------------------------------------------------------*/

  116.     /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */
  117.     SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;

  118.     /* Enable Internal RC 22.1184MHz clock */
  119.     CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;

  120.     /* Waiting for Internal RC clock ready */
  121.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk));

  122.     /* Switch HCLK clock source to Internal RC and and HCLK source divide 1 */
  123.     CLK->CLKSEL0 &= ~CLK_CLKSEL0_HCLK_S_Msk;
  124.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HIRC;
  125.     CLK->CLKDIV &= ~CLK_CLKDIV_HCLK_N_Msk;
  126.     CLK->CLKDIV |= CLK_CLKDIV_HCLK(1);

  127.     /* Enable external XTAL 12MHz clock */
  128.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

  129.     /* Waiting for external XTAL clock ready */
  130.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk));

  131.     /* Set core clock as PLL_CLOCK from PLL */
  132.     CLK->PLLCON = PLLCON_SETTING;
  133.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk));
  134.     CLK->CLKSEL0 &= (~CLK_CLKSEL0_HCLK_S_Msk);
  135.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_PLL;

  136.     /* Update System Core Clock */
  137.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  138.     //SystemCoreClockUpdate();
  139.     PllClock        = PLL_CLOCK;            // PLL
  140.     SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  141.     CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()

  142.     /* Enable UART & I2C0 module clock */
  143.     CLK->APBCLK |= (CLK_APBCLK_UART0_EN_Msk | CLK_APBCLK_I2C0_EN_Msk);

  144.     /* Select UART module clock source */
  145.     CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
  146.     CLK->CLKSEL1 |= CLK_CLKSEL1_UART_S_HXT;

  147.     /*---------------------------------------------------------------------------------------------------------*/
  148.     /* Init I/O Multi-function                                                                                 */
  149.     /*---------------------------------------------------------------------------------------------------------*/

  150.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  151.     SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

  152.     /* Set GPF multi-function pins for I2C0 SDA and SCL */
  153.     SYS->GPF_MFP |= (SYS_GPF_MFP_PF2_I2C0_SDA | SYS_GPF_MFP_PF3_I2C0_SCL);
  154.     SYS->ALT_MFP1 &= ~(SYS_ALT_MFP1_PF2_Msk | SYS_ALT_MFP1_PF3_Msk);
  155.     SYS->ALT_MFP1 |= (SYS_ALT_MFP1_PF2_I2C0_SDA | SYS_ALT_MFP1_PF3_I2C0_SCL);
  156. }

  157. void UART0_Init(void)
  158. {
  159.     /*---------------------------------------------------------------------------------------------------------*/
  160.     /* Init UART                                                                                               */
  161.     /*---------------------------------------------------------------------------------------------------------*/
  162.     /* Reset UART IP */
  163.     SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
  164.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;

  165.     /* Configure UART0 and set UART0 Baudrate */
  166.     UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
  167.     UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
  168. }

  169. void I2C0_Init(void)
  170. {
  171.     uint32_t u32BusClock;

  172.     /* Reset I2C0 */
  173.     SYS->IPRSTC2 |=  SYS_IPRSTC2_I2C0_RST_Msk;
  174.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_I2C0_RST_Msk;

  175.     /* Enable I2C0 Controller */
  176.     I2C0->I2CON |= I2C_I2CON_ENS1_Msk;

  177.     /* I2C0 bus clock 100K divider setting, I2CLK = PCLK/(100K*4)-1 */
  178.     u32BusClock = 100000;
  179.     I2C0->I2CLK = (uint32_t)(((SystemCoreClock * 10) / (u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */

  180.     /* Get I2C0 Bus Clock */
  181.     printf("I2C clock %d Hz\n", (SystemCoreClock / (((I2C0->I2CLK) + 1) << 2)));

  182.     /* Set I2C0 4 Slave Addresses */
  183.     /* Slave Address : 0x15 */
  184.     I2C0->I2CADDR0 = (I2C0->I2CADDR0 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x15 << I2C_I2CADDR_I2CADDR_Pos);
  185.     /* Slave Address : 0x35 */
  186.     I2C0->I2CADDR1 = (I2C0->I2CADDR1 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x35 << I2C_I2CADDR_I2CADDR_Pos);
  187.     /* Slave Address : 0x55 */
  188.     I2C0->I2CADDR2 = (I2C0->I2CADDR2 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x55 << I2C_I2CADDR_I2CADDR_Pos);
  189.     /* Slave Address : 0x75 */
  190.     I2C0->I2CADDR3 = (I2C0->I2CADDR3 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x75 << I2C_I2CADDR_I2CADDR_Pos);

  191.     /* Set I2C0 4 Slave Addresses Mask Bits*/
  192.     /* Slave Address Mask Bits: 0x01 */
  193.     I2C0->I2CADM0 = (I2C0->I2CADM0 & ~I2C_I2CADM_I2CADM_Msk) | (0x01 << I2C_I2CADM_I2CADM_Pos);
  194.     /* Slave Address Mask Bits: 0x04 */
  195.     I2C0->I2CADM1 = (I2C0->I2CADM1 & ~I2C_I2CADM_I2CADM_Msk) | (0x04 << I2C_I2CADM_I2CADM_Pos);
  196.     /* Slave Address Mask Bits: 0x01 */
  197.     I2C0->I2CADM2 = (I2C0->I2CADM2 & ~I2C_I2CADM_I2CADM_Msk) | (0x01 << I2C_I2CADM_I2CADM_Pos);
  198.     /* Slave Address Mask Bits: 0x04 */
  199.     I2C0->I2CADM3 = (I2C0->I2CADM3 & ~I2C_I2CADM_I2CADM_Msk) | (0x04 << I2C_I2CADM_I2CADM_Pos);

  200.     /* Enable I2C0 interrupt and set corresponding NVIC bit */
  201.     I2C0->I2CON |= I2C_I2CON_EI_Msk;
  202.     NVIC_EnableIRQ(I2C0_IRQn);
  203. }

  204. void I2C0_Close(void)
  205. {
  206.     /* Disable I2C0 interrupt and clear corresponding NVIC bit */
  207.     I2C0->I2CON &= ~I2C_I2CON_EI_Msk;
  208.     NVIC_DisableIRQ(I2C0_IRQn);

  209.     /* Disable I2C0 and close I2C0 clock */
  210.     I2C0->I2CON &= ~I2C_I2CON_ENS1_Msk;
  211.     CLK->APBCLK &= ~CLK_APBCLK_I2C0_EN_Msk;
  212. }

  213. /*---------------------------------------------------------------------------------------------------------*/
  214. /*  Main Function                                                                                          */
  215. /*---------------------------------------------------------------------------------------------------------*/
  216. int32_t main(void)
  217. {
  218.     uint32_t i;

  219.     /* Unlock protected registers */
  220.     SYS_UnlockReg();

  221.     /* Init System, IP clock and multi-function I/O */
  222.     SYS_Init();


  223.     /* Lock protected registers */
  224.     SYS_LockReg();

  225.     /* Init UART0 for printf */
  226.     UART0_Init();

  227.     /*
  228.         This sample code sets I2C bus clock to 100kHz. Then, Master accesses Slave with Byte Write
  229.         and Byte Read operations, and check if the read data is equal to the programmed data.
  230.     */

  231.     printf("+----------------------------------------------------+\n");
  232.     printf("| I2C Driver Sample Code(Slave) for access Slave     |\n");
  233.     printf("| Needs to work with I2C_Master sample code          |\n");
  234.     printf("| I2C Master (I2C0) <---> I2C Slave(I2C0)            |\n");
  235.     printf("| !! This sample code requires two borads to test !! |\n");
  236.     printf("+----------------------------------------------------+\n");

  237.     printf("Configure I2C0 as a slave.\n");
  238.     printf("The I/O connection for I2C0:\n");
  239.     printf("I2C0_SDA(PF.2), I2C0_SCL(PF.3)\n");

  240.     /* Init I2C0 */
  241.     I2C0_Init();

  242.     /* I2C enter no address SLV mode */
  243.     I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI_AA);

  244.     for(i = 0; i < 0x100; i++)
  245.     {
  246.         g_au8SlvData[i] = 0;
  247.     }

  248.     /* I2C function to Slave receive/transmit data */
  249.     s_I2C0HandlerFn = I2C_SlaveTRx;

  250.     printf("\n");
  251.     printf("I2C Slave Mode is Running.\n");

  252.     while(1);
  253. }




 楼主| 玛尼玛尼哄 发表于 2017-8-20 21:43 | 显示全部楼层
  1. /**************************************************************************//**
  2. * @file     main.c
  3. * @version  V3.00
  4. * $Revision: 15 $
  5. * $Date: 16/06/21 7:49p $
  6. * @brief    Demonstrate a Master how to access Slave.
  7. *           Needs to work with I2C_Slave sample code.
  8. * @note
  9. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "NUC123.h"

  14. #define PLLCON_SETTING  CLK_PLLCON_72MHz_HXT
  15. #define PLL_CLOCK       72000000


  16. /*---------------------------------------------------------------------------------------------------------*/
  17. /* Global variables                                                                                        */
  18. /*---------------------------------------------------------------------------------------------------------*/
  19. volatile uint8_t g_u8DeviceAddr;
  20. volatile uint8_t g_au8MstTxData[3];
  21. volatile uint8_t g_u8MstRxData;
  22. volatile uint8_t g_u8MstDataLen;
  23. volatile uint8_t g_u8MstEndFlag = 0;

  24. typedef void (*I2C_FUNC)(uint32_t u32Status);

  25. static volatile I2C_FUNC s_I2C0HandlerFn = NULL;

  26. /*---------------------------------------------------------------------------------------------------------*/
  27. /*  I2C0 IRQ Handler                                                                                       */
  28. /*---------------------------------------------------------------------------------------------------------*/
  29. void I2C0_IRQHandler(void)
  30. {
  31.     uint32_t u32Status;

  32.     u32Status = I2C0->I2CSTATUS;

  33.     if(I2C0->I2CTOC & I2C_I2CTOC_TIF_Msk)
  34.     {
  35.         /* Clear I2C0 Timeout Flag */
  36.         I2C0->I2CTOC |= I2C_I2CTOC_TIF_Msk;
  37.     }
  38.     else
  39.     {
  40.         if(s_I2C0HandlerFn != NULL)
  41.             s_I2C0HandlerFn(u32Status);
  42.     }
  43. }

  44. /*---------------------------------------------------------------------------------------------------------*/
  45. /*  I2C Rx Callback Function                                                                               */
  46. /*---------------------------------------------------------------------------------------------------------*/
  47. void I2C_MasterRx(uint32_t u32Status)
  48. {
  49.     if(u32Status == 0x08)                       /* START has been transmitted and prepare SLA+W */
  50.     {
  51.         I2C0->I2CDAT = g_u8DeviceAddr << 1;     /* Write SLA+W to Register I2CDAT */
  52.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  53.     }
  54.     else if(u32Status == 0x18)                  /* SLA+W has been transmitted and ACK has been received */
  55.     {
  56.         I2C0->I2CDAT = g_au8MstTxData[g_u8MstDataLen++];
  57.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  58.     }
  59.     else if(u32Status == 0x20)                  /* SLA+W has been transmitted and NACK has been received */
  60.     {
  61.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
  62.     }
  63.     else if(u32Status == 0x28)                  /* DATA has been transmitted and ACK has been received */
  64.     {
  65.         if(g_u8MstDataLen != 2)
  66.         {
  67.             I2C0->I2CDAT = g_au8MstTxData[g_u8MstDataLen++];
  68.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  69.         }
  70.         else
  71.         {
  72.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_SI);
  73.         }
  74.     }
  75.     else if(u32Status == 0x10)                  /* Repeat START has been transmitted and prepare SLA+R */
  76.     {
  77.         I2C0->I2CDAT = ((g_u8DeviceAddr << 1) | 0x01);   /* Write SLA+R to Register I2CDAT */
  78.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  79.     }
  80.     else if(u32Status == 0x40)                  /* SLA+R has been transmitted and ACK has been received */
  81.     {
  82.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  83.     }
  84.     else if(u32Status == 0x58)                  /* DATA has been received and NACK has been returned */
  85.     {
  86.         g_u8MstRxData = I2C0->I2CDAT;
  87.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
  88.         g_u8MstEndFlag = 1;
  89.     }
  90.     else
  91.     {
  92.         /* TO DO */
  93.         printf("Status 0x%x is NOT processed\n", u32Status);
  94.     }
  95. }

  96. /*---------------------------------------------------------------------------------------------------------*/
  97. /*  I2C Tx Callback Function                                                                               */
  98. /*---------------------------------------------------------------------------------------------------------*/
  99. void I2C_MasterTx(uint32_t u32Status)
  100. {
  101.     if(u32Status == 0x08)                       /* START has been transmitted */
  102.     {
  103.         I2C0->I2CDAT = g_u8DeviceAddr << 1;     /* Write SLA+W to Register I2CDAT */
  104.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  105.     }
  106.     else if(u32Status == 0x18)                  /* SLA+W has been transmitted and ACK has been received */
  107.     {
  108.         I2C0->I2CDAT = g_au8MstTxData[g_u8MstDataLen++];
  109.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  110.     }
  111.     else if(u32Status == 0x20)                  /* SLA+W has been transmitted and NACK has been received */
  112.     {
  113.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA_STO_SI);
  114.     }
  115.     else if(u32Status == 0x28)                  /* DATA has been transmitted and ACK has been received */
  116.     {
  117.         if(g_u8MstDataLen != 3)
  118.         {
  119.             I2C0->I2CDAT = g_au8MstTxData[g_u8MstDataLen++];
  120.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_SI);
  121.         }
  122.         else
  123.         {
  124.             I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
  125.             g_u8MstEndFlag = 1;
  126.         }
  127.     }
  128.     else
  129.     {
  130.         /* TO DO */
  131.         printf("Status 0x%x is NOT processed\n", u32Status);
  132.     }
  133. }

  134. void SYS_Init(void)
  135. {
  136.     /*---------------------------------------------------------------------------------------------------------*/
  137.     /* Init System Clock                                                                                       */
  138.     /*---------------------------------------------------------------------------------------------------------*/

  139.     /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */
  140.     SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;

  141.     /* Enable Internal RC 22.1184MHz clock */
  142.     CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;

  143.     /* Waiting for Internal RC clock ready */
  144.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk));

  145.     /* Switch HCLK clock source to Internal RC and and HCLK source divide 1 */
  146.     CLK->CLKSEL0 &= ~CLK_CLKSEL0_HCLK_S_Msk;
  147.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HIRC;
  148.     CLK->CLKDIV &= ~CLK_CLKDIV_HCLK_N_Msk;
  149.     CLK->CLKDIV |= CLK_CLKDIV_HCLK(1);

  150.     /* Enable external XTAL 12MHz clock */
  151.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

  152.     /* Waiting for external XTAL clock ready */
  153.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk));

  154.     /* Set core clock as PLL_CLOCK from PLL */
  155.     CLK->PLLCON = PLLCON_SETTING;
  156.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk));
  157.     CLK->CLKSEL0 &= (~CLK_CLKSEL0_HCLK_S_Msk);
  158.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_PLL;

  159.     /* Update System Core Clock */
  160.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  161.     //SystemCoreClockUpdate();
  162.     PllClock        = PLL_CLOCK;            // PLL
  163.     SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  164.     CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()

  165.     /* Enable UART & I2C0 module clock */
  166.     CLK->APBCLK |= (CLK_APBCLK_UART0_EN_Msk | CLK_APBCLK_I2C0_EN_Msk);

  167.     /* Select UART module clock source */
  168.     CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
  169.     CLK->CLKSEL1 |= CLK_CLKSEL1_UART_S_HXT;

  170.     /*---------------------------------------------------------------------------------------------------------*/
  171.     /* Init I/O Multi-function                                                                                 */
  172.     /*---------------------------------------------------------------------------------------------------------*/

  173.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  174.     SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

  175.     /* Set GPF multi-function pins for I2C0 SDA and SCL */
  176.     SYS->GPF_MFP |= (SYS_GPF_MFP_PF2_I2C0_SDA | SYS_GPF_MFP_PF3_I2C0_SCL);
  177.     SYS->ALT_MFP1 &= ~(SYS_ALT_MFP1_PF2_Msk | SYS_ALT_MFP1_PF3_Msk);
  178.     SYS->ALT_MFP1 |= (SYS_ALT_MFP1_PF2_I2C0_SDA | SYS_ALT_MFP1_PF3_I2C0_SCL);
  179. }

  180. void UART0_Init(void)
  181. {
  182.     /*---------------------------------------------------------------------------------------------------------*/
  183.     /* Init UART                                                                                               */
  184.     /*---------------------------------------------------------------------------------------------------------*/
  185.     /* Reset UART IP */
  186.     SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
  187.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;

  188.     /* Configure UART0 and set UART0 Baudrate */
  189.     UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
  190.     UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
  191. }

  192. void I2C0_Init(void)
  193. {
  194.     uint32_t u32BusClock;

  195.     /* Reset I2C0 */
  196.     SYS->IPRSTC2 |=  SYS_IPRSTC2_I2C0_RST_Msk;
  197.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_I2C0_RST_Msk;

  198.     /* Enable I2C0 Controller */
  199.     I2C0->I2CON |= I2C_I2CON_ENS1_Msk;

  200.     /* I2C0 bus clock 100K divider setting, I2CLK = PCLK/(100K*4)-1 */
  201.     u32BusClock = 100000;
  202.     I2C0->I2CLK = (uint32_t)(((SystemCoreClock * 10) / (u32BusClock * 4) + 5) / 10 - 1); /* Compute proper divider for I2C clock */

  203.     /* Get I2C0 Bus Clock */
  204.     printf("I2C clock %d Hz\n", (SystemCoreClock / (((I2C0->I2CLK) + 1) << 2)));

  205.     /* Set I2C0 4 Slave Addresses */
  206.     /* Slave Address : 0x15 */
  207.     I2C0->I2CADDR0 = (I2C0->I2CADDR0 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x15 << I2C_I2CADDR_I2CADDR_Pos);
  208.     /* Slave Address : 0x35 */
  209.     I2C0->I2CADDR1 = (I2C0->I2CADDR1 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x35 << I2C_I2CADDR_I2CADDR_Pos);
  210.     /* Slave Address : 0x55 */
  211.     I2C0->I2CADDR2 = (I2C0->I2CADDR2 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x55 << I2C_I2CADDR_I2CADDR_Pos);
  212.     /* Slave Address : 0x75 */
  213.     I2C0->I2CADDR3 = (I2C0->I2CADDR3 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x75 << I2C_I2CADDR_I2CADDR_Pos);

  214.     /* Enable I2C0 interrupt and set corresponding NVIC bit */
  215.     I2C0->I2CON |= I2C_I2CON_EI_Msk;
  216.     NVIC_EnableIRQ(I2C0_IRQn);
  217. }

  218. void I2C0_Close(void)
  219. {
  220.     /* Disable I2C0 interrupt and clear corresponding NVIC bit */
  221.     I2C0->I2CON &= ~I2C_I2CON_EI_Msk;
  222.     NVIC_DisableIRQ(I2C0_IRQn);

  223.     /* Disable I2C0 and close I2C0 clock */
  224.     I2C0->I2CON &= ~I2C_I2CON_ENS1_Msk;
  225.     CLK->APBCLK &= ~CLK_APBCLK_I2C0_EN_Msk;

  226. }

  227. int32_t Read_Write_SLAVE(uint8_t slvaddr)
  228. {
  229.     uint32_t i;

  230.     g_u8DeviceAddr = slvaddr;

  231.     for(i = 0; i < 0x100; i++)
  232.     {
  233.         g_au8MstTxData[0] = (uint8_t)((i & 0xFF00) >> 8);
  234.         g_au8MstTxData[1] = (uint8_t)(i & 0x00FF);
  235.         g_au8MstTxData[2] = (uint8_t)(g_au8MstTxData[1] + 3);

  236.         g_u8MstDataLen = 0;
  237.         g_u8MstEndFlag = 0;

  238.         /* I2C function to write data to slave */
  239.         s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterTx;

  240.         /* I2C as master sends START signal */
  241.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);

  242.         /* Wait I2C Tx Finish */
  243.         while(g_u8MstEndFlag == 0);
  244.         g_u8MstEndFlag = 0;

  245.         /* I2C function to read data from slave */
  246.         s_I2C0HandlerFn = (I2C_FUNC)I2C_MasterRx;

  247.         g_u8MstDataLen = 0;
  248.         g_u8DeviceAddr = slvaddr;

  249.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);

  250.         /* Wait I2C Rx Finish */
  251.         while(g_u8MstEndFlag == 0);

  252.         /* Compare data */
  253.         if(g_u8MstRxData != g_au8MstTxData[2])
  254.         {
  255.             printf("I2C Byte Write/Read Failed, Data 0x%x\n", g_u8MstRxData);
  256.             return -1;
  257.         }
  258.     }
  259.     printf("Master Access Slave (0x%X) Test OK\n", slvaddr);
  260.     return 0;
  261. }
  262. /*---------------------------------------------------------------------------------------------------------*/
  263. /*  Main Function                                                                                          */
  264. /*---------------------------------------------------------------------------------------------------------*/
  265. int32_t main(void)
  266. {
  267.     /* Unlock protected registers */
  268.     SYS_UnlockReg();

  269.     /* Init System, IP clock and multi-function I/O */
  270.     SYS_Init();

  271.     /* Lock protected registers */
  272.     SYS_LockReg();

  273.     /* Init UART0 for printf */
  274.     UART0_Init();

  275.     /*
  276.         This sample code sets I2C bus clock to 100kHz. Then, Master accesses Slave with Byte Write
  277.         and Byte Read operations, and check if the read data is equal to the programmed data.
  278.     */
  279.     printf("\n");
  280.     printf("+----------------------------------------------------+\n");
  281.     printf("| I2C Driver Sample Code(Master) for access Slave    |\n");
  282.     printf("| Needs to work with I2C_Slave sample code           |\n");
  283.     printf("| I2C Master (I2C0) <---> I2C Slave(I2C0)            |\n");
  284.     printf("| !! This sample code requires two borads to test !! |\n");
  285.     printf("+----------------------------------------------------+\n");

  286.     printf("Configure I2C0 as a master.\n");
  287.     printf("The I/O connection for I2C0:\n");
  288.     printf("I2C0_SDA(PF.2), I2C0_SCL(PF.3)\n");

  289.     /* Init I2C0 */
  290.     I2C0_Init();

  291.     printf("\n");
  292.     printf("Check I2C Slave(I2C0) is running first!\n");
  293.     printf("Press any key to continue.\n");
  294.     getchar();

  295.     /* Access Slave with no address mask */
  296.     printf("\n");
  297.     printf(" == No Mask Address ==\n");
  298.     Read_Write_SLAVE(0x15);
  299.     Read_Write_SLAVE(0x35);
  300.     Read_Write_SLAVE(0x55);
  301.     Read_Write_SLAVE(0x75);
  302.     printf("SLAVE Address test OK.\n");

  303.     /* Access Slave with address mask */
  304.     printf("\n");
  305.     printf(" == Mask Address ==\n");
  306.     Read_Write_SLAVE(0x15 & ~0x01);
  307.     Read_Write_SLAVE(0x35 & ~0x04);
  308.     Read_Write_SLAVE(0x55 & ~0x01);
  309.     Read_Write_SLAVE(0x75 & ~0x04);
  310.     printf("SLAVE Address Mask test OK.\n");

  311.     s_I2C0HandlerFn = NULL;

  312.     /* Close I2C0 */
  313.     I2C0_Close();

  314.     while(1);
  315. }




 楼主| 玛尼玛尼哄 发表于 2017-8-20 21:44 | 显示全部楼层
其实最好配合着手册,看着说明再看例子比较好懂了
598330983 发表于 2017-8-21 15:47 | 显示全部楼层
    /* Set I2C0 4 Slave Addresses */
    /* Slave Address : 0x15 */
    I2C0->I2CADDR0 = (I2C0->I2CADDR0 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x15 << I2C_I2CADDR_I2CADDR_Pos);
    /* Slave Address : 0x35 */
    I2C0->I2CADDR1 = (I2C0->I2CADDR1 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x35 << I2C_I2CADDR_I2CADDR_Pos);
    /* Slave Address : 0x55 */
    I2C0->I2CADDR2 = (I2C0->I2CADDR2 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x55 << I2C_I2CADDR_I2CADDR_Pos);
    /* Slave Address : 0x75 */
    I2C0->I2CADDR3 = (I2C0->I2CADDR3 & ~I2C_I2CADDR_I2CADDR_Msk) | (0x75 << I2C_I2CADDR_I2CADDR_Pos);
不就一个单片机吗,怎么这么多从机地址
jiekou001 发表于 2017-8-21 19:09 | 显示全部楼层
有点难以理解了。
xinpian101 发表于 2017-8-21 20:41 | 显示全部楼层
有一些命名的寄存器看着好奇葩
天灵灵地灵灵 发表于 2017-8-21 21:52 | 显示全部楼层
用寄存器虽然效率高,但是没有库函数的好理解。
5574293 发表于 2017-8-22 17:38 | 显示全部楼层
天灵灵地灵灵 发表于 2017-8-21 21:52
用寄存器虽然效率高,但是没有库函数的好理解。

可以先用库函数写,再改成寄存器的 ,效果很好
wanduzi 发表于 2017-8-26 19:18 | 显示全部楼层
总结库函数有个规则,就是每次都是配置一堆那个结构体变量,然后通过一个函数把配置的结构体变量传递进去。
wanduzi 发表于 2017-8-26 19:19 | 显示全部楼层
比如那个时钟那个,之前看不懂,现在逛论坛多了,就懂了
天灵灵地灵灵 发表于 2017-8-27 16:23 | 显示全部楼层
5574293 发表于 2017-8-22 17:38
可以先用库函数写,再改成寄存器的 ,效果很好

这一招真给力。
捉虫天师 发表于 2017-8-27 20:19 | 显示全部楼层
手上没有IIC芯片,没法玩啊。
lss1985 发表于 2017-9-5 08:45 | 显示全部楼层
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
{
    *(volatile uint32_t *)((uint32_t)&CLK->APBCLK + (MODULE_APBCLK(u32ModuleIdx) * 4))  |= 1 << MODULE_IP_EN_Pos(u32ModuleIdx);
}
这个时钟使能库函数就没看懂,调用的是PWM01模块,,,
#define PWM01_MODULE   ((0x0<<31)|(0x1<<29)    |(0x3<<25)         |(28<<20)                       |(MODULE_NoMsk<<10)               |CLK_APBCLK_PWM01_EN_Pos)
huangcunxiake 发表于 2017-9-5 23:08 | 显示全部楼层
手里不搞个I2C的芯片,玩起来费劲。
zhuotuzi 发表于 2017-9-6 20:39 | 显示全部楼层
看完觉得简单多了。
zhuotuzi 发表于 2017-9-6 20:40 | 显示全部楼层
lss1985 发表于 2017-9-5 08:45
void CLK_EnableModuleClock(uint32_t u32ModuleIdx)
{
    *(volatile uint32_t *)((uint32_t)&CLK->APBCL ...

是的,估计是用的都是APB时钟吧,你研究的怪深入的,那要研究这个,就别看库函数,直接看寄存器版本的例子,比较好。
lss1985 发表于 2017-9-7 09:55 | 显示全部楼层
zhuotuzi 发表于 2017-9-6 20:40
是的,估计是用的都是APB时钟吧,你研究的怪深入的,那要研究这个,就别看库函数,直接看寄存器版本的例 ...

最终还是用了寄存器版本的写法,库函数直接能用的就用了,看不懂的还是寄存器好用
arsenallai 发表于 2019-7-4 17:35 | 显示全部楼层
IIC 超时功能怎么用?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

198

主题

3432

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部