[其他ST产品] stm32下的IIC实现EEPROM代码-stm32G431RBT6

[复制链接]
736|27
 楼主| 工程师犹饿死 发表于 2022-12-29 23:52 | 显示全部楼层
  1. void eeprom_page_write(unsigned char adress,unsigned char *data,unsigned char num)
  2. {
  3.         I2CStart();
  4.         I2CSendByte(0xa0);
  5.         I2CWaitAck();
  6.        
  7.   I2CSendByte(adress);
  8.         I2CWaitAck();
  9.         while(num--)
  10.         {
  11.         I2CSendByte(*data++);
  12.         I2CWaitAck();
  13.         }
  14.         I2CStop();
  15. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:53 | 显示全部楼层
其他代码:

IIC.c:

  1. #include "i2c.h"

  2. #define DELAY_TIME        20


  3. /**
  4.   * [url=home.php?mod=space&uid=247401]@brief[/url] SDA线输入模式配置
  5.   * @param None
  6.   * @retval None
  7.   */
  8. void SDA_Input_Mode()
  9. {
  10.     GPIO_InitTypeDef GPIO_InitStructure = {0};

  11.     GPIO_InitStructure.Pin = GPIO_PIN_7;
  12.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  13.     GPIO_InitStructure.Pull = GPIO_PULLUP;
  14.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  15.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  16. }

  17. /**
  18.   * @brief SDA线输出模式配置
  19.   * @param None
  20.   * @retval None
  21.   */
  22. void SDA_Output_Mode()
  23. {
  24.     GPIO_InitTypeDef GPIO_InitStructure = {0};

  25.     GPIO_InitStructure.Pin = GPIO_PIN_7;
  26.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
  27.     GPIO_InitStructure.Pull = GPIO_NOPULL;
  28.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  29.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  30. }

  31. /**
  32.   * @brief SDA线输出一个位
  33.   * @param val 输出的数据
  34.   * @retval None
  35.   */
  36. void SDA_Output( uint16_t val )
  37. {
  38.     if ( val )
  39.     {
  40.         GPIOB->BSRR |= GPIO_PIN_7;
  41.     }
  42.     else
  43.     {
  44.         GPIOB->BRR |= GPIO_PIN_7;
  45.     }
  46. }

  47. /**
  48.   * @brief SCL线输出一个位
  49.   * @param val 输出的数据
  50.   * @retval None
  51.   */
  52. void SCL_Output( uint16_t val )
  53. {
  54.     if ( val )
  55.     {
  56.         GPIOB->BSRR |= GPIO_PIN_6;
  57.     }
  58.     else
  59.     {
  60.         GPIOB->BRR |= GPIO_PIN_6;
  61.     }
  62. }

  63. /**
  64.   * @brief SDA输入一位
  65.   * @param None
  66.   * @retval GPIO读入一位
  67.   */
  68. uint8_t SDA_Input(void)
  69. {
  70.         if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET){
  71.                 return 1;
  72.         }else{
  73.                 return 0;
  74.         }
  75. }


  76. /**
  77.   * @brief I2C的短暂延时
  78.   * @param None
  79.   * @retval None
  80.   */
  81. static void delay1(unsigned int n)
  82. {
  83.     uint32_t i;
  84.     for ( i = 0; i < n; ++i);
  85. }

  86. /**
  87.   * @brief I2C起始信号
  88.   * @param None
  89.   * @retval None
  90.   */
  91. void I2CStart(void)
  92. {
  93.     SDA_Output(1);
  94.     delay1(DELAY_TIME);
  95.     SCL_Output(1);
  96.     delay1(DELAY_TIME);
  97.     SDA_Output(0);
  98.     delay1(DELAY_TIME);
  99.     SCL_Output(0);
  100.     delay1(DELAY_TIME);
  101. }

  102. /**
  103.   * @brief I2C结束信号
  104.   * @param None
  105.   * @retval None
  106.   */
  107. void I2CStop(void)
  108. {
  109.     SCL_Output(0);
  110.     delay1(DELAY_TIME);
  111.     SDA_Output(0);
  112.     delay1(DELAY_TIME);
  113.     SCL_Output(1);
  114.     delay1(DELAY_TIME);
  115.     SDA_Output(1);
  116.     delay1(DELAY_TIME);

  117. }

  118. /**
  119.   * @brief I2C等待确认信号
  120.   * @param None
  121.   * @retval None
  122.   */
  123. unsigned char I2CWaitAck(void)
  124. {
  125.     unsigned short cErrTime = 5;
  126.     SDA_Input_Mode();
  127.     delay1(DELAY_TIME);
  128.     SCL_Output(1);
  129.     delay1(DELAY_TIME);
  130.     while(SDA_Input())
  131.     {
  132.         cErrTime--;
  133.         delay1(DELAY_TIME);
  134.         if (0 == cErrTime)
  135.         {
  136.             SDA_Output_Mode();
  137.             I2CStop();
  138.             return ERROR;
  139.         }
  140.     }
  141.     SDA_Output_Mode();
  142.     SCL_Output(0);
  143.     delay1(DELAY_TIME);
  144.     return SUCCESS;
  145. }

  146. /**
  147.   * @brief I2C发送确认信号
  148.   * @param None
  149.   * @retval None
  150.   */
  151. void I2CSendAck(void)
  152. {
  153.     SDA_Output(0);
  154.     delay1(DELAY_TIME);
  155.     delay1(DELAY_TIME);
  156.     SCL_Output(1);
  157.     delay1(DELAY_TIME);
  158.     SCL_Output(0);
  159.     delay1(DELAY_TIME);

  160. }

  161. /**
  162.   * @brief I2C发送非确认信号
  163.   * @param None
  164.   * @retval None
  165.   */
  166. void I2CSendNotAck(void)
  167. {
  168.     SDA_Output(1);
  169.     delay1(DELAY_TIME);
  170.     delay1(DELAY_TIME);
  171.     SCL_Output(1);
  172.     delay1(DELAY_TIME);
  173.     SCL_Output(0);
  174.     delay1(DELAY_TIME);

  175. }

  176. /**
  177.   * @brief I2C发送一个字节
  178.   * @param cSendByte 需要发送的字节
  179.   * @retval None
  180.   */
  181. void I2CSendByte(unsigned char cSendByte)
  182. {
  183.     unsigned char  i = 8;
  184.     while (i--)
  185.     {
  186.         SCL_Output(0);
  187.         delay1(DELAY_TIME);
  188.         SDA_Output(cSendByte & 0x80);
  189.         delay1(DELAY_TIME);
  190.         cSendByte += cSendByte;
  191.         delay1(DELAY_TIME);
  192.         SCL_Output(1);
  193.         delay1(DELAY_TIME);
  194.     }
  195.     SCL_Output(0);
  196.     delay1(DELAY_TIME);
  197. }

  198. /**
  199.   * @brief I2C接收一个字节
  200.   * @param None
  201.   * @retval 接收到的字节
  202.   */
  203. unsigned char I2CReceiveByte(void)
  204. {
  205.     unsigned char i = 8;
  206.     unsigned char cR_Byte = 0;
  207.     SDA_Input_Mode();
  208.     while (i--)
  209.     {
  210.         cR_Byte += cR_Byte;
  211.         SCL_Output(0);
  212.         delay1(DELAY_TIME);
  213.         delay1(DELAY_TIME);
  214.         SCL_Output(1);
  215.         delay1(DELAY_TIME);
  216.         cR_Byte |=  SDA_Input();
  217.     }
  218.     SCL_Output(0);
  219.     delay1(DELAY_TIME);
  220.     SDA_Output_Mode();
  221.     return cR_Byte;
  222. }

  223. //
  224. void I2CInit(void)
  225. {
  226.                 GPIO_InitTypeDef GPIO_InitStructure = {0};

  227.     GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_6;
  228.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  229.     GPIO_InitStructure.Pull = GPIO_PULLUP;
  230.     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  231.     HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  232. }
 楼主| 工程师犹饿死 发表于 2022-12-29 23:54 | 显示全部楼层
