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

贵港市网站建设_网站建设公司_自助建站_seo优化

网站做链接的意义是什么,宁夏网络推广公司,硬件产品开发流程图,河南整站关键词排名优化软件STM32——EEPROM 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神是无限的。 一、I2C接口读写EEPROM#xff08;AT24C02#xff09; ——主模式#xff0c;分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。 1、I 2C接口初始化 与其他对GPIO 复用…STM32——EEPROM 宗旨技术的学习是有限的分享的精神是无限的。 一、I2C接口读写EEPROMAT24C02 ——主模式分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。 1、I 2C接口初始化 与其他对GPIO 复用的外设一样它先调用了用户函数I2C_GPIO_Confi g() 配置好 I 2 C 所用的 I/O端口然后再调用用户函数 I2C_Mode_Confi gu() 设置 I 2 C 的工作模式并使能相关外设的时钟。 void I2C_EE_Init(void) {I2C_GPIO_Config();I2C_Mode_Config();/* 根据头文件 i2c_ee. 14 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 } 1EEPROM地址 AT24C02256字节高四位硬性规定最低位是R/W传输方向选择位在制作硬件时我们可以根据需要改变的是地址位中的 A2、A1、A0 位。原理图上面全接地所以它的地址为 0xA0 或 0xA1。 2、GPIO端口初始化 static void I2C_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;/* 使能与 I2C1 有关的时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);/* 配置SCL SDA引脚速率输出方式 */GPIO_InitStructure.GPIO_Pin GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_OD; // 开漏输出GPIO_Init(GPIOB, GPIO_InitStructure); } 3、I2C模式初始化 typedef struct {uint32_t I2C_ClockSpeed;uint16_t I2C_Mode;uint16_t I2C_DutyCycle;uint16_t I2C_OwnAddress1;uint16_t I2C_Ack;uint16_t I2C_AcknowledgedAddress; } I2C_InitTypeDef; 1I2C_Mode本成员是选择 I 2 C 的使用方式有 I 2 C 模式I2C_Mode_I2C和SMBus 模式。I2C_Mode_SMBusDevice、I2C_Mode_SMBusHost 2I2C_DutyCycle设置的是 I 2 C 的 SCL 线时钟的占空比。在 STM32 的 I 2 C 占空比配置中有两个选择分别为高电平时间和低电平时间之比为16 9 I2C_DutyCycle_16_9和 2 1 I2C_DutyCycle_2。 3I2C_OwnAddress1本 成 员 配 置 的 是 STM32 的 I 2 C 设 备 自 己 的 地 址 每个 连 接 到 I 2 C 总线上的设备都要有一个自己的地址作为主机也不例外。这个地址可以被配置为 7 位和 10 位地址。我们把这个地址设置为 0x0A 自定义宏I2C1_OWN_ADDRESS7 的值。 4I2C_Ack_Enable本成员关于 I 2 C 应答设置设置为使能则每接收到一个字节就返回一个应答信号。配置为允许应答I2C_Ack_Enable这是绝大多数遵循 I 2 C标准的设备通信的要求改为禁止应答 I2C_Ack_Disable往往会导致通信错误。 5I2C_AcknowledgeAddress本成员选择 I 2 C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I 2C 总线上设备的地址进行选择。与 EEPROM 进行通信使用的为 7 位寻址模式I2C_AcknowledgedAddress_7bit。 6I2C_ClockSpeed本成员设置的是 I 2 C 的传输速率在调用初始化函数时函数会根据我们输入的数值经过运算后把分频值写入到 I 2 C 的时钟控制寄存器。而我们写入的这个参数值不得高于 400 kHz。——400000 对结构体成员赋值完成后我们调用库函数 I2C_Init() 根据我们的配置对 I 2 C 进行初始化 并调用库函数 I2C_Cmd() 使能I 2 C 外设。  static void I2C_Mode_Configu(void) {I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode I2C_Mode_I2C; /* I2C 配置 */I2C_InitStructure.I2C_DutyCycle I2C_DutyCycle_2; /* 高电平数据稳定低电平数据变化 SCL 时钟线的占空比 */I2C_InitStructure.I2C_OwnAddress1 I2C1_OWN_ADDRESS7;I2C_InitStructure.I2C_Ack I2C_Ack_Enable ;I2C_InitStructure.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit; /* I2C 的寻址模式 */I2C_InitStructure.I2C_ClockSpeed I2C_Speed; /* 通信速率 */I2C_Init(I2C1, I2C_InitStructure); /* I2C1 初始化 */I2C_Cmd(I2C1, ENABLE); /* 使能 I2C1 */ }二、对EEPROM的读写操作 void I2C_Test(void) {u16 i;printf(写入的数据\n\r);for ( i 0; i 255; i ) //填充缓冲{I2c_Buf_Write[i] i;printf(0x%02X , I2c_Buf_Write[i]);if (i % 16 15){printf(\n\r);}}I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256); //将 I2c_Buf_Write 中顺序递增的数据写入 EERPOM 中printf(\n\r 写成功\n\r);printf(\n\r 读出的数据\n\r);I2C_EE_BufferRead(I2c_Buf_Read, EEP_Firstpage, 256); //将 EEPROM 读出数据顺序保持到 I2c_Buf_Read 中//将 I2c_Buf_Read 中的数据通过串口打印for (i 0; i 256; i){if (I2c_Buf_Read[i] ! I2c_Buf_Write[i]){printf(0x%02X , I2c_Buf_Read[i]);printf(错误:I2C EEPROM 写入与读出的数据不一致\n\r);return;}printf(0x%02X , I2c_Buf_Read[i]);if (i % 16 15){printf(\n\r);}}printf(I2C(AT24C02)读写测试成功\n\r); } 功能是把数值 0 255 按顺序填入缓冲区数组并通过串口打印到终端接着通过用户函数I2C_EE_BufferWrite()把缓冲区的数据写入EEPROM。写入成功之后利用用户函数 I2C_EE_BufferRead() 把数据读取出来进行校验判断数据是否被正确写入。  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();}}} } AT24C02 的 EEPROM 分为 32 页每页可存储8个字节的数据若在同一页写入超过 8 字节则超过的部分会被写在该页的起始地址这样部分数据会被覆盖。为了把连续的缓冲区数组按页写入 EEPROM就需要对缓冲区进入分页处理。I2C_EE_BufferWrite() 函数根据我们输入的缓冲区大小参数 NumByteToWrite计算出我们需要写入多少页并计算写入位置。分页处理好之后调用 I2C_EE_PageWrite() 函数这个函数是与 EEPROM 进行 I 2 C通信的最底层函数它与 STM32 的 I 2 C 库函数使用密切相关。 void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite) {while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE); /* Send START condition */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Test on EV5 and clear it */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); /* Send EEPROM address for write */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Test on EV6 and clear it */I2C_SendData(I2C1, WriteAddr); /* Send the EEPROMs internal address to write to */while (! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Test on EV8 and clear it */while (NumByteToWrite--) /* While there is data to be written */{I2C_SendData(I2C1, *pBuffer); /* Send the current byte */pBuffer; /* Point to the next byte to be written */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) ); /* Test on EV8 and clear it */}I2C_GenerateSTOP(I2C1, ENABLE); /* Send STOP condition */ } 1、EEPROM页写入时序 这个页写入的函数是根据 EEPROM 的页写入时序来编写的。 调用库函数I2C_Generate START() 产生 I 2 C 的通信起始信号 S。 调用库函数I2C_Send7bitAddress() 把前面条件编译中赋值的变量EEPROM_ADDRESS 地 址 通 过 I 2 C1接口发送出去数据传输方向为STM32的I2 C发送数据I2C_Direction_Transmitter。 调 用 库 函 数I2C_SendData() 请 注 意 这 个 库 函 数 的 输 入 参 数 为WriteAddr根据 EEPROM 的页写入时序发送完 I 2 C 的地址后的第一个数据并不就是要写入 EEPROM 的数据 EEPROM 对这个数据解释为将要对存储矩阵写入的地址这个参数 WriteAddr 是在我们调用 I2C_EE_PageWrite() 函数时作为参数输入的。这个库函数实际上是把数据传输到数据寄存器再由 I 2 C 模块根据 I 2 C 协议发送出 去。 调用I2C_SendData() 函数向 EEPROM 发送要写入的数据根据EEPROM 的页写入时序这些数据将会被写入到前面发送的页地址中若连续写入超过一页的最大字节数8个则多出来的数据会重新从该页的起始地址连续写入覆盖前面的数据。 调用库函数I2C_Generate STOP() 产生 I 2 C 传输结束信号完成一次 I2 C 通信。 2、I2C事件检测 在 I 2 C的通信过程中会产生一系列的事件出现事件后在相应的寄存器中会产生标志位。 若发出了起始信号会产生事件 5EV5即 STM32 的 I 2 C成为主机模式继续发送完 I 2C 设备寻址并得到应答后会产生 EV6即 STM32 的 I 2C 成为数据发送端之后发送数据完成会产生 EV8 等。我们在做出 I 2 C 通信操作时可以通过循环调用库函数I2C_CheckEvent()进行事件查询以确保上一操作完成后才进行下一操作。 3、等到EEPROM内部写入完成 void I2C_EE_WaitEepromStandbyState(void) {vu16 SR1_Tmp 0;do{I2C_GenerateSTART(I2C1, ENABLE); /* Send START condition */SR1_Tmp I2C_ReadRegister(I2C1, I2C_Register_SR1); /* Read I2C1 SR1 register */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); /* Send EEPROM address for write */}while (!(I2C_ReadRegister(I2C1, I2C_Register_SR1) 0x0002));I2C_ClearFlag(I2C1, I2C_FLAG_AF); /* Clear AF flag */I2C_GenerateSTOP(I2C1, ENABLE); /* STOP condition */ } 利用了 EEPROM 在接收完数据后启动内部周期写入数据的时间内不会对主机的请求做出应答的特性。所以利用这个函数循环发送起始信号若检测到 EEPROM 的应答则说明 EEPROM 已经完成上一步的数据写入进入 Standby 状态可以进行下一步的操作了。 三、EEPROM读 void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) { //*((u8 *)0x4001080c) |0x80;while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // Added by Najoua/* Send START condition */I2C_GenerateSTART(I2C1, ENABLE); //*((u8 *)0x4001080c) ~0x80;/* Test on EV5 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/* Send EEPROM address for write */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);/* Test on EV6 and clear it */while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/* Clear EV6 by setting again the PE bit */I2C_Cmd(I2C1, ENABLE);/* Send the EEPROMs internal address to write to */I2C_SendData(I2C1, ReadAddr);/* Test on EV8 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/* Send STRAT condition a second time */I2C_GenerateSTART(I2C1, ENABLE);/* Test on EV5 and clear it */while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/* Send EEPROM address for read */I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);/* Test on EV6 and clear it */while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));/* While there is data to be read */while (NumByteToRead){if (NumByteToRead 1){/* Disable Acknowledgement */I2C_AcknowledgeConfig(I2C1, DISABLE);/* Send STOP Condition */I2C_GenerateSTOP(I2C1, ENABLE);}/* Test on EV7 and clear it */if (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)){/* Read a byte from the EEPROM */*pBuffer I2C_ReceiveData(I2C1);/* Point to the next location where the byte read will besaved */pBuffer;/* Decrement the read bytes counter */NumByteToRead--;}}/* Enable Acknowledgement to be ready for another reception */I2C_AcknowledgeConfig(I2C1, ENABLE); }四、使用 I2 C读写EEPROM流程总结 1配置 I/O 端口确定并配置 I 2 C 的模式使能 GPIO 和 I 2 C 时钟。 2写 ① 检测 SDA 是否空闲。 ② 按 I 2 C 协议发出起始信号。 ③ 发出 7 位器件地址和写模式。 ④ 要写入的存储区首地址。 ⑤ 用页写入方式或字节写入方式写入数据。 ⑥ 发送 I 2 C 通信结束信号。 每个操作之后要检测“事件”是否成功。写完后检测 EEPROM 是否进入Standby状态。 3读 ① 检测 SDA 是否空闲。 ② 按 I 2 C 协议发出起始信号。 ③ 发出 7 位器件地址和写模式伪写。 ④ 发出要读取的存储区首地址。 ⑤ 重发起始信号。 ⑥ 发出 7 位器件地址和读模式。 ⑦ 接收数据。 类似写操作每个操作之后要检测“事件”是否成功。
http://www.lebaoying.cn/news/28557.html

