当前位置: 首页 > news >正文

做我女朋友的表白句的网站站长网站优点

做我女朋友的表白句的网站,站长网站优点,自豪得用wordpress删,网站和网页的区别main.c 硬件结构如下#xff0c;EEPROM 芯片(AT24C02)的 SCL 及 SDA 引脚连接到了 STM32 的 I2C 引脚中#xff0c;结合上拉电阻#xff0c;构成了 I2C 通讯总线#xff0c;它们通过 I2C 总线交互。 EEPROM 芯片的设备地址#xff1a;一共有 7 位#xff0c;其中高 4 位…main.c 硬件结构如下EEPROM 芯片(AT24C02)的 SCL 及 SDA 引脚连接到了 STM32 的 I2C 引脚中结合上拉电阻构成了 I2C 通讯总线它们通过 I2C 总线交互。 EEPROM 芯片的设备地址一共有 7 位其中高 4 位固定为1010 b低 3 位则由 A0/A1/A2 信号线的电平决定。设备地址如下图图中的 R/W 是读写方向位与地址无关。 I2C 通讯时常常是地址跟读写方向连在一起构成一个 8 位数电路图中把A2到A0都接地了所以都是零那么当 R/W 位为 0 时表示写方向I2C 设备的写地址就是101000000xA0当 R/W 位为 1 时表示读方向I2C 设备的读地址就是101000010xA1。 AT24C02芯片中还有一个 WP 引脚具有写保护功能当该引脚电平为高时禁止写入数据当引脚为低电平时可写入数据这里直接接地不使用写保护功能。 main.c文件里面首先初始化串口、I2C 外设然后调用 I2C_Test 函数进行读写测试。 下面说一下 I2C_Test函数函数里首先造一个数组然后把这个数组的内容写入到 EEPROM 中这里用的是I2C_EE_BufferWrite函数它是基于EEPROM页写入方式改进的多字节写入。接着调用I2C_EE_BufferRead函数从EEPROM读出数据并且保存到I2c_Buf_Read中。把读取得到的与写入的数据进行校验若一致说明读写正常。至于输出到串口上采用重定向的方法重定向后可使用printf函数直接把数据输出到串口。 结果 #include stm32f10x.h #include ./led/bsp_led.h #include ./usart/bsp_usart.h #include ./i2c/bsp_i2c_ee.h #include string.h#define EEP_Firstpage 0x00 uint8_t I2c_Buf_Write[256]; uint8_t I2c_Buf_Read[256]; uint8_t I2C_Test(void);/*** brief 主函数* param 无* retval 无*/ int main(void) { LED_GPIO_Config();LED_BLUE;/* 串口初始化 */USART_Config();printf(\r\n 这是一个I2C外设(AT24C02)读写测试例程 \r\n);/* I2C 外设初(AT24C02)始化 */I2C_EE_Init();printf(\r\n 这是一个I2C外设(AT24C02)读写测试例程 \r\n); //EEPROM 读写测试if(I2C_Test() 1){LED_GREEN;}else{LED_RED;}while (1){ } }/*** brief I2C(AT24C02)读写测试* param 无* retval 正常返回1异常返回0*/ uint8_t I2C_Test(void) {uint16_t i;printf(写入的数据\n\r);for ( i0; i255; i ) //填充缓冲{ I2c_Buf_Write[i] i;printf(0x%02X , I2c_Buf_Write[i]);if(i%16 15) printf(\n\r); }//将I2c_Buf_Write中顺序递增的数据写入EERPOM中 I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256);EEPROM_INFO(\n\r写成功\n\r);EEPROM_INFO(\n\r读出的数据\n\r);//将EEPROM读出数据顺序保持到I2c_Buf_Read中I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256); //将I2c_Buf_Read中的数据通过串口打印for (i0; i256; i){ if(I2c_Buf_Read[i] ! I2c_Buf_Write[i]){EEPROM_ERROR(0x%02X , I2c_Buf_Read[i]);EEPROM_ERROR(错误:I2C EEPROM写入与读出的数据不一致\n\r);return 0;}printf(0x%02X , I2c_Buf_Read[i]);if(i%16 15) printf(\n\r);}EEPROM_INFO(I2C(AT24C02)读写测试成功\n\r);return 1; }i2c_ee.h 这里面写了一些I2C 硬件相关的宏定义。 把与 EEPROM 通讯使用的 I2C 号 、引脚号都以宏封装起来 并且定义了自身的 I2C 地址及通讯速率以便配置模式的时候使用。 #ifndef __I2C_EE_H #define __I2C_EE_H#include stm32f10x.h/**************************I2C参数定义I2C1或I2C2********************************/ #define EEPROM_I2Cx I2C1 #define EEPROM_I2C_APBxClock_FUN RCC_APB1PeriphClockCmd #define EEPROM_I2C_CLK RCC_APB1Periph_I2C1 #define EEPROM_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd #define EEPROM_I2C_GPIO_CLK RCC_APB2Periph_GPIOB #define EEPROM_I2C_SCL_PORT GPIOB #define EEPROM_I2C_SCL_PIN GPIO_Pin_6 #define EEPROM_I2C_SDA_PORT GPIOB #define EEPROM_I2C_SDA_PIN GPIO_Pin_7/* STM32 I2C 快速模式 */ #define I2C_Speed 400000 //*/* 这个地址只要与STM32外挂的I2C器件地址不一样即可 */ #define I2Cx_OWN_ADDRESS7 0X0A /* AT24C01/02每页有8个字节 */ #define I2C_PageSize 8/* AT24C04/08A/16A每页有16个字节 */ //#define I2C_PageSize 16 /*等待超时时间*/ #define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000) #define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))/*信息输出*/ #define EEPROM_DEBUG_ON 0#define EEPROM_INFO(fmt,arg...) printf(-EEPROM-INFO- fmt\n,##arg) #define EEPROM_ERROR(fmt,arg...) printf(-EEPROM-ERROR- fmt\n,##arg) #define EEPROM_DEBUG(fmt,arg...) do{\if(EEPROM_DEBUG_ON)\printf(-EEPROM-DEBUG- [%d]fmt\n,__LINE__, ##arg);\}while(0)/* * AT24C02 2kb 2048bit 2048/8 B 256 B* 32 pages of 8 bytes each** Device Address* 1 0 1 0 A2 A1 A0 R/W* 1 0 1 0 0 0 0 0 0XA0* 1 0 1 0 0 0 0 1 0XA1 *//* EEPROM Addresses defines */ #define EEPROM_Block0_ADDRESS 0xA0 /* E2 0 */ //#define EEPROM_Block1_ADDRESS 0xA2 /* E2 0 */ //#define EEPROM_Block2_ADDRESS 0xA4 /* E2 0 */ //#define EEPROM_Block3_ADDRESS 0xA6 /* E2 0 */void I2C_EE_Init(void); void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite); uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr); uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite); uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead); void I2C_EE_WaitEepromStandbyState(void);#endif /* __I2C_EE_H */ i2c_ee.c 下面这个函数用来初始化 I2C 的 GPIO。这里面使能了两个时钟一个是I2C 外设时钟另一个是使能 I2C 引脚使用的 GPIO 端口时钟。然后向 GPIO 初始化结构体赋值把引脚初始化成复用开漏模式。最后调用 GPIO_Init 函数向寄存器写入参数完成 GPIO 的 初始化。这里只是配置了 I2C 使用的引脚还不算对 I2C 模式的配置。 static void I2C_GPIO_Config(void)下面这个函数用来配置 I2C 模式。把 I2C 外设通讯时钟 SCL 的低/高电平比设置为 2使能响应功能使用 7 位地址 I2C_OWN_ADDRESS7 以及速率配置为 I2C_Speed(前面i2c_ee.h定义的宏)。最后调用库函数 I2C_Init 把这些配置写入寄存器并调用 I2C_Cmd 函数使能外设。 static void I2C_Mode_Configu(void)下面这个I2C_EE_Init 函数把 I2C 的 GPIO 及模式配置都封装起来。 void I2C_EE_Init(void)下面这个I2C_EE_ByteWrite函数向 EEPROM 写入一个字节的数据。这个函数实现了I2C 主发送器通讯流程。 uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr) 下面分析一下这个函数 首先使用库函数 I2C_GenerateSTART 产生 I2C 起始信号其中的 EEPROM_I2C 宏是 I2C 编号。 /* Send STRAT condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);当发生起始信号后产生事件EV5接下来该循环通过调用库函数 I2C_CheckEvent 检测事件EV5若检测到事件则进入通讯的下一阶段. I2CTimeout I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(0);} 然后主发送器发送设备地址并等待应答信号I2C_Send7bitAddress函数发送 EEPROM 的设备地址并把数据传输方向设置为 I2C_Direction_Transmitter(即发送方向)。发送地址后以同样的方式检测 EV6 标志。 I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(1);} 然后调用库函数 I2C_SendData 向 EEPROM 发送要写入的内部地址该地址是 I2C_EE_ByteWrite 函数的输入参数发送完毕后等待 EV8 事件。这个内部地址跟上面的 EEPROM 地址不一样上面的是指 I2C 总线设备的独立地址而此处的内部地址是指 EEPROM 内数据组织的地址。 I2C_SendData(EEPROM_I2Cx, WriteAddr);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV8 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(2);} 然后调用库函数 I2C_SendData 向 EEPROM 发送要写入的数据该数据是I2C_EE_ByteWrite 函数的输入参数发送完毕后等待 EV8 事件。 I2C_SendData(EEPROM_I2Cx, *pBuffer); I2CTimeout I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(3);} 一个 I2C 通讯过程完毕调用 I2C_GenerateSTOP 发送停止信号。 /* Send STOP condition */I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);向 EEPROM 写入一个字节的数据这个通讯过程中STM32 实际上通过 I2C 向 EEPROM 发送了两个数据EEPROM 的单字节时序规定向它写入数据的时候第一个字节为内存地址第二个字节是要写入的数据内容。如下图所示。 下面说一下I2C_TIMEOUT_UserCallback函数里面只调用了宏 EEPROM_ERROR这个宏封装了 printf 函数方便使用串口向上位机打印调试信息。 /*** brief Basic management of the timeout situation.* param errorCode错误代码可以用来定位是哪个环节出错.* retval 返回0表示IIC读取失败.*/ static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode) {/* Block communication and all processes */EEPROM_ERROR(I2C 等待超时!errorCode %d,errorCode);return 0; }I2CTimeout是等待的时间上限。 在 I2C 通讯的很多过程都需要检测事件当检测到某事件后才能继续下一步的操作但有时通讯错误或者 I2C 总线被占用不能无休止地等待下去所以设定每个事件检测都有等待的时间上限若超过这个时间就调用 I2C_TIMEOUT_UserCallback 函数输出调试信息(或可以自己加其它操作)并终止 I2C 通讯。 有了写一个字节的函数就可以写下面写多字节的函数。单字节写入通讯结束后EEPROM 芯片会根据这个通讯结果擦写该内存地址的内容所以我们在多次写入数据时要先等待 EEPROM 内部擦写完毕。 /*** brief 将缓冲区中的数据写到 I2C EEPROM 中采用单字节写入的方式速度比页写入慢* param pBuffer:缓冲区指针* param WriteAddr:写地址* param NumByteToWrite:写的字节数* retval 无*/uint8_t I2C_EE_ByetsWrite(uint8_t* pBuffer,uint8_t WriteAddr,uint16_t NumByteToWrite){uint16_t i;uint8_t res;/*每写一个字节调用一次 I2C_EE_ByteWrite 函数*/for (i0; iNumByteToWrite; i){/*等待 EEPROM 准备完毕*/I2C_EE_WaitEepromStandbyState();/*按字节写入数据*/res I2C_EE_ByteWrite(pBuffer,WriteAddr);}return res;} 里面调用了 I2C_EE_WaitEepromStandbyState 函数等待 EEPROM 内部擦写完毕。主要实现是向 EEPROM 发送它设备地址检测 EEPROM 的响应若 EEPROM 接收到地址后返回应答信号则表示 EEPROM 已经准备好可以开始下一次通 讯。函数中检测响应是通过读取 STM32 的 SR1 寄存器的 ADDR 位及 AF 位来实现的当 I2C 设备响应了地址的时候ADDR 会置 1若应答失败AF 位会置 1。 EEPROM 的页写入以字节写入的话每写入一个数据都需要向 EEPROM 发送写入的地址我们希望 向连续地址写入多个数据的时候只要告诉 EEPROM 第一个内存地址 address1后面的数 据按次序写入到 address2、address3… 这样可以节省通讯的时间加快速度。AT24C02里面有一个页写入时序。根据页写入时序第一个数据被解释为要写入的内存地址 address1后续可连续发送 n 个数据这些数据会依次写入到内存中。其中 AT24C02 型号的芯片页写入时序最多可以一次发送 8 个数据(即 n 8 )该值也称为页大小。只要每次传输的数据小于等于 EEPROM 时序规定的页大小(每页8个字节)就能正常传输。 下面这个函数就是根据上面页写入时序图写的。 uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)下面这个函数是利用EEPROM页写入方式改进前面的多字节写入。需要先对输入的数据进行分页(每页8字节)这个有点复杂jym另写一篇文章分析。 void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)从EEPROM读取数据 下面这个图是EEPROM数据读取时序图。 下面这个图是连续读取多个字节数据的时许图主机发送NoACK结束。 下面这个函数就是根据这些个时序图写的。读过程中接收数据时需要使用库函数 I2C_ReceiveData 来读取。响应信号则通过库函数 I2C_AcknowledgeConfig 来发送 DISABLE 时为非响应信号ENABLE 为响应信号。 uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)下面是完整代码。 #include ./i2c/bsp_i2c_ee.h #include ./usart/bsp_usart.h uint16_t EEPROM_ADDRESS;static __IO uint32_t I2CTimeout I2CT_LONG_TIMEOUT; static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);/*** brief I2C I/O配置* param 无* retval 无*/ static void I2C_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure; /* 使能与 I2C 有关的时钟 */EEPROM_I2C_APBxClock_FUN ( EEPROM_I2C_CLK, ENABLE );EEPROM_I2C_GPIO_APBxClock_FUN ( EEPROM_I2C_GPIO_CLK, ENABLE );/* I2C_SCL、I2C_SDA*/GPIO_InitStructure.GPIO_Pin EEPROM_I2C_SCL_PIN;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_OD; // 开漏输出GPIO_Init(EEPROM_I2C_SCL_PORT, GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin EEPROM_I2C_SDA_PIN;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_OD; // 开漏输出GPIO_Init(EEPROM_I2C_SDA_PORT, GPIO_InitStructure); }/*** brief I2C 工作模式配置* param 无* retval 无*/ static void I2C_Mode_Configu(void) {I2C_InitTypeDef I2C_InitStructure; /* I2C 配置 */I2C_InitStructure.I2C_Mode I2C_Mode_I2C;/* 高电平数据稳定低电平数据变化 SCL 时钟线的占空比 */I2C_InitStructure.I2C_DutyCycle I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 I2Cx_OWN_ADDRESS7; I2C_InitStructure.I2C_Ack I2C_Ack_Enable ;/* I2C的寻址模式 */I2C_InitStructure.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit;/* 通信速率 */I2C_InitStructure.I2C_ClockSpeed I2C_Speed;/* I2C 初始化 */I2C_Init(EEPROM_I2Cx, I2C_InitStructure);/* 使能 I2C */I2C_Cmd(EEPROM_I2Cx, ENABLE); }/*** brief I2C 外设(EEPROM)初始化* param 无* retval 无*/ void I2C_EE_Init(void) {I2C_GPIO_Config(); I2C_Mode_Configu();/* 根据头文件i2c_ee.h中的定义来选择EEPROM的设备地址 */ #ifdef EEPROM_Block0_ADDRESS/* 选择 EEPROM Block0 来写入 */EEPROM_ADDRESS EEPROM_Block0_ADDRESS; #endif#ifdef EEPROM_Block1_ADDRESS /* 选择 EEPROM Block1 来写入 */EEPROM_ADDRESS EEPROM_Block1_ADDRESS; #endif#ifdef EEPROM_Block2_ADDRESS /* 选择 EEPROM Block2 来写入 */EEPROM_ADDRESS EEPROM_Block2_ADDRESS; #endif#ifdef EEPROM_Block3_ADDRESS /* 选择 EEPROM Block3 来写入 */EEPROM_ADDRESS EEPROM_Block3_ADDRESS; #endif }/*** brief 将缓冲区中的数据写到I2C EEPROM中* param * arg pBuffer:缓冲区指针* arg WriteAddr:写地址* arg NumByteToWrite:写的字节数* retval 无*/ void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite) {u8 NumOfPage 0, NumOfSingle 0, Addr 0, count 0;Addr WriteAddr % I2C_PageSize;count I2C_PageSize - Addr;NumOfPage NumByteToWrite / I2C_PageSize;NumOfSingle NumByteToWrite % I2C_PageSize;/* If WriteAddr is I2C_PageSize aligned */if(Addr 0) {/* If NumByteToWrite I2C_PageSize */if(NumOfPage 0) {I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}/* If NumByteToWrite I2C_PageSize */else {while(NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize); I2C_EE_WaitEepromStandbyState();WriteAddr I2C_PageSize;pBuffer I2C_PageSize;}if(NumOfSingle!0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}}}/* If WriteAddr is not I2C_PageSize aligned */else {/* If NumByteToWrite I2C_PageSize */if(NumOfPage 0) {I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);I2C_EE_WaitEepromStandbyState();}/* If NumByteToWrite I2C_PageSize */else{NumByteToWrite - count;NumOfPage NumByteToWrite / I2C_PageSize;NumOfSingle NumByteToWrite % I2C_PageSize; if(count ! 0){ I2C_EE_PageWrite(pBuffer, WriteAddr, count);I2C_EE_WaitEepromStandbyState();WriteAddr count;pBuffer count;} while(NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);I2C_EE_WaitEepromStandbyState();WriteAddr I2C_PageSize;pBuffer I2C_PageSize; }if(NumOfSingle ! 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); I2C_EE_WaitEepromStandbyState();}}} }/*** brief 写一个字节到I2C EEPROM中* param * arg pBuffer:缓冲区指针* arg WriteAddr:写地址 * retval 无*/ uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr) {/* Send STRAT condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);I2CTimeout I2CT_FLAG_TIMEOUT; /* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(0);} I2CTimeout I2CT_FLAG_TIMEOUT;/* Send EEPROM address for write */I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(1);} /* Send the EEPROMs internal address to write to */I2C_SendData(EEPROM_I2Cx, WriteAddr);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV8 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(2);} /* Send the byte to be written */I2C_SendData(EEPROM_I2Cx, *pBuffer); I2CTimeout I2CT_FLAG_TIMEOUT; /* Test on EV8 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(3);} /* Send STOP condition */I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);return 1; }/*** brief 在EEPROM的一个写循环中可以写多个字节但一次写入的字节数* 不能超过EEPROM页的大小AT24C02每页有8个字节* param * arg pBuffer:缓冲区指针* arg WriteAddr:写地址* arg NumByteToWrite:写的字节数* retval 无*/ uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite) {I2CTimeout I2CT_LONG_TIMEOUT;while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY)) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(4);} /* Send START condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(5);} /* Send EEPROM address for write */I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(6);} /* Send the EEPROMs internal address to write to */ I2C_SendData(EEPROM_I2Cx, WriteAddr); I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV8 and clear it */while(! I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(7);} /* While there is data to be written */while(NumByteToWrite--) {/* Send the current byte */I2C_SendData(EEPROM_I2Cx, *pBuffer); /* Point to the next byte to be written */pBuffer; I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV8 and clear it */while (!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(8);} }/* Send STOP condition */I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);return 1; }/*** brief 从EEPROM里面读取一块数据 * param * arg pBuffer:存放从EEPROM读取的数据的缓冲区指针* arg WriteAddr:接收数据的EEPROM的地址* arg NumByteToWrite:要从EEPROM读取的字节数* retval 无*/ uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) { I2CTimeout I2CT_LONG_TIMEOUT;//*((u8 *)0x4001080c) |0x80; while(I2C_GetFlagStatus(EEPROM_I2Cx, I2C_FLAG_BUSY)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(9);}/* Send START condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);//*((u8 *)0x4001080c) ~0x80;I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(10);}/* Send EEPROM address for write */I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(11);}/* Clear EV6 by setting again the PE bit */I2C_Cmd(EEPROM_I2Cx, ENABLE);/* Send the EEPROMs internal address to write to */I2C_SendData(EEPROM_I2Cx, ReadAddr); I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV8 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(12);}/* Send STRAT condition a second time */ I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV5 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_MODE_SELECT)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(13);}/* Send EEPROM address for read */I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Receiver);I2CTimeout I2CT_FLAG_TIMEOUT;/* Test on EV6 and clear it */while(!I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(14);}/* While there is data to be read */while(NumByteToRead) {if(NumByteToRead 1){/* Disable Acknowledgement */I2C_AcknowledgeConfig(EEPROM_I2Cx, DISABLE);/* Send STOP Condition */I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE);}/* Test on EV7 and clear it */ I2CTimeout I2CT_LONG_TIMEOUT;while(I2C_CheckEvent(EEPROM_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)0) {if((I2CTimeout--) 0) return I2C_TIMEOUT_UserCallback(3);} { /* Read a byte from the EEPROM */*pBuffer I2C_ReceiveData(EEPROM_I2Cx);/* Point to the next location where the byte read will be saved */pBuffer; /* Decrement the read bytes counter */NumByteToRead--; } }/* Enable Acknowledgement to be ready for another reception */I2C_AcknowledgeConfig(EEPROM_I2Cx, ENABLE);return 1; }/*** brief Wait for EEPROM Standby state * param 无* retval 无*/ void I2C_EE_WaitEepromStandbyState(void) {vu16 SR1_Tmp 0;do{/* Send START condition */I2C_GenerateSTART(EEPROM_I2Cx, ENABLE);/* Read I2C1 SR1 register */SR1_Tmp I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1);/* Send EEPROM address for write */I2C_Send7bitAddress(EEPROM_I2Cx, EEPROM_ADDRESS, I2C_Direction_Transmitter);}while(!(I2C_ReadRegister(EEPROM_I2Cx, I2C_Register_SR1) 0x0002));/* Clear AF flag */I2C_ClearFlag(EEPROM_I2Cx, I2C_FLAG_AF);/* STOP condition */ I2C_GenerateSTOP(EEPROM_I2Cx, ENABLE); }/*** brief Basic management of the timeout situation.* param errorCode错误代码可以用来定位是哪个环节出错.* retval 返回0表示IIC读取失败.*/ static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode) {/* Block communication and all processes */EEPROM_ERROR(I2C 等待超时!errorCode %d,errorCode);return 0; } /*********************************************END OF FILE**********************/
http://www.pierceye.com/news/38010/

