单片机GD32F303RCT6 (Macos环境)开发 (十六)—— Eeprom AT24C08的读取

本文主要是介绍单片机GD32F303RCT6 (Macos环境)开发 (十六)—— Eeprom AT24C08的读取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、AT24C04 、AT24C08、AT24C016应该都适应这份代码,他们每一页的大小都是16字节。如果是AT24C02的话,每一页的大小为8个字节,修改一下#define I2C_PAGE_SIZE 8 应该也可以正常换页读取。
2、关于代码的宏定义配置
Application目录的Makefile中 ENABLE_I2C_TEST = yes才会编译I2C1的相关代码。
同时修改i2c.h文件,定义I2C1_MODE为I2C1_MODE_POLL,at24c08 .c 相关代码才会编译进去。
3、At24C08.c 核心就是一个换页写入的操作,因为eeprom连续写入时不支持自动换页,但是连续读取时,是可以自动换页的。

#include "gd32f30x.h"
#include "systick.h"
#include "at24c08.h"
#include "i2c.h"#if I2C1_MODE == I2C1_MODE_POLL #define I2C1_SPEED                          100000
#define EE_ADDR   							0xA0 
#define I2C_PAGE_SIZE                       16/*!\brief      write one byte to the I2C EEPROM\param[in]  p_buffer: pointer to the buffer containing the data to be written to the EEPROM\param[in]  write_address: EEPROM's internal address to write to\param[out] none\retval     none
*/
void eeprom_byte_write(uint8_t Data, uint8_t write_address)
{/* wait until I2C bus is idle */while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));/* send a start condition to I2C bus */i2c_start_on_bus(I2C1);/* wait until SBSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));/* send slave address to I2C bus */i2c_master_addressing(I2C1, EE_ADDR, I2C_TRANSMITTER);/* wait until ADDSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));/* clear the ADDSEND bit */i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);/* wait until the transmit data buffer is empty */while(SET != i2c_flag_get(I2C1, I2C_FLAG_TBE));/* send the EEPROM's internal address to write to : only one byte address */i2c_data_transmit(I2C1, write_address);/* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* send the byte to be written */i2c_data_transmit(I2C1, Data); /* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);/* wait until the stop condition is finished */while(I2C_CTL0(I2C1)&0x0200);
}/*!\brief      write more than one byte to the EEPROM with a single write cycle\param[in]  p_buffer: pointer to the buffer containing the data to be written to the EEPROM\param[in]  write_address: EEPROM's internal address to write to\param[in]  number_of_byte: number of bytes to write to the EEPROM\param[out] none\retval     none
*/
void eeprom_page_write(uint8_t* p_buffer, uint8_t write_address, uint8_t number_of_byte)
{/* wait until I2C bus is idle */while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));/* send a start condition to I2C bus */i2c_start_on_bus(I2C1);/* wait until SBSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));/* send slave address to I2C bus */i2c_master_addressing(I2C1, EE_ADDR, I2C_TRANSMITTER);/* wait until ADDSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));/* clear the ADDSEND bit */i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);/* wait until the transmit data buffer is empty */while( SET != i2c_flag_get(I2C1, I2C_FLAG_TBE));/* send the EEPROM's internal address to write to : only one byte address */i2c_data_transmit(I2C1, write_address);/* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* while there is data to be written */while(number_of_byte--){  i2c_data_transmit(I2C1, *p_buffer);/* point to the next byte to be written */p_buffer++; /* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));}/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);/* wait until the stop condition is finished */while(I2C_CTL0(I2C1)&0x0200);
}/*!\brief      read data from the EEPROM\param[in]  p_buffer: pointer to the buffer that receives the data read from the EEPROM\param[in]  read_address: EEPROM's internal address to start reading from\param[in]  number_of_byte: number of bytes to reads from the EEPROM\param[out] none\retval     none
*/
void eeprom_buffer_read(uint8_t* p_buffer, uint8_t read_address, uint16_t number_of_byte)
{  /* wait until I2C bus is idle */while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));if(2 == number_of_byte){i2c_ackpos_config(I2C1,I2C_ACKPOS_NEXT);}/* send a start condition to I2C bus */i2c_start_on_bus(I2C1);/* wait until SBSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));/* send slave address to I2C bus */i2c_master_addressing(I2C1, EE_ADDR, I2C_TRANSMITTER);/* wait until ADDSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));/* clear the ADDSEND bit */i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);/* wait until the transmit data buffer is empty */while(SET != i2c_flag_get( I2C1 , I2C_FLAG_TBE));/* enable I2C1*/i2c_enable(I2C1);/* send the EEPROM's internal address to write to */i2c_data_transmit(I2C1, read_address);  /* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* send a start condition to I2C bus */i2c_start_on_bus(I2C1);/* wait until SBSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));/* send slave address to I2C bus */i2c_master_addressing(I2C1, EE_ADDR, I2C_RECEIVER);if(number_of_byte < 3){/* disable acknowledge */i2c_ack_config(I2C1,I2C_ACK_DISABLE);}/* wait until ADDSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND));/* clear the ADDSEND bit */i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);if(1 == number_of_byte){/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);}/* while there is data to be read */while(number_of_byte){if(3 == number_of_byte){/* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* disable acknowledge */i2c_ack_config(I2C1,I2C_ACK_DISABLE);}if(2 == number_of_byte){/* wait until BTC bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_BTC));/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);}/* wait until the RBNE bit is set and clear it */if(i2c_flag_get(I2C1, I2C_FLAG_RBNE)){/* read a byte from the EEPROM */*p_buffer = i2c_data_receive(I2C1);/* point to the next location where the byte read will be saved */p_buffer++; /* decrement the read bytes counter */number_of_byte--;} }/* wait until the stop condition is finished */while(I2C_CTL0(I2C1)&0x0200);/* enable acknowledge */i2c_ack_config(I2C1,I2C_ACK_ENABLE);i2c_ackpos_config(I2C1,I2C_ACKPOS_CURRENT);
}/*!\brief      wait for EEPROM standby state\param[in]  none\param[out] none\retval     none
*/
void eeprom_wait_standby_state(void)
{__IO uint32_t val = 0;while(1){/* wait until I2C bus is idle */while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY));/* send a start condition to I2C bus */i2c_start_on_bus(I2C1);/* wait until SBSEND bit is set */while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND));/* send slave address to I2C bus */i2c_master_addressing(I2C1, EE_ADDR, I2C_TRANSMITTER);/* keep looping till the Address is acknowledged or the AE flag is set (address not acknowledged at time) */do{/* get the current value of the I2C_STAT0 register */val = I2C_STAT0(I2C1);}while(0 == (val & (I2C_STAT0_ADDSEND | I2C_STAT0_AERR)));/* check if the ADDSEND flag has been set */if(val & I2C_STAT0_ADDSEND){/* clear ADDSEND flag */i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);/* exit the function */return ;}else{/* clear the bit of AE */i2c_flag_clear(I2C1,I2C_FLAG_AERR);}/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C1);/* wait until the stop condition is finished */while(I2C_CTL0(I2C1)&0x0200);}
}/*!\brief      write buffer of data to the I2C EEPROM\param[in]  p_buffer: pointer to the buffer  containing the data to be written to the EEPROM\param[in]  write_address: EEPROM's internal address to write to\param[in]  number_of_byte: number of bytes to write to the EEPROM\param[out] none\retval     none
*/
void eeprom_buffer_write(uint8_t* p_buffer, uint8_t write_address, uint16_t number_of_byte)
{uint8_t number_of_page = 0, number_of_single = 0, address = 0, count = 0;address = write_address % I2C_PAGE_SIZE;count = I2C_PAGE_SIZE - address;number_of_page =  number_of_byte / I2C_PAGE_SIZE;number_of_single = number_of_byte % I2C_PAGE_SIZE;/* if write_address is I2C_PAGE_SIZE aligned  */if(0 == address){while(number_of_page--){eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE); eeprom_wait_standby_state();write_address +=  I2C_PAGE_SIZE;p_buffer += I2C_PAGE_SIZE;}if(0 != number_of_single){eeprom_page_write(p_buffer, write_address, number_of_single);eeprom_wait_standby_state();}      }else{/* if write_address is not I2C_PAGE_SIZE aligned */if(number_of_byte < count){ eeprom_page_write(p_buffer, write_address, number_of_byte);eeprom_wait_standby_state();}else{number_of_byte -= count;number_of_page =  number_of_byte / I2C_PAGE_SIZE;number_of_single = number_of_byte % I2C_PAGE_SIZE;if(0 != count){eeprom_page_write(p_buffer, write_address, count);eeprom_wait_standby_state();write_address += count;p_buffer += count;} /* write page */while(number_of_page--){eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE);eeprom_wait_standby_state();write_address +=  I2C_PAGE_SIZE;p_buffer += I2C_PAGE_SIZE;}/* write single */if(0 != number_of_single){eeprom_page_write(p_buffer, write_address, number_of_single); eeprom_wait_standby_state();}}}  
}#endif //#if I2C1_MODE == I2C1_MODE_POLL

