/*****************************
* Copyright (C), 2015, 深圳市泰和安科技有限公司
* 文件名称: iic.c
* 文件描述: 用于驱动FT24c02
* 作 者: Riven
* 建立时间: 2017.10.16
* 版 本: 0.1
****************************/
/****************
FT24C02A
8位数据地址
16字节页写模式
共有16页,每页16个字节共256个字节
写之前自动擦除
写保护由硬件引脚控制
SCL上升沿时数据被锁存到flash中
写保护引脚低电平写使能
DriverAddr:1010+EEPROM芯片的3bit编码(000~111)+1(写)/0(读)
本程序仅一片EEprom,故芯片编号使用000,所以写操作芯片地址DRIVER_WADDR为10100001即0XA1,读操作地址DRIVER_RADDR为10100000,即0XA0;
**********************/
//注意:使用IIC写函数后续延时至少5ms
#include "iic.h"
#include "delay.h"
#include "string.h"
static void IIC_GPIO_Configuration(void);
static void IIC_Mode_Configuration(void);
void IIC_Init(void);
uint8_t EE_WritePage(uint8_t DriverAddr,uint8_t WriteAddr,uint8_t nByte,uint8_t *pBuffer);
uint8_t EE_ReadNByte(uint8_t DriverAddr, uint8_t ReadAddr, uint8_t nByte, uint8_t *pBuffer);
/**
* @brief IIC初始化
* @param 无
* @retval 无
*/
void iic_init(void)
{
IIC_GPIO_Configuration();
IIC_Mode_Configuration();
}
/**
* @brief IIC引脚配置
* @param 无
* @retval 无
*/
static void IIC_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF,ENABLE);
GPIO_InitStruct.GPIO_Pin = IIC_GPIO_SCL | IIC_GPIO_SDA;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //硬件接上拉电阻
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(IIC_GPIO_PORT,&GPIO_InitStruct);
GPIO_PinAFConfig(IIC_GPIO_PORT, GPIO_PinSource6, GPIO_AF_1);
GPIO_PinAFConfig(IIC_GPIO_PORT, GPIO_PinSource7, GPIO_AF_1);
}
/**
* @brief IIC工作参数配置
* @param 无
* @retval 无
*/
static void IIC_Mode_Configuration(void)
{
I2C_InitTypeDef I2C_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
I2C_Cmd(I2C2, DISABLE);
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStruct.I2C_DigitalFilter = 0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_OwnAddress1 = 0XA5;
I2C_InitStruct.I2C_Timing = 0x00210507; //SDADEL有差别 0x00210507
I2C_Init(I2C2,&I2C_InitStruct);
I2C_Cmd(I2C2, ENABLE);
}
/**
* @brief IIC页写
* @param DriverAddr 设备地址,即flash的地址
* @param WriteAddr 数据地址
* @param nByte 写入的字节数,最大不能超过一页16byte
* @param pBuff 写入的数据
* @retval 0 成功
* 1 失败
*/
uint8_t EE_WritePage(uint8_t DriverAddr,uint8_t WriteAddr,uint8_t nByte,uint8_t *pBuffer)
{
uint8_t WriteByte = 0;
uint8_t TimeOut = 0;
// IIC_CP_LOW;//写保护失能
/* 1.等待空闲 */
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
/* 2.开启写模式 ,Transmit data register empty */
TimeOut = TIMEOUT;
I2C_TransferHandling(I2C2, DriverAddr, 1,I2C_Reload_Mode, I2C_Generate_Start_Write);//I2C_SoftEnd_Mode
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
/* 3.发送数据地址,Transfer complete reload */
I2C_SendData(I2C2, WriteAddr);
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TCR) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
/* 4.连续发送数据 */
I2C_TransferHandling(I2C2, DriverAddr, nByte, I2C_AutoEnd_Mode, I2C_No_StartStop);
for(WriteByte = 0; WriteByte < nByte; WriteByte++)
{
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
I2C_SendData(I2C2, pBuffer[WriteByte]);
}
/* 5.STOP detection flag */
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
delay_nus(DELAY_TIME);
return 0;
}
/**
* @brief 从EEPROM中读取N个字节
* @param DriverAddr 设备地址,即flash的地址
* @param ReadAddr 数据地址
* @param nByte 读取的字节数
* @param pBuffer 读取的数据
* @retval 0 成功
* 1 失败
*/
uint8_t EE_ReadNByte(uint8_t DriverAddr, uint8_t ReadAddr, uint8_t nByte, uint8_t *pBuffer)
{
uint8_t ReadByte = 0;
uint8_t TimeOut = 0;
// IIC_CP_LOW;//写保护失能
/* 1.等待空闲 */
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
// delay_nus(Delay_Nk);
/* 2.开启读模式 */
I2C_TransferHandling(I2C2, DriverAddr, 1,I2C_SoftEnd_Mode, I2C_Generate_Start_Write); //I2C_Reload_Mode
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXIS) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
/* 3.发送数据地址 */
I2C_SendData(I2C2, ReadAddr);
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_TC) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
/* 4.连续接收数据 */
I2C_TransferHandling(I2C2, DriverAddr, nByte, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
for(ReadByte = 0; ReadByte < nByte; ReadByte++)
{
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
pBuffer[ReadByte] = I2C_ReceiveData(I2C2);
}
/* 5.STOP detection flag */
TimeOut = TIMEOUT;
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF) == RESET)
{
if((TimeOut--) == 0)
{
return 1;
}
}
delay_nus(DELAY_TIME);
return 0;
}
void test_iic(void)
{
uint8_t i;
uint8_t ret = 0;
uint8_t addr[16] = {0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xA0,0xB0,0Xc0,0Xd0,0xe0,0xF0};
uint8_t send_buff[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
uint8_t rec_buff[16] = {0};
for( i = 0; i < 16;i++)
{
ret = EE_WritePage(DRIVER_RADDR,addr[i],16, send_buff);
if(ret == 1)
break;
}
for(i = 0; i < 16;i++)
{
EE_ReadNByte(DRIVER_RADDR,addr[i], 16, rec_buff);
memset(rec_buff,0,16);
}
}