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

相关文章

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 开发的打飞机游戏脚本代码解释初始化部

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Macos创建python虚拟环境的详细步骤教学

《Macos创建python虚拟环境的详细步骤教学》在macOS上创建Python虚拟环境主要通过Python内置的venv模块实现,也可使用第三方工具如virtualenv,下面小编来和大家简单聊聊... 目录一、使用 python 内置 venv 模块(推荐)二、使用 virtualenv(兼容旧版 P