[N32G430] 国民技术N32G430 I2C1 Master的设置

[复制链接]
946|6
 楼主| 呐咯密密 发表于 2024-6-28 11:26 | 显示全部楼层 |阅读模式
I2C1 Master的设置

1、将PB6 PB7 初始化为I2C1 的 master 模式,然后往AT24C02里写五个数据,然后读出来。

2、在Common里增加i2c.c i2c.h文件

i2c.c

  1. #include "main.h"
  2. #include "i2c.h"
  3. /**
  4. * PB6 PB7   初始化为I2C1  i2c master 模式
  5. * PB10 PB11 初始化为I2C2  i2c slaver 模式
  6. */

  7. #define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000)
  8. #define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))
  9. #define I2C_SLAVE_ADDR    0xA0

  10. static __IO uint32_t I2CTimeout;
  11. static CommCtrl_t Comm_Flag = C_READY;  


  12. static void CommTimeOut_CallBack(ErrCode_t errcode)
  13. {
  14.     max_print("...ErrCode:%d\r\n", errcode);
  15.    
  16. #if (COMM_RECOVER_MODE == MODULE_SELF_RESET)
  17.     IIC_SWReset();
  18. #elif (COMM_RECOVER_MODE == MODULE_RCC_RESET)
  19.     IIC_RCCReset();
  20. #elif (COMM_RECOVER_MODE == SYSTEM_NVIC_RESET)
  21.     SystemNVICReset();
  22. #endif
  23. }


  24. static void Delay(uint32_t nCount)
  25. {
  26.     uint32_t tcnt;
  27.     while (nCount--)
  28.     {
  29.         tcnt = 48000 / 5;
  30.         while (tcnt--){;}
  31.     }
  32. }

  33. static void Delay_us(uint32_t nCount)
  34. {
  35.     uint32_t tcnt;
  36.     while (nCount--)
  37.     {
  38.         tcnt = 48 / 5;
  39.         while (tcnt--){;}
  40.     }
  41. }


  42. MI_BOOL i2c1_init(void)
  43. {
  44.     /** GPIO configuration and clock enable */
  45.     GPIO_InitType GPIO_InitStructure;
  46.     I2C_InitType I2C_InitStructure;
  47.     #if PROCESS_MODE == 1 // interrupt
  48.     NVIC_InitType NVIC_InitStructure;
  49.     #endif

  50.     /** enable peripheral clk*/
  51.     RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_I2C1);
  52.     /* I2C1 Reset */
  53.     RCC_APB1_Peripheral_Reset(RCC_APB1_PERIPH_I2C1);
  54.     RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);

  55.     GPIO_Structure_Initialize(&GPIO_InitStructure);
  56.     GPIO_InitStructure.Pin            = GPIO_PIN_6 | GPIO_PIN_7;
  57.     GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_SLOW;
  58.     GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_AF_OD;
  59.     GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_I2C1;
  60.     GPIO_InitStructure.GPIO_Pull      = GPIO_PULL_UP;
  61.     GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);

  62.     /** I2C periphral configuration */
  63.     RCC_APB1_Peripheral_Reset(RCC_APB1_PERIPH_I2C1);
  64.     I2C_InitStructure.BusMode     = I2C_BUSMODE_I2C;
  65.     I2C_InitStructure.DutyCycle   = I2C_FMDUTYCYCLE_2;
  66.     I2C_InitStructure.OwnAddr1    = 0xff;
  67.     I2C_InitStructure.AckEnable   = I2C_ACKEN;
  68.     I2C_InitStructure.AddrMode    = I2C_ADDR_MODE_7BIT;
  69.     I2C_InitStructure.ClkSpeed    = 400000;  //400K
  70.     I2C_Initializes(I2C1, &I2C_InitStructure);
  71.    
  72.     I2C_ON(I2C1);
  73.     return MI_TRUE;
  74. }

  75. /**
  76. * i2c1 挂着一个AT24C02
  77. * 我们写入一个字节,读一个字节
  78. * 验证iic读写的函数即可。
  79. */

  80. MI_BOOL i2c_master_send_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *w_data,MI_U16 len)
  81. {
  82.     I2CTimeout = I2CT_LONG_TIMEOUT;
  83.     while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  84.     {
  85.         if ((I2CTimeout--) == 0)
  86.             CommTimeOut_CallBack(MASTER_BUSY);
  87.     }

  88.     /** Send START condition */
  89.     I2C_Generate_Start_Enable(I2C1);
  90.     /** Test on EV5 and clear it */
  91.     I2CTimeout = I2CT_LONG_TIMEOUT;
  92.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG))  /*EV5*/
  93.     {
  94.         if ((I2CTimeout--) == 0)
  95.             CommTimeOut_CallBack(MASTER_MODE);
  96.     }

  97.     /** Send slave address for write */
  98.     I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_SEND);
  99.     /** Test on EV6 and clear it */
  100.     I2CTimeout = I2CT_LONG_TIMEOUT;
  101.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG))
  102.     {
  103.         if ((I2CTimeout--) == 0)
  104.             CommTimeOut_CallBack(MASTER_TXMODE);

  105.     }

  106.     I2C_Data_Send(I2C1, reg_addr);
  107.     /** Test on EV8 and clear it */
  108.     I2CTimeout = I2CT_LONG_TIMEOUT;
  109.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
  110.     {
  111.         if ((I2CTimeout--) == 0)
  112.             CommTimeOut_CallBack(MASTER_SENDED);
  113.     }

  114.      /** While there is data to be written */
  115.     while (len--)
  116.     {
  117.         /** Send the current byte */
  118.         I2C_Data_Send(I2C1, *w_data);
  119.         /** Point to the next byte to be written */
  120.         w_data++;
  121.         /** Test on EV8 and clear it */
  122.         I2CTimeout = I2CT_LONG_TIMEOUT;
  123.         while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
  124.         {
  125.             if ((I2CTimeout--) == 0)
  126.                 CommTimeOut_CallBack(MASTER_SENDED);
  127.         }
  128.     }
  129.     /** Send STOP condition */
  130.     I2C_Generate_Stop_Enable(I2C1);
  131.     return MI_TRUE;
  132. }

  133. MI_BOOL i2c_master_receive_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *r_data,MI_U16 len)
  134. {
  135.     I2CTimeout = I2CT_LONG_TIMEOUT;
  136.     while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
  137.     {
  138.         if ((I2CTimeout--) == 0)
  139.             CommTimeOut_CallBack(MASTER_BUSY);
  140.     }

  141.     I2C_PEC_Position_Set(I2C1, I2C_PEC_POS_CURRENT);
  142.     I2C_Acknowledg_Enable(I2C1);
  143.    
  144.     /** Send START condition */
  145.     I2C_Generate_Start_Enable(I2C1);

  146.     /** Test on EV5 and clear it */
  147.     I2CTimeout = I2CT_LONG_TIMEOUT;
  148.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG))
  149.     {
  150.         if ((I2CTimeout--) == 0)
  151.             CommTimeOut_CallBack(MASTER_MODE);
  152.     }

  153.     /** Send slave address for write */
  154.     I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_SEND);
  155.     /** Test on EV6 and clear it */
  156.     I2CTimeout = I2CT_LONG_TIMEOUT;
  157.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG))
  158.     {
  159.         if ((I2CTimeout--) == 0)
  160.             CommTimeOut_CallBack(MASTER_TXMODE);
  161.     }

  162.     I2C_ON(I2C1);
  163.     /** Send the slave's internal address to write to */
  164.     I2C_Data_Send(I2C1, reg_addr);
  165.     /** Test on EV8 and clear it */
  166.     I2CTimeout = I2CT_LONG_TIMEOUT;
  167.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
  168.     {
  169.         if ((I2CTimeout--) == 0)
  170.             CommTimeOut_CallBack(MASTER_SENDED);
  171.     }
  172.     I2C_Generate_Stop_Enable(I2C1);

  173.     /** Send STRAT condition a second time */
  174.     I2C_Generate_Start_Enable(I2C1);
  175.     /** Test on EV5 and clear it */
  176.     I2CTimeout = I2CT_LONG_TIMEOUT;
  177.     while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG))
  178.     {
  179.         if ((I2CTimeout--) == 0)
  180.             CommTimeOut_CallBack(MASTER_MODE);
  181.     }

  182.     /** Send slave address for read */
  183.     I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_RECV);
  184.     /* Test on EV6 and clear it */
  185.     I2CTimeout = I2CT_LONG_TIMEOUT;
  186.     while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_ADDRF))    //EV6
  187.     {
  188.         if ((I2CTimeout--) == 0)
  189.             CommTimeOut_CallBack(MASTER_RECVD);
  190.     }

  191.     /** While there is data to be read */
  192.     if (len == 1)
  193.     {
  194.         /** Disable Acknowledgement */
  195.         I2C_Acknowledg_Disable(I2C1);
  196.         /** clear ADDR */
  197.         (void)(I2C1->STS1);
  198.         (void)(I2C1->STS2);
  199.         /** Generates START condition to close communication */
  200.         I2C_Generate_Start_Enable(I2C1);
  201.     }
  202.     else
  203.     {
  204.         /** clear ADDR */
  205.         (void)(I2C1->STS1);
  206.         (void)(I2C1->STS2);
  207.     }

  208.     while (len)
  209.     {
  210.         if (len <= 2)
  211.         {
  212.             /** One byte */
  213.             if (len == 1)
  214.             {
  215.                 /** Wait until RXNE flag is set */
  216.                 I2CTimeout = I2CT_LONG_TIMEOUT;
  217.                 while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
  218.                 {
  219.                     if ((I2CTimeout--) == 0)
  220.                         CommTimeOut_CallBack(MASTER_RECVD);
  221.                 }
  222.                 /** Read data from DAT */
  223.                 *r_data = I2C_Data_Recv(I2C1);
  224.                 /** Point to the next location where the byte read will be saved */
  225.                 r_data++;
  226.                 /** Decrement the read bytes counter */
  227.                 len--;
  228.                  /** Generates STOP condition to release SCL/SDA line */
  229.                 I2C_Generate_Stop_Enable(I2C1);   
  230.             
  231.             }
  232.             /** 2 Last bytes */
  233.             else
  234.             {   
  235.                 /** Wait until RXNE flag is set */
  236.                 I2CTimeout = I2CT_LONG_TIMEOUT;
  237.                 while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
  238.                 {
  239.                     if ((I2CTimeout--) == 0)
  240.                         CommTimeOut_CallBack(MASTER_RECVD);
  241.                 }
  242.                 /** Disable Acknowledgement */
  243.                 I2C_Acknowledg_Disable(I2C1);
  244.                               
  245.                 /** Read data from DAT */
  246.                 *r_data = I2C_Data_Recv(I2C1);
  247.                 /** Point to the next location where the byte read will be saved */
  248.                 r_data++;
  249.                 /** Decrement the read bytes counter */
  250.                 len--;
  251.                
  252.                 /** Generates START condition to close communication */
  253.                 I2C_Generate_Start_Enable(I2C1);
  254.                
  255.                 while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
  256.                 {
  257.                     if ((I2CTimeout--) == 0)
  258.                         CommTimeOut_CallBack(MASTER_RECVD);
  259.                 }                                                
  260.                 /** Read data from DAT */
  261.                 *r_data = I2C_Data_Recv(I2C1);              
  262.                 /** Point to the next location where the byte read will be saved */
  263.                 r_data++;
  264.                 /** Decrement the read bytes counter */
  265.                 len--;
  266.                
  267.                 /** Generates STOP condition to release SCL/SDA line */
  268.                 I2C_Generate_Stop_Enable(I2C1);
  269.             }
  270.         }
  271.         else
  272.         {
  273.             /** Test on EV7 and clear it */
  274.             I2CTimeout = I2CT_LONG_TIMEOUT;
  275.             while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
  276.             {
  277.                 if ((I2CTimeout--) == 0)
  278.                     CommTimeOut_CallBack(MASTER_RECVD);
  279.             }
  280.             /** Read a byte from the EEPROM */
  281.             *r_data = I2C_Data_Recv(I2C1);
  282.             /** Point to the next location where the byte read will be saved */
  283.             r_data++;
  284.             /** Decrement the read bytes counter */
  285.             len--;
  286.             if (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
  287.             {
  288.                 /** Read a byte from the EEPROM */
  289.                 *r_data = I2C_Data_Recv(I2C1);
  290.                 /** Point to the next location where the byte read will be saved */
  291.                 r_data++;
  292.                 /** Decrement the read bytes counter */
  293.                 len--;
  294.             }
  295.         }
  296.     }

  297.     return MI_TRUE;
  298. }

