STM32:I2C接口读写EEPROM(AT24C02)试验例程

发布者:camuspyc最新更新时间:2017-09-21 来源: eefocus关键字:STM32  I2C接口  读写EEPROM 手机看文章 扫描二维码
随时随地手机看文章

硬件平台:stm32f10xZET6
开发环境:keil MDK uVisionv4.10
开发语言:C、ST_lib_3.5固件库

EEPROM:电可擦可编程只读存储器。

【stm32f10xZET6开发板的I2C外设物理层特点】
(1)两条串行总线:一条双向数据线(SDA),一条时钟线(SCL);
(2)从设备地址唯一;
(3)支持总线仲裁;
(4)三种速率传输模式:
    标准模式100kbit/s
    快速模式400kbit/s
    高速模式3.4Mbit/s (目前大多I2C设备尚不支持高速模式)
(5)片上的滤波器可以滤去总线数据线上的毛刺波保证数据完整;
(6)连接到相同总线的IC数量受到总线的最大电容400pF限制;

【I2C接口特性】
(1) STM32 中和大容量型号芯片均有多达 2 个I2C总线接口;
(2) 能够工作于多主机或多从机模式,主从均可收发;
(3) 支持标准模式 100Kbit/s 和快速模式 400Kbit/s,不支持高
速模式;
(4) 支持 7 位或 10 位从设备地址寻址;
(5) 内置了硬件 CRC 发生器/ 校验器;
(6) I2C 的接收和发送都可以使用 DMA 操作;
(7) 支持系统管理总线(SMBus)总线 2.0 版;

typedef struct
{
  uint32_t I2C_ClockSpeed;          /*!< 指定时钟总线速率,100/400kHz */
  uint16_t I2C_Mode;                /*!< 指定为I2C通信模式 */
  uint16_t I2C_DutyCycle;           /*!< 指定I2C快速模式 */
  uint16_t I2C_OwnAddress1;         /*!< 指定从设备自身地址,7/10bit(地址0x0A对应宏) */
  uint16_t I2C_Ack;                 /*!< 使能或禁止ack */
  uint16_t I2C_AcknowledgedAddress; /*!< 指定7/10bit从设备地址下的ack */
} I2C_InitTypeDef;

在 stm32 如何建立与 EEPROM 的通讯步骤:
(1) 配置 I/O 端口,确定并配置 I2C 的模式,使能 GPIO 和 I2C
时钟。
(2) 写:
    1) 检测 SDA 是否空闲;
    2) 按 I2C 协议发出起始信号;
    3) 发出 7 位器件地址和写模式;
    4) 要写入的存储区首地址;
    5) 用页写入方式或字节写入方式写入数据;
    6) 发送 I2C 通讯结束讯信号
每个操作之后要检测“事件”确定是否成功。写完后检测 EEPROM 是否进
入 standby 状态。
(3) 读:
    1) 检测 SDA 是否空闲;
    2) 按 I2C 协议发出起始讯号;
    3) 发出 7 位器件地址和写模式(伪写);
    4) 发出要读取的存储区首地址;
    5) 重发起始讯号;第 260 页 共 729 页
    6) 发出 7 位器件地址和读模式;
    7) 接收数据;
类似写操作,每个操作之后要检测“事件”确定是否成功。

