992|1

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【兆易GD32H759I-EVAL】 i2c读写at24c02测试 [复制链接]

 

通过官网的i2c例程测试下at24c02读写测试。

 

一、硬件部分

 

1.1、i2c硬件电路图部分

I2C1使用端口PH4和PB11

 

1.2、数据手册中PH4和PB11的映射

 

1.3、at24c02存储器参数

 

存储结构

 

at24c02总存储空间是2048bits=2048/8=256字节。内部有32页,每页有8个字节。

 

二、程序部分

 

2.1、i2c引脚配置

void gpio_config(void)
{
    /* enable I2C_SCL_PIN clock */
    rcu_periph_clock_enable(RCU_GPIO_I2C_SCL);
    /* enable I2C_SDA_PIN clock */
    rcu_periph_clock_enable(RCU_GPIO_I2C_SDA);
    /* enable I2C clock */
    rcu_periph_clock_enable(RCU_I2C);

    /* connect I2C_SCL_PIN to I2C_SCL */
    gpio_af_set(I2C_SCL_PORT, I2C_GPIO_AF, I2C_SCL_PIN);
    /* connect I2C_SDA_PIN to I2C_SDA */
    gpio_af_set(I2C_SDA_PORT, I2C_GPIO_AF, I2C_SDA_PIN);
    /* configure GPIO pins of I2C */
    gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN);
    gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, I2C_SCL_PIN);
    gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
    gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_60MHZ, I2C_SDA_PIN);
}

 

2.2、i2c时钟配置

void i2c_config(void)
{
    /* configure the I2C1 clock source selection */
    rcu_i2c_clock_config(IDX_I2C1, RCU_I2CSRC_IRC64MDIV);
    /* configure I2C timing */
    i2c_timing_config(I2CX, 0x0, 0x6, 0);
    i2c_master_clock_config(I2CX, 0x26, 0x73);
    /* enable I2C */
    i2c_enable(I2CX);
}

 

2.3、at24c02写函数

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);
            delay_1ms(6);
            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);
            delay_1ms(6);
        }
    } 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);
            delay_1ms(6);
        } 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);
                delay_1ms(6);
                write_address += count;
                p_buffer += count;
            }
            /* write page */
            while(number_of_page--) {
                eeprom_page_write(p_buffer, write_address, I2C_PAGE_SIZE);
                delay_1ms(6);
                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);
                delay_1ms(6);
            }
        }
    }
}

 

2.4、at24c02读函数