i2c.h

  1. #ifndef __I2C_H__
  2. #define __I2C_H__
  3. #include "type.h"

  4. #define NON_REENTRANT

  5. typedef enum
  6. {
  7.     FAILED = 0,
  8.     PASSED = !FAILED
  9. } Status;

  10. typedef enum
  11. {
  12.     C_READY = 0,
  13.     C_START_BIT,
  14.     C_STOP_BIT
  15. }CommCtrl_t;

  16. typedef enum
  17. {
  18.     MASTER_OK = 0,
  19.     MASTER_BUSY,
  20.     MASTER_MODE,
  21.     MASTER_TXMODE,
  22.     MASTER_RXMODE,
  23.     MASTER_SENDING,
  24.     MASTER_SENDED,
  25.     MASTER_RECVD,
  26.     MASTER_BYTEF,
  27.     MASTER_BUSERR,
  28.     MASTER_UNKNOW,
  29.     SLAVE_OK = 20,
  30.     SLAVE_BUSY,
  31.     SLAVE_MODE,
  32.     SLAVE_BUSERR,
  33.     SLAVE_UNKNOW,

  34. }ErrCode_t;

  35. #define MODULE_SELF_RESET       1
  36. #define MODULE_RCC_RESET        2
  37. #define SYSTEM_NVIC_RESET       3
  38. #define COMM_RECOVER_MODE       0

  39. MI_BOOL i2c1_init(void);
  40. MI_BOOL i2c_master_send_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *w_data,MI_U16 len);
  41. MI_BOOL i2c_master_receive_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *r_data,MI_U16 len);

  42. #endif
  1. MI_U8 w_read[5] = {0x50,0x60,0x70,0xf4,0x68};
  2.         SysTick_Delay_Ms(5000);
  3.         i2c1_init();
  4.         i2c_master_send_bytes_by_addr(0xa0,0x00,w_read,5);
  5.         SysTick_Delay_Us(5000);

  6.         MI_U8 r_data[5] = {0};
  7.         i2c_master_receive_bytes_by_addr(0xa0,0x00,r_data,5);


结合国际经验 发表于 2024-8-31 20:01 | 显示全部楼层
为了完成你的任务,我们需要在 STM32 上配置 I2C1 作为 Master,并实现与 AT24C02 EEPROM 的读写操作。
结合国际经验 发表于 2024-8-31 20:01 | 显示全部楼层
需要确保 I2C1_ADDRESS 与 EEPROM 的实际地址一致。
结合国际经验 发表于 2024-8-31 20:01 | 显示全部楼层
目前你使用的是轮询模式进行 I2C 操作。如果系统对延迟较敏感,考虑使用中断模式来提高效率和响应性。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:苏州澜宭自动化科技嵌入式工程师
简介:本人从事磁编码器研发工作,负责开发2500线增量式磁编码器以及17位、23位绝对值式磁编码器,拥有多年嵌入式开发经验,精通STM32、GD32、N32等多种品牌单片机,熟练使用单片机各种外设。

568

主题

4085

帖子

56

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