I2C_GenerateSTART();    // 产生 I2C 的通讯起始信号 S
I2C_Send7bitAddress();  // 发送7位从设备地址
I2C_SendData();         // 发送一个数据字节(8bit)
I2C_GenerateSTOP();     // 产生 I2C 的通讯停止信号 P
I2C_CheckEvent ();      // I2C 传输时的事件监测

  1. /* 代码演示 - mian.c */  

  2. /** 

  3.   ****************************************************************************** 

  4.   * @file    main.c 

  5.   * @author  fire 

  6.   * @version V1.0 

  7.   * @date    2013-xx-xx 

  8.   * @brief   I2C EEPROM(AT24C02)测试,测试信息通过USART1打印在电脑的超级终端 

  9.   ****************************************************************************** 

  10.   */  

  11.     

  12. #include "stm32f10x.h"  

  13. #include "bsp_usart1.h"  

  14. #include "bsP_i2c_ee.h"  

  15. #include "bsP_led.h"  

  16. #include   

  17.   

  18. #define  EEP_Firstpage      0x00  

  19. u8 I2c_Buf_Write[256];  

  20. u8 I2c_Buf_Read[256];  

  21. void I2C_Test(void);  

  22.   

  23. /** 

  24.   * @brief  主函数 

  25.   * @param  无 

  26.   * @retval 无 

  27.   */  

  28. int main(void)  

  29. {   

  30.     

  31.   /* 串口1初始化 */  

  32.     USART1_Config();  

  33.       

  34.     printf("\r\n 这是一个I2C外设(AT24C02)读写测试例程 \r\n");  

  35.     //LED_GPIO_Config();  

  36.   

  37.   

  38.     /* I2C 外设初(AT24C02)始化 */  

  39.     I2C_EE_Init();  

  40.   

  41.   

  42.     printf("\r\n 这是一个I2C外设(AT24C02)读写测试例程 \r\n");     

  43.            

  44.     I2C_Test();  

  45.     

  46.   while (1)  

  47.   {        

  48.   }  

  49. }  

  50.   

  51. /** 

  52.   * @brief  I2C(AT24C02)读写测试 

  53.   * @param  无 

  54.   * @retval 无 

  55.   */  

  56. void I2C_Test(void)  

  57. {  

  58.     u16 i;  

  59.   

  60.   

  61.     printf("写入的数据\n\r");  

  62.       

  63.     for ( i=0; i<=255; i++ ) // 填充缓冲  

  64.   {                              

  65.     I2c_Buf_Write[i] = i;  

  66.   

  67.   

  68.     printf("0x%02X ", I2c_Buf_Write[i]);  

  69.     if(i%16 == 15)      

  70.         printf("\n\r");      

  71.    }  

  72.   

  73.     //将I2c_Buf_Write中顺序递增的数据写入EERPOM中   

  74.     //LED1(ON);  

  75.     I2C_EE_BufferWrite (I2c_Buf_Write, EEP_Firstpage, 256);  

  76.     //LED1(OFF);     

  77.     

  78.   printf("\n\r写成功\n\r");  

  79.      

  80.    printf("\n\r读出的数据\n\r");  

  81.   //将EEPROM读出数据顺序保持到I2c_Buf_Read中  

  82.     //LED2(ON);     

  83.     I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256);   

  84.    //LED2(OFF);  

  85.      

  86.   //将I2c_Buf_Read中的数据通过串口打印  

  87.     for (i=0; i<256; i++)  

  88.     {     

  89.         if(I2c_Buf_Read[i] != I2c_Buf_Write[i])  

  90.         {  

  91.             printf("0x%02X ", I2c_Buf_Read[i]);  

  92.             printf("错误:I2C EEPROM写入与读出的数据不一致\n\r");  

  93.             return;  

  94.         }  

  95.     printf("0x%02X ", I2c_Buf_Read[i]);  

  96.     if(i%16 == 15)      

  97.         printf("\n\r");  

  98.       

  99.     }  

  100.   printf("I2C(AT24C02)读写测试成功\n\r");  

  101. }  

  102.   

  103. /* 代码演示 - bsp_i2c_ee模块 */  

  104. #ifndef __I2C_EE_H  

  105. #define __I2C_EE_H  

  106.   

  107. #include "stm32f10x.h"  

  108.   

  109. /*  

  110.  * AT24C02 2kb = 2048bit = 2048/8 B = 256 B 

  111.  * 32 pages of 8 bytes each 

  112.  * 

  113.  * Device Address 

  114.  * 1 0 1 0 A2 A1 A0 R/W 

  115.  * 1 0 1 0 0  0  0  0 = 0XA0 

  116.  * 1 0 1 0 0  0  0  1 = 0XA1  

  117.  */  

  118.   

  119. /* EEPROM Addresses defines */  

  120. #define EEPROM_Block0_ADDRESS   0xA0 /* E2 = 0 */  

  121. //#define EEPROM_Block1_ADDRESS 0xA2 /* E2 = 0 */  

  122. //#define EEPROM_Block2_ADDRESS 0xA4 /* E2 = 0 */  

  123. //#define EEPROM_Block3_ADDRESS 0xA6 /* E2 = 0 */  

  124.   

  125. void I2C_EE_Init(void);  

  126. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite);  

  127. void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr);  

  128. void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite);  

  129. void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead);  

  130. void I2C_EE_WaitEepromStandbyState(void);  

  131.   

  132. #endif /* __I2C_EE_H */  

  133.   

  134. //--------------------------------------------------------  

  135. /** 

  136.   ****************************************************************************** 

  137.   * @file    bsp_i2c_ee.c 

  138.   * @author  STMicroelectronics 

  139.   * @version V1.0 

  140.   * @date    2013-xx-xx 

  141.   * @brief   i2c EEPROM(AT24C02)应用函数bsp 

  142.   ****************************************************************************** 

  143.   */   

  144.   

  145. #include "bsp_i2c_ee.h"  

  146.   

  147. /* STM32 I2C 快速模式 */  

  148. #define I2C_Speed              400000  

  149.   

  150. /* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */  

  151. #define I2C1_OWN_ADDRESS7      0X0A     

  152.   

  153. /* AT24C01/02每页有8个字节 */  

  154. #define I2C_PageSize           8  

  155.   

  156. /* AT24C04/08A/16A每页有16个字节 */  

  157. //#define I2C_PageSize           16           

  158.   

  159. uint16_t EEPROM_ADDRESS;  

  160.   

  161. /** 

  162.   * @brief  I2C1 I/O配置 

  163.   * @param  无 

  164.   * @retval 无 

  165.   */  

  166. static void I2C_GPIO_Config(void)  

  167. {  

  168.   GPIO_InitTypeDef  GPIO_InitStructure;   

  169.   

  170.   /* 使能与 I2C1 有关的时钟 */  

  171.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  

  172.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);    

  173.       

  174.   /* PB6-I2C1_SCL、PB7-I2C1_SDA*/  

  175.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;  

  176.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  177.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;          // 开漏输出  

  178.   GPIO_Init(GPIOB, &GPIO_InitStructure);  

  179. }  

  180.   

  181. /** 

  182.   * @brief  I2C 工作模式配置 

  183.   * @param  无 

  184.   * @retval 无 

  185.   */  

  186. static void I2C_Mode_Configu(void)  

  187. {  

  188.   I2C_InitTypeDef  I2C_InitStructure;   

  189.   

  190.   /* I2C 配置 */  

  191.   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;  

  192.       

  193.   /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */  

  194.   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  

  195.       

  196.   I2C_InitStructure.I2C_OwnAddress1 = I2C1_OWN_ADDRESS7;   

  197.   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;  

  198.       

  199.   /* I2C的寻址模式 */  

  200.   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  

  201.       

  202.   /* 通信速率 */  

  203.   I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;  

  204.     

  205.   /* I2C1 初始化 */  

  206.   I2C_Init(I2C1, &I2C_InitStructure);  

  207.     

  208.   /* 使能 I2C1 */  

  209.   I2C_Cmd(I2C1, ENABLE);     

  210. }  

  211.   

  212. /** 

  213.   * @brief  I2C 外设(EEPROM)初始化 

  214.   * @param  无 

  215.   * @retval 无 

  216.   */  

  217. void I2C_EE_Init(void)  

  218. {  

  219.   

  220.   I2C_GPIO_Config();   

  221.    

  222.   I2C_Mode_Configu();  

  223.   

  224. /* 根据头文件i2c_ee.h中的定义来选择EEPROM要写入的地址 */  

  225. #ifdef EEPROM_Block0_ADDRESS  

  226.   /* 选择 EEPROM Block0 来写入 */  

  227.   EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;  

  228. #endif  

  229.   

  230. #ifdef EEPROM_Block1_ADDRESS    

  231.     /* 选择 EEPROM Block1 来写入 */  

  232.   EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;  

  233. #endif  

  234.   

  235. #ifdef EEPROM_Block2_ADDRESS    

  236.     /* 选择 EEPROM Block2 来写入 */  

  237.   EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;  

  238. #endif  

  239.   

  240. #ifdef EEPROM_Block3_ADDRESS    

  241.     /* 选择 EEPROM Block3 来写入 */  

  242.   EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;  

  243. #endif  

  244. }  

  245.   

  246. /** 

  247.   * @brief   将缓冲区中的数据写到I2C EEPROM中 

  248.   * @param    

  249.   *     @arg pBuffer:缓冲区指针 

  250.   *     @arg WriteAddr:写地址 

  251.   *     @arg NumByteToWrite:写的字节数 

  252.   * @retval  无 

  253.   */  

  254. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)  

  255. {  

  256.   u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;  

  257.   

  258.   Addr = WriteAddr % I2C_PageSize;              // addr = 8bit % 8  

  259.   count = I2C_PageSize - Addr;                  // 8 - addr  

  260.   NumOfPage =  NumByteToWrite / I2C_PageSize;  

  261.   NumOfSingle = NumByteToWrite % I2C_PageSize;  

  262.    

  263.   /* If WriteAddr is I2C_PageSize aligned  */  

  264.   if(Addr == 0)   

  265.   {  

  266.     /* If NumByteToWrite < I2C_PageSize */  

  267.     if(NumOfPage == 0)   

  268.     {  

  269.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);  

  270.       I2C_EE_WaitEepromStandbyState();  

  271.     }  

  272.     /* If NumByteToWrite > I2C_PageSize */  

  273.     else    

  274.     {  

  275.       while(NumOfPage--)  

  276.       {  

  277.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);   

  278.         I2C_EE_WaitEepromStandbyState();  

  279.         WriteAddr +=  I2C_PageSize;  

  280.         pBuffer += I2C_PageSize;  

  281.       }  

  282.   

  283.       if(NumOfSingle!=0)  

  284.       {  

  285.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);  

  286.         I2C_EE_WaitEepromStandbyState();  

  287.       }  

  288.     }  

  289.   }  

  290.   /* If WriteAddr is not I2C_PageSize aligned  */  

  291.   else   

  292.   {  

  293.     /* If NumByteToWrite < I2C_PageSize */  

  294.     if(NumOfPage== 0)   

  295.     {  

  296.       I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);  

  297.       I2C_EE_WaitEepromStandbyState();  

  298.     }  

  299.     /* If NumByteToWrite > I2C_PageSize */  

  300.     else  

  301.     {  

  302.       NumByteToWrite -= count;  

  303.       NumOfPage =  NumByteToWrite / I2C_PageSize;  

  304.       NumOfSingle = NumByteToWrite % I2C_PageSize;    

  305.         

  306.       if(count != 0)  

  307.       {    

  308.         I2C_EE_PageWrite(pBuffer, WriteAddr, count);  

  309.         I2C_EE_WaitEepromStandbyState();  

  310.         WriteAddr += count;  

  311.         pBuffer += count;  

  312.       }   

  313.         

  314.       while(NumOfPage--)  

  315.       {  

  316.         I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);  

  317.         I2C_EE_WaitEepromStandbyState();  

  318.         WriteAddr +=  I2C_PageSize;  

  319.         pBuffer += I2C_PageSize;    

  320.       }  

  321.       if(NumOfSingle != 0)  

  322.       {  

  323.         I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);   

  324.         I2C_EE_WaitEepromStandbyState();  

  325.       }  

  326.     }  

  327.   }    

  328. }  

  329.   

  330. /** 

  331.   * @brief   写一个字节到I2C EEPROM中 

  332.   * @param    

  333.   *     @arg pBuffer:缓冲区指针 

  334.   *     @arg WriteAddr:写地址  

  335.   * @retval  无 

  336.   */  

  337. void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)  

  338. {  

  339.   /* Send STRAT condition */  

  340.   I2C_GenerateSTART(I2C1, ENABLE);  

  341.   

  342.   /* Test on EV5 and clear it */  

  343.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));    

  344.   

  345.   /* Send EEPROM address for write */  

  346.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);  

  347.     

  348.   /* Test on EV6 and clear it */  

  349.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

  350.         

  351.   /* Send the EEPROM's internal address to write to */  

  352.   I2C_SendData(I2C1, WriteAddr);  

  353.     

  354.   /* Test on EV8 and clear it */  

  355.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  

  356.   

  357.   /* Send the byte to be written */  

  358.   I2C_SendData(I2C1, *pBuffer);   

  359.      

  360.   /* Test on EV8 and clear it */  

  361.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  

  362.     

  363.   /* Send STOP condition */  

  364.   I2C_GenerateSTOP(I2C1, ENABLE);  

  365. }  

  366.   

  367. /** 

  368.   * @brief   在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数 

  369.   *          不能超过EEPROM页的大小,AT24C02每页有8个字节 

  370.   * @param    

  371.   *     @arg pBuffer:缓冲区指针 

  372.   *     @arg WriteAddr:写地址 

  373.   *     @arg NumByteToWrite:写的字节数 

  374.   * @retval  无 

  375.   */  

  376. void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)  

  377. {  

  378.     while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008  

  379.       

  380.   /* 发送start信号 */  

  381.   I2C_GenerateSTART(I2C1, ENABLE);  

  382.     

  383.   /* Test on EV5 and clear it */  

  384.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));   

  385.     

  386.   /* Send EEPROM address for write */  

  387.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);  

  388.     

  389.   /* Test on EV6 and clear it */  

  390.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));    

  391.   

  392.   /* Send the EEPROM's internal address to write to */      

  393.   I2C_SendData(I2C1, WriteAddr);    

  394.   

  395.   /* Test on EV8 and clear it */  

  396.   while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  

  397.   

  398.   /* While there is data to be written */  

  399.   while(NumByteToWrite--)    

  400.   {  

  401.     /* Send the current byte */  

  402.     I2C_SendData(I2C1, *pBuffer);   

  403.   

  404.     /* Point to the next byte to be written */  

  405.     pBuffer++;   

  406.     

  407.     /* Test on EV8 and clear it */  

  408.     while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  

  409.   }  

  410.   

  411.   /* Send STOP condition */  

  412.   I2C_GenerateSTOP(I2C1, ENABLE);  

  413. }  

  414.   

  415. /** 

  416.   * @brief   从EEPROM里面读取一块数据  

  417.   * @param    

  418.   *     @arg pBuffer:存放从EEPROM读取的数据的缓冲区指针 

  419.   *     @arg WriteAddr:接收数据的EEPROM的地址 

  420.   *     @arg NumByteToWrite:要从EEPROM读取的字节数 

  421.   * @retval  无 

  422.   */  

  423. void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)  

  424. {    

  425.   //*((u8 *)0x4001080c) |=0x80;   

  426.     while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua 27/08/2008      

  427.       

  428.   /* Send START condition */  

  429.   I2C_GenerateSTART(I2C1, ENABLE);  

  430.   //*((u8 *)0x4001080c) &=~0x80;  

  431.     

  432.   /* Test on EV5 and clear it */  

  433.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  

  434.   

  435.   /* Send EEPROM address for write */  

  436.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);  

  437.   

  438.   /* Test on EV6 and clear it */  

  439.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  

  440.     

  441.   /* Clear EV6 by setting again the PE bit */  

  442.   I2C_Cmd(I2C1, ENABLE);  

  443.   

  444.   /* Send the EEPROM's internal address to write to */  

  445.   I2C_SendData(I2C1, ReadAddr);    

  446.   

  447.   /* Test on EV8 and clear it */  

  448.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  

  449.     

  450.   /* Send STRAT condition a second time */    

  451.   I2C_GenerateSTART(I2C1, ENABLE);  

  452.     

  453.   /* Test on EV5 and clear it */  

  454.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  

  455.     

  456.   /* Send EEPROM address for read */  

  457.   I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);  

  458.     

  459.   /* Test on EV6 and clear it */  

  460.   while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  

  461.     

  462.   /* While there is data to be read */  

  463.   while(NumByteToRead)    

  464.   {  

  465.     if(NumByteToRead == 1)  

  466.     {  

  467.       /* Disable Acknowledgement */  

  468.       I2C_AcknowledgeConfig(I2C1, DISABLE);  

  469.         

  470.       /* Send STOP Condition */  

  471.       I2C_GenerateSTOP(I2C1, ENABLE);  

  472.     }  

  473.   

  474.     /* Test on EV7 and clear it */  

  475.     if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))    

  476.     {        

  477.       /* Read a byte from the EEPROM */  

  478.       *pBuffer = I2C_ReceiveData(I2C1);  

  479.   

  480.       /* Point to the next location where the byte read will be saved */  

  481.       pBuffer++;   

  482.         

  483.       /* Decrement the read bytes counter */  

  484.       NumByteToRead--;          

  485.     }     

  486.   }  

  487.   

  488.   /* Enable Acknowledgement to be ready for another reception */  

  489.   I2C_AcknowledgeConfig(I2C1, ENABLE);  

  490. }  

  491.   

  492. /** 

  493.   * @brief  Wait for EEPROM Standby state  

  494.   * @param  无 

  495.   * @retval 无 

  496.   */  

  497. void I2C_EE_WaitEepromStandbyState(void)        

  498. {  

  499.   vu16 SR1_Tmp = 0;  

  500.   

  501.   do  

  502.   {  

  503.     /* Send START condition */  

  504.     I2C_GenerateSTART(I2C1, ENABLE);  

  505.     /* Read I2C1 SR1 register */  

  506.     SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);  

  507.     /* Send EEPROM address for write */  

  508.     I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);  

  509.   }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));  

  510.     

  511.   /* Clear AF flag */  

  512.   I2C_ClearFlag(I2C1, I2C_FLAG_AF);  

  513.     /* STOP condition */      

  514.     I2C_GenerateSTOP(I2C1, ENABLE);   

  515. }  





