单片机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

相关文章

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部