[综合信息] 【华大测评】+24C02

[复制链接]
669|0
 楼主| Cjy_JDxy 发表于 2020-6-1 18:33 | 显示全部楼层 |阅读模式
I2c, TI, se, TE
今天搞了一下AT24C02.
原理图:
3.jpg
程序:
  1. #include "hc32_ddl.h"

  2. /*******************************************************************************
  3. * Local type definitions ('typedef')
  4. ******************************************************************************/

  5. /*******************************************************************************
  6. * Local pre-processor symbols/macros ('#define')
  7. ******************************************************************************/
  8. /* Define I2C unit used for the example */
  9. #define I2C_CH                          (M4_I2C1)
  10. /* Define E2PROM device address */
  11. #define E2_ADDRESS                      0x50u
  12. /* AT24C02 page length is 8byte*/
  13. #define PAGE_LEN                        8u
  14. /* Define test address for read and write */
  15. #define DATA_TEST_ADDR                  0x00u
  16. /* Define port and pin for SDA and SCL */
  17. #define I2C1_SCL_PORT                   (PortC)
  18. #define I2C1_SCL_PIN                    (Pin04)
  19. #define I2C1_SDA_PORT                   (PortC)
  20. #define I2C1_SDA_PIN                    (Pin05)

  21. #define TIMEOUT                         0x10000ul

  22. #define I2C_RET_OK                      0u
  23. #define I2C_RET_ERROR                   1u

  24. #define GENERATE_START                  0x00u
  25. #define GENERATE_RESTART                0x01u

  26. #define E2_ADDRESS_W                    0x00u
  27. #define E2_ADDRESS_R                    0x01u

  28. /* LED0 Port/Pin definition */
  29. #define  LED0_PORT        (PortE)
  30. #define  LED0_PIN         (Pin06)

  31. /* LED1 Port/Pin definition */
  32. #define  LED1_PORT        (PortA)
  33. #define  LED1_PIN         (Pin07)

  34. /* LED0~1 toggle definition */
  35. #define  LED0_TOGGLE()    (PORT_Toggle(LED0_PORT, LED0_PIN))
  36. #define  LED1_TOGGLE()    (PORT_Toggle(LED1_PORT, LED1_PIN))

  37. /*******************************************************************************
  38. * Global variable definitions (declared in header file with 'extern')
  39. ******************************************************************************/

  40. /*******************************************************************************
  41. * Local function prototypes ('static')
  42. ******************************************************************************/

  43. /*******************************************************************************
  44. * Local variable definitions ('static')
  45. ******************************************************************************/

  46. /*******************************************************************************
  47. * Function implementation - global ('extern') and local ('static')
  48. ******************************************************************************/

  49. /**
  50. ******************************************************************************
  51. ** \brief  Send start or restart condition
  52. **
  53. ** \param  none
  54. **
  55. ** \retval Process result
  56. **         - I2C_RET_ERROR  Send failed
  57. **         - I2C_RET_OK     Send success
  58. ******************************************************************************/
  59. static uint8_t E2_StartOrRestart(uint8_t u8Start)
  60. {
  61.     uint32_t u32TimeOut = TIMEOUT;
  62.     en_flag_status_t enFlagBusy = Reset;
  63.     en_flag_status_t enFlagStartf = Reset;

  64.     /* generate start or restart signal */
  65.     if(GENERATE_START == u8Start)
  66.     {
  67.         /* Wait I2C bus idle */
  68.         while(Set == I2C_GetStatus(I2C_CH, I2C_SR_BUSY))
  69.         {
  70.             if(0ul == (u32TimeOut--))
  71.             {
  72.                 return I2C_RET_ERROR;
  73.             }
  74.         }

  75.         I2C_GenerateStart(I2C_CH , Enable);
  76.     }
  77.     else
  78.     {
  79.         /* Clear start status flag */
  80.         I2C_ClearStatus(I2C_CH, I2C_CLR_STARTFCLR);
  81.         /* Send restart condition */
  82.         I2C_GenerateReStart(I2C_CH , Enable);
  83.     }

  84.     /* Judge if start success*/
  85.     u32TimeOut = TIMEOUT;
  86.     while(1)
  87.     {
  88.         enFlagBusy = I2C_GetStatus(I2C_CH, I2C_SR_BUSY);
  89.         enFlagStartf = I2C_GetStatus(I2C_CH, I2C_SR_STARTF);
  90.         if(enFlagBusy && enFlagStartf)
  91.         {
  92.             break;
  93.         }
  94.         if(0ul == (u32TimeOut--))
  95.         {
  96.             return I2C_RET_ERROR;
  97.         }
  98.     }

  99.     return I2C_RET_OK;
  100. }

  101. /**
  102. ******************************************************************************
  103. ** \brief  Send e2prom device address
  104. **
  105. ** \param  u16Adr  The slave address
  106. **
  107. ** \retval Process result
  108. **         - I2C_RET_ERROR  Send failed
  109. **         - I2C_RET_OK     Send success
  110. ******************************************************************************/
  111. static uint8_t E2_SendAdr(uint8_t u8Adr)
  112. {
  113.     uint32_t u32TimeOut = TIMEOUT;

  114.     /* Wait tx buffer empty */
  115.     while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
  116.     {
  117.         if(0ul == (u32TimeOut--))
  118.         {
  119.             return I2C_RET_ERROR;
  120.         }
  121.     }

  122.     /* Send I2C address */
  123.     I2C_SendData(I2C_CH, u8Adr);

  124.     if(E2_ADDRESS_W == (u8Adr & 0x01u))
  125.     {
  126.         /* If in master transfer process, Need wait transfer end*/
  127.         uint32_t u32TimeOut = TIMEOUT;
  128.         while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
  129.         {
  130.             if(0ul == (u32TimeOut--))
  131.             {
  132.                 return I2C_RET_ERROR;
  133.             }
  134.         }
  135.     }

  136.     /* Check ACK */
  137.     u32TimeOut = TIMEOUT;
  138.     while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
  139.     {
  140.         if(0ul == (u32TimeOut--))
  141.         {
  142.             return I2C_RET_ERROR;
  143.         }
  144.     }

  145.     return I2C_RET_OK;
  146. }

  147. /**
  148. ******************************************************************************
  149. ** \brief  Send data address to e2prom
  150. **
  151. ** \param  u8DataAdr  Data address to be send
  152. **
  153. ** \retval Process result
  154. **         - I2C_RET_ERROR  Send failed
  155. **         - I2C_RET_OK     Send success
  156. ******************************************************************************/
  157. static uint8_t E2_SendDataAdr(uint8_t u8DataAdr)
  158. {
  159.     uint32_t u32TimeOut = TIMEOUT;

  160.     /* Wait tx buffer empty */
  161.     u32TimeOut = TIMEOUT;
  162.     while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
  163.     {
  164.         if(0ul == (u32TimeOut--))
  165.         {
  166.             return I2C_RET_ERROR;
  167.         }
  168.     }

  169.     /* Send one byte data */
  170.     I2C_SendData(I2C_CH, u8DataAdr);

  171.     /* Wait transfer end*/
  172.     u32TimeOut = TIMEOUT;
  173.     while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
  174.     {
  175.         if(0ul == (u32TimeOut--))
  176.         {
  177.             return I2C_RET_ERROR;
  178.         }
  179.     }

  180.     /* Check ACK */
  181.     u32TimeOut = TIMEOUT;
  182.     while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
  183.     {
  184.         if(0ul == (u32TimeOut--))
  185.         {
  186.             return I2C_RET_ERROR;
  187.         }
  188.     }

  189.     return I2C_RET_OK;
  190. }

  191. /**
  192. ******************************************************************************
  193. ** \brief  Send data to e2prom
  194. **
  195. ** \param  pTxData  Pointer to the data buffer
  196. ** \param  u32Size  Data size
  197. **
  198. ** \retval Process result
  199. **         - I2C_RET_ERROR  Send failed
  200. **         - I2C_RET_OK     Send success
  201. ******************************************************************************/
  202. static uint8_t E2_WriteData(uint8_t *pTxData, uint32_t u32Size)
  203. {
  204.     uint32_t u32TimeOut = TIMEOUT;

  205.     while(u32Size--)
  206.     {
  207.         /* Wait tx buffer empty */
  208.         u32TimeOut = TIMEOUT;
  209.         while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TEMPTYF))
  210.         {
  211.             if(0ul == (u32TimeOut--))
  212.             {
  213.                 return I2C_RET_ERROR;
  214.             }
  215.         }

  216.         /* Send one byte data */
  217.         I2C_SendData(I2C_CH, *pTxData++);

  218.         /* Wait transfer end*/
  219.         u32TimeOut = TIMEOUT;
  220.         while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_TENDF))
  221.         {
  222.             if(0ul == (u32TimeOut--))
  223.             {
  224.                 return I2C_RET_ERROR;
  225.             }
  226.         }

  227.         /* Check ACK */
  228.         u32TimeOut = TIMEOUT;
  229.         while(Set == I2C_GetStatus(I2C_CH, I2C_SR_NACKDETECTF))
  230.         {
  231.             if(0ul == (u32TimeOut--))
  232.             {
  233.                 return I2C_RET_ERROR;
  234.             }
  235.         }
  236.     }

  237.     return I2C_RET_OK;
  238. }

  239. /**
  240. ******************************************************************************
  241. ** \brief  Receive data from e2prom
  242. **
  243. ** \param  pTxData  Pointer to the data buffer
  244. ** \param  u32Size  Data size
  245. **
  246. ** \retval Process result
  247. **         - I2C_RET_ERROR  Send failed
  248. **         - I2C_RET_OK     Send success
  249. ******************************************************************************/
  250. static uint8_t E2_RevData(uint8_t *pRxData, uint32_t u32Size)
  251. {
  252.     uint32_t u32TimeOut = TIMEOUT;

  253.     for(uint32_t i=0ul; i<u32Size; i++)
  254.     {
  255.         /* if the last byte receive, need config NACK*/
  256.         if(i == (u32Size - 1ul))
  257.         {
  258.             I2C_NackConfig(I2C_CH, Enable);
  259.         }

  260.         /* Wait receive full flag*/
  261.         u32TimeOut = TIMEOUT;
  262.         while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_RFULLF))
  263.         {
  264.             if(0ul == (u32TimeOut--))
  265.             {
  266.                 return I2C_RET_ERROR;
  267.             }
  268.         }

  269.         /* read data from register*/
  270.         *pRxData++ = I2C_ReadData(I2C_CH);
  271.     }

  272.     return I2C_RET_OK;
  273. }

  274. /**
  275. ******************************************************************************
  276. ** \brief  General stop condition to e2prom
  277. **
  278. ** \param  None
  279. **
  280. ** \retval Process result
  281. **         - I2C_RET_ERROR  Send failed
  282. **         - I2C_RET_OK     Send success
  283. ******************************************************************************/
  284. uint8_t E2_Stop(void)
  285. {
  286.     uint32_t u32TimeOut;

  287.     /* Wait I2C bus busy */
  288.     u32TimeOut = TIMEOUT;
  289.     while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_BUSY))
  290.     {
  291.         if(0ul == (u32TimeOut--))
  292.         {
  293.             return I2C_RET_ERROR;
  294.         }
  295.     }

  296.     I2C_GenerateStop(I2C_CH, Enable);

  297.     /* Wait STOPF */
  298.     u32TimeOut = TIMEOUT;
  299.     while(Reset == I2C_GetStatus(I2C_CH, I2C_SR_STOPF))
  300.     {
  301.         if(0ul == (u32TimeOut--))
  302.         {
  303.             return I2C_RET_ERROR;
  304.         }
  305.     }

  306.     return I2C_RET_OK;
  307. }

  308. /**
  309. ******************************************************************************
  310. ** \brief  Initialize the I2C peripheral for e2prom
  311. **
  312. ** \param  None
  313. **
  314. ** \retval Process result
  315. **         - I2C_RET_ERROR  failed
  316. **         - I2C_RET_OK     success
  317. ******************************************************************************/
  318. uint8_t E2_Initialize(void)
  319. {
  320.     stc_i2c_init_t stcI2cInit;
  321.     stc_clk_freq_t stcClkFreq;

  322.     I2C_DeInit(I2C_CH);

  323.     /* Get system clock frequency */
  324.     CLK_GetClockFreq(&stcClkFreq);

  325.     MEM_ZERO_STRUCT(stcI2cInit);
  326.     stcI2cInit.u32Pclk3 = stcClkFreq.pclk3Freq;
  327.     stcI2cInit.enI2cMode = I2cMaster;
  328.     stcI2cInit.u32Baudrate = 100000ul;
  329.     stcI2cInit.u32SclTime = 0ul;
  330.     I2C_Init(I2C_CH, &stcI2cInit);

  331.     I2C_Cmd(I2C_CH, Enable);

  332.     return I2C_RET_OK;
  333. }

  334. /**
  335. ******************************************************************************
  336. ** \brief  Initialize the system clock for the sample
  337. **
  338. ** \param  None
  339. **
  340. ** \retval None
  341. ******************************************************************************/
  342. static void SysClkIni(void)
  343. {
  344.     en_clk_sys_source_t     enSysClkSrc;
  345.     stc_clk_sysclk_cfg_t    stcSysClkCfg;
  346.     stc_clk_xtal_cfg_t      stcXtalCfg;
  347.     stc_clk_mpll_cfg_t      stcMpllCfg;

  348.     MEM_ZERO_STRUCT(enSysClkSrc);
  349.     MEM_ZERO_STRUCT(stcSysClkCfg);
  350.     MEM_ZERO_STRUCT(stcXtalCfg);
  351.     MEM_ZERO_STRUCT(stcMpllCfg);

  352.     /* Set bus clk div. */
  353.     stcSysClkCfg.enHclkDiv = ClkSysclkDiv1;   // Max 168MHz
  354.     stcSysClkCfg.enExclkDiv = ClkSysclkDiv2;  // Max 84MHz
  355.     stcSysClkCfg.enPclk0Div = ClkSysclkDiv1;  // Max 168MHz
  356.     stcSysClkCfg.enPclk1Div = ClkSysclkDiv2;  // Max 84MHz
  357.     stcSysClkCfg.enPclk2Div = ClkSysclkDiv4;  // Max 60MHz
  358.     stcSysClkCfg.enPclk3Div = ClkSysclkDiv4;  // Max 42MHz
  359.     stcSysClkCfg.enPclk4Div = ClkSysclkDiv2;  // Max 84MHz
  360.     CLK_SysClkConfig(&stcSysClkCfg);

  361.     /* Switch system clock source to MPLL. */
  362.     /* Use Xtal32 as MPLL source. */
  363.     stcXtalCfg.enMode = ClkXtalModeOsc;
  364.     stcXtalCfg.enDrv = ClkXtalLowDrv;
  365.     stcXtalCfg.enFastStartup = Enable;
  366.     CLK_XtalConfig(&stcXtalCfg);
  367.     CLK_XtalCmd(Enable);

  368.     /* MPLL config. */
  369.     stcMpllCfg.pllmDiv = 1u;
  370.     stcMpllCfg.plln =42u;
  371.     stcMpllCfg.PllpDiv = 2u;
  372.     stcMpllCfg.PllqDiv = 2u;
  373.     stcMpllCfg.PllrDiv = 2u;
  374.     CLK_SetPllSource(ClkPllSrcXTAL);
  375.     CLK_MpllConfig(&stcMpllCfg);

  376.     /* flash read wait cycle setting */
  377.     EFM_Unlock();
  378.     EFM_SetLatency(EFM_LATENCY_5);
  379.     EFM_Lock();

  380.     /* Enable MPLL. */
  381.     CLK_MpllCmd(Enable);

  382.     /* Wait MPLL ready. */
  383.     while(Set != CLK_GetFlagStatus(ClkFlagMPLLRdy))
  384.     {
  385.       ;
  386.     }

  387.     /* Switch system clock source to MPLL. */
  388.     CLK_SetSysClkSource(CLKSysSrcMPLL);
  389. }

  390. /**
  391. ******************************************************************************
  392. ** \brief  Judge the result. LED0 toggle when result is error status.
  393. **
  394. ** \param  u8Result
  395. **
  396. ** \retval None
  397. ******************************************************************************/
  398. static void JudgeResult(uint8_t u8Result)
  399. {
  400.     if(I2C_RET_ERROR == u8Result)
  401.     {
  402.         while(1)
  403.         {
  404.             LED0_TOGGLE();
  405.             Ddl_Delay1ms(500ul);
  406.         }
  407.     }
  408. }

  409. /**
  410. *******************************************************************************
  411. ** \brief  Main function of template project
  412. **
  413. ** \param  None
  414. **
  415. ** \retval int32_t return value, if needed
  416. **
  417. ******************************************************************************/
  418. int32_t main(void)
  419. {
  420.     uint8_t u8TxBuf[PAGE_LEN];
  421.     uint8_t u8RxBuf[PAGE_LEN];
  422.     uint32_t i;
  423.     uint8_t u8Ret = I2C_RET_OK;
  424.     stc_port_init_t stcPortInit;

  425.     for(i=0ul; i<PAGE_LEN; i++)
  426.     {
  427.         u8TxBuf[i] = (uint8_t)i+1u;
  428.     }
  429.     memset(u8RxBuf, 0x00, PAGE_LEN);

  430.     /* Initialize system clock*/
  431.     SysClkIni();

  432.     /*initiallize LED port*/
  433.     MEM_ZERO_STRUCT(stcPortInit);

  434.     stcPortInit.enPinMode = Pin_Mode_Out;
  435.     stcPortInit.enExInt = Enable;
  436.     stcPortInit.enPullUp = Enable;

  437.     /* LED0 Port/Pin initialization */
  438.     PORT_Init(LED0_PORT, LED0_PIN, &stcPortInit);

  439.     /* LED1 Port/Pin initialization */
  440.     PORT_Init(LED1_PORT, LED1_PIN, &stcPortInit);

  441.     /* Initialize I2C port*/
  442.     PORT_SetFunc(I2C1_SCL_PORT, I2C1_SCL_PIN, Func_I2c1_Scl, Disable);
  443.     PORT_SetFunc(I2C1_SDA_PORT, I2C1_SDA_PIN, Func_I2c1_Sda, Disable);

  444.     /* Enable I2C Peripheral*/
  445.     PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_I2C1, Enable);
  446.     /* Initialize I2C peripheral and enable function*/
  447.     E2_Initialize();

  448.     /* E2prom byte write*/
  449.     u8Ret = E2_StartOrRestart(GENERATE_START);
  450.     JudgeResult(u8Ret);
  451.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
  452.     JudgeResult(u8Ret);
  453.     u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
  454.     JudgeResult(u8Ret);
  455.     u8Ret = E2_WriteData(u8TxBuf, 1u);
  456.     JudgeResult(u8Ret);
  457.     u8Ret = E2_Stop();
  458.     JudgeResult(u8Ret);

  459.     /* 5mS delay for e2prom*/
  460.     Ddl_Delay1ms(5ul);

  461.     /* E2prom ramdom read*/
  462.     u8Ret = E2_StartOrRestart(GENERATE_START);
  463.     JudgeResult(u8Ret);
  464.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
  465.     JudgeResult(u8Ret);
  466.     u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
  467.     JudgeResult(u8Ret);

  468.     u8Ret = E2_StartOrRestart(GENERATE_RESTART);
  469.     JudgeResult(u8Ret);
  470.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_R);
  471.     JudgeResult(u8Ret);
  472.     u8Ret = E2_RevData(u8RxBuf, 1u);
  473.     JudgeResult(u8Ret);
  474.     u8Ret = E2_Stop();
  475.     JudgeResult(u8Ret);

  476.     /* Compare the data */
  477.     if(0x01u != u8RxBuf[0])
  478.     {
  479.         /* e2prom byte write error*/
  480.         while(1)
  481.         {
  482.             LED0_TOGGLE();
  483.             Ddl_Delay1ms(500ul);
  484.         }
  485.     }

  486.     /* 5mS delay for e2prom*/
  487.     Ddl_Delay1ms(5ul);
  488.     /* E2prom page write*/
  489.     u8Ret = E2_StartOrRestart(GENERATE_START);
  490.     JudgeResult(u8Ret);
  491.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
  492.     JudgeResult(u8Ret);
  493.     u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
  494.     JudgeResult(u8Ret);
  495.     u8Ret = E2_WriteData(u8TxBuf, PAGE_LEN);
  496.     JudgeResult(u8Ret);
  497.     u8Ret = E2_Stop();
  498.     JudgeResult(u8Ret);

  499.     /* 5mS delay for e2prom*/
  500.     Ddl_Delay1ms(5ul);

  501.     /* E2prom sequential read*/
  502.     u8Ret = E2_StartOrRestart(GENERATE_START);
  503.     JudgeResult(u8Ret);
  504.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_W);
  505.     JudgeResult(u8Ret);
  506.     u8Ret = E2_SendDataAdr(DATA_TEST_ADDR);
  507.     JudgeResult(u8Ret);

  508.     u8Ret = E2_StartOrRestart(GENERATE_RESTART);
  509.     JudgeResult(u8Ret);
  510.     u8Ret = E2_SendAdr((uint8_t)(E2_ADDRESS<<1u)|E2_ADDRESS_R);
  511.     JudgeResult(u8Ret);
  512.     u8Ret = E2_RevData(u8RxBuf, PAGE_LEN);
  513.     JudgeResult(u8Ret);
  514.     u8Ret = E2_Stop();
  515.     JudgeResult(u8Ret);

  516.     /* Compare the data */
  517.     for(i=0ul; i<PAGE_LEN; i++)
  518.     {
  519.         if(u8TxBuf[i] != u8RxBuf[i])
  520.         {
  521.             /* e2prom page write error*/
  522.             while(1)
  523.             {
  524.                 LED0_TOGGLE();
  525.                 Ddl_Delay1ms(500ul);
  526.             }
  527.         }
  528.     }

  529.     /* e2prom sample success*/
  530.     while(1)
  531.     {
  532.         LED1_TOGGLE();
  533.         Ddl_Delay1ms(500ul);
  534.     }
  535. }

  536. /*******************************************************************************
  537. * EOF (not truncated)
  538. ******************************************************************************/
效果图:
1.jpg
板子上LED2闪烁,读写正常。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3530

帖子

20

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