GD32F3x0之I2C配置以及对24C128进行数据存储和读取

掉电保存数据模块,有SPI通信和I2C通信,这次简单用I2C对24C128进行简单测试

废话不多说,直接上代码

一、i2c.h
#ifndef I2C_H
#define I2C_H

#include "gd32f3x0.h"
#include "systick.h"

void i2c_config(void);

void i2c_byte_write(uint8_t* p_buffer, uint16_t write_address);
void i2c_byte_read(uint8_t* p_buffer, uint16_t read_address);

void i2c_buff_write(uint8_t* p_buffer, uint16_t write_address,uint8_t number_to_write);
void i2c_buff_read(uint8_t* p_buffer, uint16_t read_address,uint8_t number_to_read);
void V_data_to_24c128(void);

#endif 
二、i2c.c

其中需要注意的是寄存器地址,在不同的24c器件中,它的寄存器地址会有不同,这里的寄存器地址是两个字节如下图所示

所以,要是写其他的24cxx记得看用户手册

还有一点,读字节时需要注意何时非应答和停止

在GD32F3x0中有详细介绍 如下图

#include "i2c.h"

#define I2C_SlAVER_ADDRESS (0xA0)

void i2c_config(void)
{		
	
    rcu_periph_clock_enable(RCU_I2C1);
	rcu_periph_clock_enable(RCU_GPIOF);
	i2c_deinit(I2C1);
		
	gpio_af_set(GPIOF, GPIO_AF_0, GPIO_PIN_6);  //  PF6  AF_0   CLK   
    gpio_af_set(GPIOF, GPIO_AF_0, GPIO_PIN_7);	//  PF7  AF_0		SDA 
    gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_6);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
    gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_7);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
	
		
    i2c_clock_config(I2C1,100000,I2C_DTCY_2);
    i2c_mode_addr_config(I2C1,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,I2C_SlAVER_ADDRESS);
    i2c_enable(I2C1);
    i2c_ack_config(I2C1,I2C_ACK_ENABLE);

		//i2c_ackpos_config(I2C1,I2C_ACKPOS_CURRENT);
}

void i2c_byte_write(uint8_t* p_buffer, uint16_t write_address)
{
	
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY)){;}   // 等忙过去
 i2c_start_on_bus(I2C1);  											//	起始信号
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND)){;}  //  判断起始信号是否发送成功
 i2c_master_addressing(I2C1, I2C_SlAVER_ADDRESS, I2C_TRANSMITTER); //建立与从设备连接方向
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND)){;}    //判断连接是否成功
i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);	
while(!i2c_flag_get(I2C1, I2C_FLAG_TBE)){;}  //判断发送寄存器是否为空  空为1
i2c_data_transmit(I2C1, (write_address>>8));   		 //发送寄存器地址的高8位地址
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC)){;}			//判断字节是否发送完成
i2c_data_transmit(I2C1, (write_address&0xFF));   		 //发送寄存器地址的低8位地址
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC)){;}			//判断字节是否发送完成
i2c_data_transmit(I2C1, *p_buffer);							// 发送一个字节的数据
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC)){;}				//判断字节是否发送完成
2c_stop_on_bus(I2C1);											// 停止信号
}

void i2c_byte_read(uint8_t* p_buffer, uint16_t read_address)
{		
//		 i2c_ackpos_config(I2C1,I2C_ACKPOS_CURRENT);
while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY)){;}   // 等忙过去
i2c_start_on_bus(I2C1);  											//	起始信号
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND)){;}  //  判断起始信号是否发送成功
i2c_master_addressing(I2C1, I2C_SlAVER_ADDRESS, I2C_TRANSMITTER); //建立与从设备连接
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND)){;}    //判断连接是否成功	
i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
while(SET != i2c_flag_get(I2C1, I2C_FLAG_TBE)){;}  //判断发送寄存器是否为空  空为1
i2c_data_transmit(I2C1, (read_address>>8));   //发送寄存器地址的高8位地址
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC)){;}			//判断字节是否发送完成
i2c_data_transmit(I2C1, (read_address&0xFF));   //发送寄存器地址的低8位地址
while(!i2c_flag_get(I2C1, I2C_FLAG_BTC)){;}			//判断字节是否发送完成
		
i2c_start_on_bus(I2C1);  											//	起始信号
while(!i2c_flag_get(I2C1, I2C_FLAG_SBSEND)){;}  //  判断起始信号是否发送成功	
i2c_master_addressing(I2C1, I2C_SlAVER_ADDRESS, I2C_RECEIVER); //建立与从设备连接方向
			
i2c_ack_config(I2C1,I2C_ACK_DISABLE);
		 											
while(!i2c_flag_get(I2C1, I2C_FLAG_ADDSEND)){;}    //判断连接是否成功
i2c_flag_clear(I2C1,I2C_FLAG_ADDSEND);
i2c_stop_on_bus(I2C1);										// 停止信号
				
while(!i2c_flag_get(I2C1, I2C_FLAG_RBNE)){;}			//判断接收寄存器是否非空
*p_buffer = i2c_data_receive(I2C1);						//开始接收数据
		
i2c_ack_config(I2C1, I2C_ACK_ENABLE);  	  //  重新启动应答,方便下一次字节读取
}
void i2c_buff_write(uint8_t* p_buffer, uint16_t write_address,uint8_t number_to_write)
{
	while(number_to_write--)
		{
			i2c_byte_write(p_buffer++,write_address++);
			delay_1ms(7);
		}

}
void i2c_buff_read(uint8_t* p_buffer, uint16_t read_address,uint8_t number_to_read)
{
	while(number_to_read--)
		{
			i2c_byte_read(p_buffer++,read_address++);
		}

}

主函数页面就不写了,非常简单,直接调用写 然后再读出来就行了   

有一点需要注意,如果一页不够写的话,需要等待 换页,否者会从本页开始继续写

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值