相关文章:

  • 接单网站源码网站建设检查整改情况报告
  • 做网站的成本有多少凌河网站建设推广
  • 长沙做网站优化的公司aitt网站建设中
  • 建设网站站点过程中全国装修公司排名前十强
  • 环保局网站建设wordpress头像怎么修改
  • 烟台福山建设工程监测网站主机网站
  • 苏州网站排名方案wordpress网站资源
  • 邯郸网站设计价位seo如何快速出排名
  • 爱站关键词挖掘old怎么申请自己公司的网址
  • 网上商城网站模板知名响应式网站企业
  • 0基础建站网站搭建教程门户系统1号线wordpress
  • 个人网站 商城 备案网站建设报价请示
  • 网站建设工作室小俊哥建筑公司logo设计大全
  • 重庆最便宜的网站建设公司重庆网站建设 公司
  • 网站开发与网页设计wordpress4.9下载
  • 网站维护是什么职业wordpress灯箱代码
  • 著名设计案例网站如何申请域名网站注册
  • 网站流量分析网站wordpress 个人写作
  • 卢松松的网站网站h1标签的应用
  • 网站规划与建设ppt模板下载今天的三个新闻
  • 做网站的伪原创怎么弄有哪些做ae小动效的网站
  • 外包公司做网站多少钱网业加速器
  • 湖北建设厅网站首页长春做网站搜吉网传媒
  • php的网站模板如何提升网站的流量
  • 在线医疗 网站建设网站备案和备案的区别吗
  • 永泰县建设局网站wordpress打不开主页
  • 重庆市建设项目环境申报表网站呼和浩特网站开发 千投
  • 怎么注册网站网址从零开始学做视频剪辑
  • 哪家可以做网站无屏蔽搜索引擎
  • 优秀网站建设模版有限公司网站建设 中企动力重庆