查看: 69|回复: 6
收起左侧

[DemoCode下载] M051操作I2C的EEPROM

[复制链接]

43

主题

1588

帖子

4747

积分

中级工程师

 楼主| 发表于 2017-7-11 21:13 | 显示全部楼层 |返回版面|阅读模式
  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: 3 $
  5. * $Date: 14/01/28 11:44a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series I2C Driver Sample Code for EEPROM 24LC64
  7. *
  8. * @note
  9. * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. #include <stdio.h>
  13. #include "M051Series.h"

  14. #define PLLCON_SETTING      SYSCLK_PLLCON_50MHz_XTAL
  15. #define PLL_CLOCK           50000000


  16. /*---------------------------------------------------------------------------------------------------------*/
  17. /* Global variables                                                                                        */
  18. /*---------------------------------------------------------------------------------------------------------*/
  19. volatile uint8_t g_u8DeviceAddr;
  20. volatile uint8_t g_au8TxData[3];
  21. volatile uint8_t g_u8RxData;
  22. volatile uint8_t g_u8DataLen;
  23. volatile uint8_t g_u8EndFlag = 0;

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

  25. static I2C_FUNC s_I2C0HandlerFn = NULL;

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

  32.     u32Status = I2C_GET_STATUS(I2C0);
  33.     if(I2C_GET_TIMEOUT_FLAG(I2C0))
  34.     {
  35.         /* Clear I2C0 Timeout Flag */
  36.         I2C_ClearTimeoutFlag(I2C0);
  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.         I2C_SET_DATA(I2C0, (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.         I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  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_u8DataLen != 2)
  66.         {
  67.             I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  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.         I2C_SET_DATA(I2C0, ((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_u8RxData = (unsigned char) I2C_GET_DATA(I2C0);
  87.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STO_SI);
  88.         g_u8EndFlag = 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.         I2C_SET_DATA(I2C0, 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.         I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  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_u8DataLen != 3)
  118.         {
  119.             I2C_SET_DATA(I2C0, g_au8TxData[g_u8DataLen++]);
  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_u8EndFlag = 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 Internal RC 22.1184MHz clock */
  140.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  141.     /* Waiting for Internal RC clock ready */
  142.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  143.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  144.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  145.     /* Enable external XTAL 12MHz clock */
  146.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  147.     /* Waiting for external XTAL clock ready */
  148.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  149.     /* Set core clock as PLL_CLOCK from PLL */
  150.     CLK_SetCoreClock(PLL_CLOCK);

  151.     /* Enable UART & I2C0 module clock */
  152.     CLK_EnableModuleClock(UART0_MODULE);
  153.     CLK_EnableModuleClock(I2C0_MODULE);

  154.     /* Select UART module clock source */
  155.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));

  156.     /*---------------------------------------------------------------------------------------------------------*/
  157.     /* Init I/O Multi-function                                                                                 */
  158.     /*---------------------------------------------------------------------------------------------------------*/

  159.     /* Set P3 multi-function pins for UART0 RXD and TXD */
  160.     SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
  161.     SYS->P3_MFP |= SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0;

  162.     /* Configure the SDA0 & SCL0 of I2C0 pins */
  163.     SYS->P3_MFP &= ~(SYS_MFP_P34_Msk | SYS_MFP_P35_Msk);
  164.     SYS->P3_MFP |= SYS_MFP_P34_SDA0 | SYS_MFP_P35_SCL0;
  165. }

  166. void UART0_Init()
  167. {
  168.     /*---------------------------------------------------------------------------------------------------------*/
  169.     /* Init UART                                                                                               */
  170.     /*---------------------------------------------------------------------------------------------------------*/
  171.     /* Reset IP */
  172.     SYS_ResetModule(UART0_RST);

  173.     /* Configure UART0 and set UART0 Baudrate */
  174.     UART_Open(UART0, 115200);
  175. }

  176. void I2C0_Close(void)
  177. {
  178.     /* Disable I2C0 interrupt and clear corresponding NVIC bit */
  179.     I2C_DisableInt(I2C0);
  180.     NVIC_DisableIRQ(I2C0_IRQn);

  181.     /* Disable I2C0 and close I2C0 clock */
  182.     I2C_Close(I2C0);
  183.     CLK_DisableModuleClock(I2C0_MODULE);

  184. }

  185. void I2C0_Init(void)
  186. {
  187.     /* Open I2C module and set bus clock */
  188.     I2C_Open(I2C0, 100000);

  189.     /* Get I2C0 Bus Clock */
  190.     printf("I2C clock %d Hz\n", I2C_GetBusClockFreq(I2C0));

  191.     /* Set I2C 4 Slave Addresses */
  192.     I2C_SetSlaveAddr(I2C0, 0, 0x15, 0);   /* Slave Address : 0x15 */
  193.     I2C_SetSlaveAddr(I2C0, 1, 0x35, 0);   /* Slave Address : 0x35 */
  194.     I2C_SetSlaveAddr(I2C0, 2, 0x55, 0);   /* Slave Address : 0x55 */
  195.     I2C_SetSlaveAddr(I2C0, 3, 0x75, 0);   /* Slave Address : 0x75 */

  196.     /* Enable I2C interrupt */
  197.     I2C_EnableInt(I2C0);
  198.     NVIC_EnableIRQ(I2C0_IRQn);
  199. }

  200. /*---------------------------------------------------------------------------------------------------------*/
  201. /*  Main Function                                                                                          */
  202. /*---------------------------------------------------------------------------------------------------------*/
  203. int32_t main(void)
  204. {
  205.     uint32_t i;

  206.     /* Unlock protected registers */
  207.     SYS_UnlockReg();

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

  210.     /* Lock protected registers */
  211.     SYS_LockReg();

  212.     /* Init UART0 for printf */
  213.     UART0_Init();

  214.     /*
  215.         This sample code sets I2C bus clock to 100kHz. Then, accesses EEPROM 24LC64 with Byte Write
  216.         and Byte Read operations, and check if the read data is equal to the programmed data.
  217.     */

  218.     printf("+-------------------------------------------------------+\n");
  219.     printf("|    M05xx I2C Driver Sample Code with EEPROM 24LC64    |\n");
  220.     printf("+-------------------------------------------------------+\n");

  221.     /* Init I2C0 to access EEPROM */
  222.     I2C0_Init();

  223.     g_u8DeviceAddr = 0x50;

  224.     for(i = 0; i < 0x100; i++)
  225.     {
  226.         g_au8TxData[0] = (uint8_t)((i & 0xFF00) >> 8);
  227.         g_au8TxData[1] = (uint8_t)(i & 0x00FF);
  228.         g_au8TxData[2] = (uint8_t)(g_au8TxData[1] + 3);

  229.         g_u8DataLen = 0;
  230.         g_u8EndFlag = 0;

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

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

  235.         /* Wait I2C Tx Finish */
  236.         while(g_u8EndFlag == 0);
  237.         g_u8EndFlag = 0;

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

  240.         g_u8DataLen = 0;
  241.         g_u8DeviceAddr = 0x50;

  242.         I2C_SET_CONTROL_REG(I2C0, I2C_I2CON_STA);

  243.         /* Wait I2C Rx Finish */
  244.         while(g_u8EndFlag == 0);

  245.         /* Compare data */
  246.         if(g_u8RxData != g_au8TxData[2])
  247.         {
  248.             printf("I2C Byte Write/Read Failed, Data 0x%x\n", g_u8RxData);
  249.             return -1;
  250.         }
  251.     }
  252.     printf("I2C0 Access EEPROM Test OK\n");

  253.     s_I2C0HandlerFn = NULL;

  254.     /* Close I2C0 */
  255.     I2C0_Close();

  256.     return 0;
  257. }


复制代码


21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

43

主题

1588

帖子

4747

积分

中级工程师

 楼主| 发表于 2017-7-11 21:16 | 显示全部楼层 |返回版面
官方为了用户更好的使用外设,对每个外设都提供了例程序操作示例。
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

85

主题

3576

帖子

1万

积分

资深工程师

发表于 2017-7-12 19:24 | 显示全部楼层 |返回版面
I2C接口的使用方法。
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

53

主题

1361

帖子

4095

积分

中级工程师

发表于 2017-7-12 19:36 | 显示全部楼层 |返回版面
051接口真多。给力。
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

32

主题

723

帖子

2164

积分

初级工程师

发表于 2017-7-17 22:13 | 显示全部楼层 |返回版面
很多人都不是很会使用这些接口
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

54

主题

1491

帖子

4479

积分

中级工程师

发表于 2017-7-17 22:38 | 显示全部楼层 |返回版面
必须好好学习这个了。
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0

70

主题

1564

帖子

4692

积分

中级工程师

发表于 2017-7-18 11:52 | 显示全部楼层 |返回版面
特别想学几个串口一起工作。
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里 http://open.21ic.com 移步更多21ic独家微课:http://open.21ic.com/list/3/0/0
您需要登录后才可以回帖 登录 | 注册

本版积分规则

分享 快速回复 返回顶部 返回列表