void eeprom_buffer_read(uint8_t *p_buffer, uint8_t read_address, uint16_t number_of_byte)
{
    uint32_t nbytes_reload = 0;
    i2c_process_enum state = I2C_START;
    uint32_t timeout = 0;
    uint8_t end_flag = 0;
    uint8_t restart_flag = 0;
    uint8_t first_reload_flag = 1;
    uint8_t last_reload_flag = 0;

    while(!end_flag) {
        switch(state) {
            case I2C_START:
                if(0 == restart_flag) {
                    /* clear I2C_TDATA register */
                    I2C_STAT(I2CX) |= I2C_STAT_TBE;
                    /* configure slave address */
                    i2c_master_addressing(I2CX, eeprom_address, I2C_MASTER_TRANSMIT);
                    /* configure number of bytes to be transferred */
                    i2c_transfer_byte_number_config(I2CX, 1);
                    /* disable I2C automatic end mode in master mode */
                    i2c_automatic_end_disable(I2CX);
                    /* i2c master sends start signal only when the bus is idle */
                    while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
                        timeout++;
                    }
                    if(timeout < I2C_TIME_OUT) {
                        i2c_start_on_bus(I2CX);
                        timeout = 0;
                        state = I2C_SEND_ADDRESS;
                    } else {
                        /* timeout, bus reset */
                        i2c_bus_reset();
                        timeout = 0;
                        state = I2C_START;
                        printf("i2c bus is busy in read!\n");
                    }
                } else {
                    /* restart */
                    i2c_start_on_bus(I2CX);
                    restart_flag = 0;
                    state = I2C_TRANSMIT_DATA;
                }
                break;
            case I2C_SEND_ADDRESS:
                /* wait until the transmit data buffer is empty */
                while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
                    timeout++;
                }
                if(timeout < I2C_TIME_OUT) {
                    /* send the EEPROM's internal address to write to : only one byte address */
                    i2c_data_transmit(I2CX, read_address);
                    timeout = 0;
                    state = I2C_RESTART;
                } else {
                    timeout = 0;
                    state = I2C_START;
                    printf("i2c master sends data timeout in read!\n");
                }
                break;
            case I2C_RESTART:
                /* wait until the transmit data buffer is empty */
                while((!i2c_flag_get(I2CX, I2C_FLAG_TC)) && (timeout < I2C_TIME_OUT)) {
                    timeout++;
                }
                if(timeout < I2C_TIME_OUT) {
                    /* configure the EEPROM's internal address to write to : only one byte address */
                    i2c_master_addressing(I2CX, eeprom_address, I2C_MASTER_RECEIVE);
                    /* enable I2C reload mode */
                    i2c_reload_enable(I2CX);
                    /* configure number of bytes to be transferred */
                    timeout = 0;
                    state = I2C_RELOAD;
                    restart_flag = 1;
                } else {
                    timeout = 0;
                    state = I2C_START;
                    printf("i2c master sends EEPROM's internal address timeout in read!\n");
                }
                break;
            case I2C_RELOAD:
                if(number_of_byte > MAX_RELOAD_SIZE) {
                    number_of_byte = number_of_byte - MAX_RELOAD_SIZE;
                    nbytes_reload = MAX_RELOAD_SIZE;
                } else {
                    nbytes_reload = number_of_byte;
                    last_reload_flag = 1;
                }
                if(1 == first_reload_flag) {
                    /* configure number of bytes to be transferred */
                    i2c_transfer_byte_number_config(I2CX, nbytes_reload);
                    if(1 == last_reload_flag) {
                        last_reload_flag = 0;
                        /* disable I2C reload mode */
                        if(number_of_byte <= MAX_RELOAD_SIZE) {
                            i2c_reload_disable(I2CX);
                            /* enable I2C automatic end mode in master mode */
                            i2c_automatic_end_enable(I2CX);
                        }
                    }
                    first_reload_flag = 0;
                    state = I2C_START;
                } else {
                    /* wait for TCR flag */
                    while((!i2c_flag_get(I2CX, I2C_FLAG_TCR)) && (timeout < I2C_TIME_OUT)) {
                        timeout++;
                    }
                    if(timeout < I2C_TIME_OUT) {
                        /* configure number of bytes to be transferred */
                        i2c_transfer_byte_number_config(I2CX, nbytes_reload);
                        /* disable I2C reload mode */
                        if(number_of_byte <= MAX_RELOAD_SIZE) {
                            i2c_reload_disable(I2CX);
                            /* enable I2C automatic end mode in master mode */
                            i2c_automatic_end_enable(I2CX);
                        }
                        timeout = 0;
                        state = I2C_TRANSMIT_DATA;
                    } else {
                        timeout = 0;
                        state = I2C_START;
                        printf("i2c master reload data timeout in read!\n");
                    }
                }
                break;
            case I2C_TRANSMIT_DATA:
                /* wait until TI bit is set */
                while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
                    timeout++;
                }
                if(timeout < I2C_TIME_OUT) {
                    while(nbytes_reload) {
                        delay_1ms(2);
                        /* wait until the RBNE bit is set and clear it */
                        if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)) {
                            /* read a byte from the EEPROM */
                            *p_buffer = i2c_data_receive(I2CX);
                            /* point to the next location where the byte read will be saved */
                            p_buffer++;
                            /* decrement the read bytes counter */
                            nbytes_reload--;
                        }
                    }
                    timeout = 0;
                    /* check if the reload mode is enabled or not */
                    if(I2C_CTL1(I2CX) & I2C_CTL1_RELOAD) {
                        timeout = 0;
                        state = I2C_RELOAD;
                    } else {
                        timeout = 0;
                        state = I2C_STOP;
                    }
                } else {
                    /* wait TI timeout */
                    timeout = 0;
                    state = I2C_START;
                    printf("i2c master read data timeout in read!\n");
                }
                break;
            case I2C_STOP:
                /* wait until the stop condition is finished */
                while((!i2c_flag_get(I2CX, I2C_FLAG_STPDET)) && (timeout < I2C_TIME_OUT)) {
                    timeout++;
                }
                if(timeout < I2C_TIME_OUT) {
                    /* clear STPDET flag */
                    i2c_flag_clear(I2CX, I2C_FLAG_STPDET);
                    timeout = 0;
                    state = I2C_END;
                    end_flag = 1;
                } else {
                    timeout = 0;
                    state = I2C_START;
                    printf("i2c master sends stop signal timeout in read!\n");
                }
                break;
            default:
                /* default status */
                state = I2C_START;
                end_flag = 1;
                timeout = 0;
                printf("i2c master sends start signal in read!\n");
                break;
        }
    }
}
 
 

