Read four hundred and forty | return one

Pure silicon (advanced)

Building owner
 

[Zhaoyi GD32H759I-EVAL] i2c read/write at24c02 test [Copy Link]

 

The at24c02 read/write test is performed through the i2c routine on the official website.

 

1、 Hardware

 

1.1. i2c hardware circuit diagram

I2C1 uses ports PH4 and PB11

 

1.2 Mapping of PH4 and PB11 in the Data Book

 

1.3. at24c02 memory parameters

 

storage structure

 

The total storage space of at24c02 is 2048bits=2048/8=256 bytes. There are 32 pages inside, and each page has 8 bytes.

 

2、 Program part

 

2.1. i2c pin configuration

 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 Clock Configuration

 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 Write Function

 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 Read Function

 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(); }

 

3、 Operation results

 

After downloading the program and running the development board, the content of writing and reading at24c02 will be displayed on the display screen.

 

4、 Attachment

 

2024051423554292.c (18.66 KB, number of downloads: 0)
at24cxx.h (2.64 KB, downloads: 0)
i2c.c (4.6 KB, download times: 0)
i2c.h (2.38 KB, number of downloads: 0)

 

 

Latest reply

The article is very good. The source code is provided from the schematic diagram to the introduction of peripherals.   details reply Published on 11:40 the day before yesterday
Like (1) follow
 
 

reply
report

Moderator

sofa
 

The article is very good. The source code is provided from the schematic diagram to the introduction of peripherals.

 
 
 

reply
You need to log in before you can reply Sign in | register

Guess you like it
look around
Find Data Book?

EEWorld Datasheet Technical Support

Related articles More>>
close
Recommended by webmaster Previous one /10  Next
Copyright Electronic Engineering World Beijing B2-20211791 Jing ICP Bei 10001474-1 TSSP [2006] No. 258 Jinggong Network Anbei No. 11010802033920 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
Quick reply Back to top Back to list