IIC.h:
  1. #ifndef __I2C_H
  2. #define __I2C_H

  3. #include "main.h"

  4. void I2CStart(void);
  5. void I2CStop(void);
  6. unsigned char I2CWaitAck(void);
  7. void I2CSendAck(void);
  8. void I2CSendNotAck(void);
  9. void I2CSendByte(unsigned char cSendByte);
  10. unsigned char I2CReceiveByte(void);
  11. void I2CInit(void);

  12. #endif
 楼主| 工程师犹饿死 发表于 2022-12-29 23:55 | 显示全部楼层
main函数初始化;
  1. MX_GPIO_Init();
  2. MX_TIM3_Init();
  3. I2CInit();
 楼主| 工程师犹饿死 发表于 2022-12-29 23:55 | 显示全部楼层
总结:

有人说EEPROM经不起快速的连续读写,所以在读和写之间加入20ms的delay,我没有试过。

还有一些问题没有解决。
 楼主| 工程师犹饿死 发表于 2022-12-29 23:56 | 显示全部楼层
寄掉了,昨天只能写入八个数据,今天发现可以随便页写,几个数据都行,一开始字节写第9位置以及后面都写不进去,突然想写多少个写多少个,懵圈了,咱也不知道,咱也不敢问,我没有在读和写之间加延时,不会是这个的问题吧?
 楼主| 工程师犹饿死 发表于 2022-12-29 23:57 | 显示全部楼层
试了一下,还真的是延时的问题,不能写完之后立马读,不然就是读出255.............
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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