2.5、main.c

#include "main.h"

void cache_enable(void);

char txbuf[]="https://bbs.eeworld.com.cn/GD32H759I-EVAL";
char rxbuf[];

int main(void)
{
	uint8_t x=0;
	uint32_t sd=0;
	uint32_t yd=0;
	cache_enable();
	systick_config();
	init_usart(115200);
	init_led();
	gpio_config();
	i2c_config();
	i2c_eeprom_init();
	exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0);
	init_lcd();
	LCDDisplayDir(LCD_SCREEN_HORIZONTAL);
    LCDClear(LCD_COLOR_WHITE);

	eeprom_buffer_write(txbuf, 0x00, sizeof(txbuf));
	
	LCDShowString(10, 20, 400,16, LCD_FONT_16, LCD_TEXT_TRANS, LCD_COLOR_RED, NULL, "at24c02 write data:");
	LCDShowString(10, 40, 400,16, LCD_FONT_16, LCD_TEXT_TRANS, LCD_COLOR_RED, NULL, txbuf);

	eeprom_buffer_read(rxbuf, 0x00, sizeof(txbuf));
	
	LCDShowString(10, 80, 400,16, LCD_FONT_16, LCD_TEXT_TRANS, LCD_COLOR_BLUE, NULL, "at24c02 read data:");
	LCDShowString(10, 100, 400,16, LCD_FONT_16, LCD_TEXT_TRANS, LCD_COLOR_BLUE, NULL, rxbuf);
 
	while(1) 
	{
		delay_1ms(100);
	}
}

void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

 

三、运行结果

 

下载程序,开发板运行后,显示屏上显示写和读at24c02的内容。

 

四、附件

 

2024051423554292.c (18.66 KB, 下载次数: 2)
at24cxx.h (2.64 KB, 下载次数: 2)
i2c.c (4.6 KB, 下载次数: 4)
i2c.h (2.38 KB, 下载次数: 2)

 

 

最新回复

文章非常棒,从原理图到外设的介绍,源代码都有提供。   详情 回复 发表于 2024-6-1 11:40
点赞(1) 关注
 
 

回复
举报

6968

帖子

11

TA的资源

版主

沙发
 

文章非常棒,从原理图到外设的介绍,源代码都有提供。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
[分享下载]C语言编程900例及C语言视频教学BT种子(谭浩强)

对于C语言的初学者,这些是很有用的东东,要用的下载吧,免费分享哦 C程序设计 谭浩强 清华大学出版社 第一讲 第一章 C语言 ...

【全】2007年全国大学生电子设计竞赛各题论文(包括本科组和高职高专组)

2007年全国大学生电子设计竞赛试题各题论文下载【包括部分主要电路及代码】 给各位备战2009大赛的XDJM作参考~~~~~ 音频信号分析 ...

(原创)网络摄像机外接红外对射报警实地测试

网络摄像机可以外接报警器这个基本上很多人都知道,但怎么接?软件怎么调试?接好之后怎么用?接好之后的网络摄像机和报警器 ...

EK_LM3S811问题集锦(Q&A)

:)看到论坛里很多关于LM3S811的资料零散在各处,于是做一个粗略的整理,期待能够对坛子里的朋友有益,也希望大家能够在这个基础 ...

今天上午10点直播【ST 家用电器三相电机控制解决方案】

意法半导体家用电器三相电机控制解决方案,具有丰富的生态系统、绿色节能、成熟可靠、系统级、全方位支持、使用方便等特点,用于 ...

光伏行业规模“狂飙”至87.41GW,机器视觉检测成保量提质“王牌”?

在产业政策引导和市场需求驱动的双重作用下,我国光伏产业已成为具备国际竞争优势的产业,在制造规模、技术水平和市场份额等方面 ...

为什么有的PCB要用压接连接器

以前我见过的PCB板对板连接器是贴片式或者直插焊接的,现在又见识到一种压接式连接器,居然是不需要用焊锡来焊接到板子上,而是 ...

5.1打工人的放松时刻

感谢大家在 https://bbs.eeworld.com.cn/thread-1280054-1-1.html的帮助,终于可以休息一下,打算找点或者玩点不一样的看看

FREERTOS串口输出出错

先上图: 866320 前面有三个错误 port.c第349行configASSERT( ucMaxPriorityValue == ( configKERNEL_INTERRUPT_PRIO ...

关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表