相关文章:

  • 自己服务器建网站网页翻译软件
  • 网站微信支付怎么做北京突发重大消息
  • 社交网站怎么做网站开发方案及报价单
  • 聚美优品网站建设外贸网络营销软件
  • 泉州企业做网站网站栏目建设存在的问题
  • 网站设计大全wordpress同标题关键字
  • 衡阳网站优化教程湖南长沙理工大学
  • wordpress 整站打包兰州网络推广制度
  • 上海 网站备案平面设计
  • 网站管理系统后台wordpress安装完成
  • 网站源码运行医院网站建设目的
  • 灵台县住房和城乡建设局网站免费中介系统房产软件
  • 建德网站设计公司社交网络推广方法
  • 娱乐网站开发晋城网站建设网站
  • 网站建设方案ppt 枫子科技怎么做考试资料分享网站
  • 网站开发后如何维护seo搜索引擎优化推广
  • 建网站的详细技术开网站需要钱吗
  • 源码交易网站简单动画制作
  • 手机端便民服务平台网站建设上海小程序设计
  • 城乡建设网站投稿wordpress 教程网
  • 小语种外贸建站动漫设计专业学什么
  • 商业网站建设的方法从用户旅程角度做网站分析
  • 自己做的网站加载慢的原因技校网站建设与维护课程教学总结
  • 旅游公司网站设计海外域名注册商
  • 全包胶衣网站上线了做的网站怎么办
  • 2016wap网站开发语言页面模板嵌入文章内
  • 网站开发 支付宝订单号滨州网站建设费用
  • 网站开发服务协议免费空间凡科
  • 天津网站建设企业用npp做网站
  • 河南便宜网站建设价格低分享网站排名