at24c08.h

/*
**------------------------------------------------------------------------------------------------------
** Modified by:			
** Modified date:	
** Version:
** Descriptions:		
********************************************************************************************************/
#ifndef __24C08_H
#define __24C08_H
#include "i2c.h"#if I2C1_MODE == I2C1_MODE_POLL
/* Private function prototypes -----------------------------------------------*/
void eeprom_buffer_read(uint8_t* p_buffer, uint8_t read_address, uint16_t number_of_byte);
void eeprom_buffer_write(uint8_t* p_buffer, uint8_t write_address, uint16_t number_of_byte);
#endif  //#if I2C1_MODE == I2C1_MODE_POLL
#endif //__24C08_H
/*********************************************************************************************************END FILE
*********************************************************************************************************/

i2c1de 初始化在 i2c1.c中

/*** PB10 PB11 config I2C1
*/
void i2c1_config(void)
{/* enable GPIOB clock */rcu_periph_clock_enable(RCU_GPIOB);/* enable I2C1 clock */rcu_periph_clock_enable(RCU_I2C1);/* connect PB10 to I2C1_SCL *//* connect PB11 to I2C2_SDA */gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_10 | GPIO_PIN_11);//配置PB10,PB11为复用功能/* configure I2C clock */i2c_clock_config(I2C1, I2C1_SPEED, I2C_DTCY_2);/* configure I2C address */i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_SLAVE_ADDR);/* enable I2C1 */i2c_enable(I2C1);/* enable acknowledge */i2c_ack_config(I2C1, I2C_ACK_ENABLE);
}

4、主函数调用,我们连续写入一个字符串,超过16个字节,然后读取,看是否一致

    char r_buff[48] = {0};  char *buff = "hello world,GD32F330RCT6!";eeprom_buffer_write(r_buff,0,sizeof(r_buff)); //清零delay_1ms(200);eeprom_buffer_write(buff,0,strlen(buff));delay_1ms(200);eeprom_buffer_read(r_buff,0,48);printf("read data form eeprom = %s\r\n",r_buff);

5、开机打印信息如下:
在这里插入图片描述
6 、代码路径:https://gitee.com/xiaoguo-tec_0/gd32-iap-code.git

这篇关于单片机GD32F303RCT6 (Macos环境)开发 (十六)—— Eeprom AT24C08的读取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/205586

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

修复已被利用的高危漏洞! macOS Sequoia 15.6.1发布

《修复已被利用的高危漏洞!macOSSequoia15.6.1发布》苹果公司于今日发布了macOSSequoia15.6.1更新,这是去年9月推出的macOSSequoia操作... MACOS Sequoia 15.6.1 正式发布!此次更新修复了一个已被黑客利用的严重安全漏洞,并解决了部分中文用户反馈的

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块