关键字:STM32  I2C接口  读写EEPROM 引用地址:STM32:I2C接口读写EEPROM(AT24C02)试验例程

上一篇:STM32:USART串口通信笔记
下一篇:STM32:ADC采集数据实例(采用DMA模式)

推荐阅读最新更新时间:2024-03-16 15:37

stm32定时器捕捉高低电平计时长代码分析
定时器是stm32的一大利器,现在的项目中可以说没有一个不会用到定时器的,所以掌握理解运用定时器才会做出好的产品来。 本章内容说一说关于stm32的定时器TIM_GetCounter(TIMx)的运用。之前的项目中曾经用这个来获取高低电平的时长,在超声波测距,红外遥控解码中运用过。Stm32的定时器除了1和8其他都是通用定时器。如何用这句函数来捕捉电平时长呢?首先看一下初始化内容,以TIM4为例 void Timer4_CFG() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1Per
[单片机]
STM32的三种开发模式
寄存器,固件库,操作系统
[单片机]
<font color='red'>STM32</font>的三种开发模式
用qt编写上位机与stm32通信
好的文章 1、Qt5.5.1实现通用串口程序https://www.2cto.com/kf/201607/524028.html 2、QT实现串口通信 https://www.2cto.com/kf/201610/558768.html 资源下载:https://download.csdn.net/download/hellybobo/9950904?web=web 本文采用的的开发环境是VS2010+Qt5.5.1版本,所有程序不是通过Qt Creator编译的,如果有需要可以介绍VS2010和Qt环境的搭建和简单的使用。 QSerialPort QSerialPort这个类是从QT5.1开始引入的,之前都是通过
[单片机]
用qt编写上位机与<font color='red'>stm32</font>通信
STM32使用HAL库驱动USART详解及例程
HAL库串口驱动详解 STM32硬件串口收发数据过程 串口发送流程–TXD 配置步骤: 编程USARTx_CR1的M位来定义字长。 编程USARTx_CR2的STOP位来定义停止位位数。 编程USARTx_BRR寄存器确定波特率。 使能USARTx_CR1的UE位使能USARTx。 如果进行多缓冲通信,配置USARTx_CR3的DMA使能(DMAT)。 使能USARTx_CR1的TE位使能发送器。 /* 配置1~6步骤 */ HAL_UART_Init(UART_HandleTypeDef *huart) 发送数据: 向发送数据寄存器TDR写入要发送的数据(对于M3,发送和接收共用DR寄存器)。 向TRD寄存器写入最后
[单片机]
STM32 ADC多通道DMA传输
ADC多通道采集是在ADC单通道DMA传输的基础上写的,代码如下: volatile u16 adcconverdata ={0,0}; static void ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;//添加PA2的GPIO初始化代码 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_Init(
[单片机]
关于STM32GPIO的详细解析
一、GPIO的综合描述 stm32每一个GPIO端口拥有2个32bits的configuration寄存器(GPIOx_CRL,GPIOx_CRH),2个32bits的数据寄存器(GPIOx_IDR,GPIOx_ODR),1个32bits的set/reset寄存器(GPIOx_BSRR),1个16bits的reset寄存器(GPIOx_BRR)和1个32bits的Lock寄存器(GPIOx_LCKR)。 (一)每一个IO引脚都可以使用软件配置为以下几种模式: 1. 浮空输入 2. 带上拉输入 3. 带下拉输入 4. 模拟输入 5. 开漏输出——(此模式可实现hotpower说的真双向IO) 6. 推挽输出 7. 复用
[单片机]
STM32】通用定时器的输入捕获(实例:输入捕获)
通用定时器输入捕获概述 输入捕获的工作原理 在通用定时器框图中,主要涉及到最顶上的一部分(计数时钟的选择)、中间部分(时基单元)、左下部分(输入捕获)这三个部分。这里主要讲解一下左下部分(输入捕获),其他两个部分可以参考文章:【STM32】通用定时器的基本原理(实例:定时器中断)。 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6、TIM7,其他的定时器都有输入捕获的功能。下面以一个简单的脉冲输入为例,简单地讲述一下输入捕获用于测量脉冲宽度的工作原理: 先设置输入捕获为上升沿检测,记录发生上升沿时TIMx_CNT的值。然后配置捕获信号为下降沿捕获,当下降沿到来的时候发生捕
[单片机]
【<font color='red'>STM32</font>】通用定时器的输入捕获(实例:输入捕获)
STM32单片机特性解析
STM32单片机 由ST厂商推出的STM32系列单片机,行业的朋友都知道,这是一款性价比超高的系列单片机,应该没有之一,功能及其强大。其基于专为要求高性能、 低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M内核,同时具有一流的外设:1μs的双12位ADC,4兆位/秒的UART,18兆位/秒的SPI等等,在功耗和集成度方面也有不俗的表现,当然和MSP430的功耗比起来是稍微逊色的一些,但这并不影响工程师们对它的热捧程度,由于其简单的结构和易用的工具再配合其强大的功能在行业中赫赫有名。其强大的功能主要表现在: 特性 1、内核:ARM32位Cortex-M3CPU,最高工作频率72MHz,1.25DMIPS/MHz,单周
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved