ac7811---硬件i2c---FM24C16D

发布时间:2024年01月18日

1.使用硬件i2c,polling模式
2.从任意地址写任意长度数据暂未实现
3.FM24C16D的地址说明
在这里插入图片描述

#define I2C_READY_STATUS_TIMEOUT        400000          ///< I2C timeout value
#define I2C_POLLING_SW			(TRUE)
#define I2C_SLAVE_ADDR			(0xA0)//从机地址
#define I2C_STAND_MODE			(FALSE)//设置为TRUE时,标准模式,否则是快速模式.
#define I2C_DATA_TTL_LEN		(8)//数据长度为8.
#define I2C_SDA_PIN			(GPIO_PB8)
#define I2C_SCL_PIN			(GPIO_PD10)

#define I2C_READ                        0x01			///< I2C read
#define I2C_WRITE                       0x0  			///< I2C write
void I2C_Init(void)
{
	I2C_ConfigType i2cConfig = {0};
	
    /*初始化I2C引脚.*/
	GPIO_SetFunc(I2C_SDA_PIN, GPIO_FUNC_2);
	GPIO_SetFunc(I2C_SCL_PIN, GPIO_FUNC_2);
    
    /*初始化I2C模块.*/
	i2cConfig.setting.master = ENABLE;
	#if (I2C_POLLING_SW)
	i2cConfig.setting.intEn  = DISABLE;
	#else
	i2cConfig.setting.intEn  = ENABLE;
	#endif
	i2cConfig.setting.i2cEn  = ENABLE;
	i2cConfig.setting.syncEn = ENABLE;
	i2cConfig.setting.gcaEn = ENABLE;
	i2cConfig.setting.addressExt = DISABLE;
	
	i2cConfig.addr1	= I2C_SLAVE_ADDR;
	#if (I2C_STAND_MODE)//100K波特率
	i2cConfig.sampleCNT = 11;//speed = APBclk/((sampleCnt+1)*(stepCNT+1)*2)
	i2cConfig.stepCNT = 19;
	#else //400K波特率
	i2cConfig.sampleCNT = 11;//speed = APBclk/((sampleCnt+1)*(stepCNT+1)*2)
	i2cConfig.stepCNT = 4;
	#endif
	I2C_Initialize(I2C2, &i2cConfig);
}

void WRITE(uint16_t addr, uint8_t data)
{
	uint8_t tempWrBuf[2];
	uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
	tempWrBuf[0] = (uint8_t)addr;
	tempWrBuf[1] = data;
	I2C_MasterWrite(I2C2, slaveAddr, &tempWrBuf[0], 2);	
	udelay(1500);
 }


 uint8_t  READ(uint16_t addr)
{
	uint8_t wdata;
	uint8_t rdata;

	uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
	wdata = (uint8_t)addr;
	I2C_MasterWrite(I2C2, slaveAddr, &wdata, 1);//此函数最多只能读当前页数据
	I2C_MasterRead(I2C2, (I2C_SLAVE_ADDR>>1), &rdata,1);
	return rdata;
}


 
uint16_t READWORD(uint16_t addr)
{
	uint8_t wdata;
	uint8_t rdata[2];
	uint16_t data;

	uint32_t slaveAddr =(uint32_t) (((addr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
	wdata = (uint8_t)addr;
	I2C_MasterWrite(I2C2, slaveAddr, &wdata, 1);
	I2C_MasterRead(I2C2, (I2C_SLAVE_ADDR>>1), &rdata[0],2);

	data = (rdata[0]<<8 | rdata[1]);
	return data;
}
void ERASE(void)
{
	uint8_t tempWrBuf[600];
	memset(tempWrBuf,0x0,600);
	WriteBytes(0x0, tempWrBuf, 600);
}


/**
* @prototype WriteBytes(uint8_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
*
* @param[in] startAddr:写数据起始地址
* @param[in] pDataBuf: 写数据缓存区
* @param[in] dataLen:  写数据长度
* @return	 void
*
* @brief  	 向EEPROM写入数据.**此函数地址只能是页的整数倍**
*/
void WriteBytes(uint16_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
{
	uint8_t ii,restLen,wrTimes;
	uint8_t tempWrBuf[16 + 1];
	
	if ((startAddr + (dataLen - 1)) > 2047){return;}//地址超出范围退出
	
	restLen = (dataLen % 16);
	wrTimes = (dataLen / 16);
	
	for (ii = 0; ii < wrTimes; ii++)
	{
		tempWrBuf[0] = (uint8_t)startAddr;
		memcpy(&tempWrBuf[1], &pDataBuf[ii * 16], 16);//单次写页16字节
		
		uint32_t slaveAddr =(uint32_t) (((startAddr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
		I2C_MasterWrite(I2C2, slaveAddr, tempWrBuf, 16+1);//此函数只能写入当前页的数据
		startAddr   += 16;
		mdelay(5);//需要等待5ms发送下一条写入命令
	}
	
	if (restLen > 0)//非满页,需要单字节方式写入
	{
		tempWrBuf[0] = (uint8_t)startAddr;
		memcpy(&tempWrBuf[1], &pDataBuf[ii * 16], restLen);//单次写页16字节
		
		uint32_t slaveAddr =(uint32_t) (((startAddr>>8)&0x07)|(I2C_SLAVE_ADDR>>1));
		I2C_MasterWrite(I2C2, slaveAddr, tempWrBuf, restLen+1);	
		mdelay(5);//需要等待5ms发送下一条写入命令
	}
}
 
文章来源:https://blog.csdn.net/liuyuedechuchu/article/details/135677551
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。