×
单片机 > 单片机程序设计 > 详情

STM32 硬件I2C EEPROM命令解析

发布时间:2020-08-28 发布时间:
|
void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
{
    u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
    //写入地址是每页的第几位
    Addr = WriteAddr % I2C_PageSize;
    //在开始的一页要写入的个数
    count = I2C_PageSize - Addr;
    //要写入的页数
    NumOfPage = NumByteToWrite / I2C_PageSize;
    //不足一页的个数
    NumOfSingle = NumByteToWrite % I2C_PageSize;
    //EEPROM设为待命状态
    I2C_EE_WaitEepromStandbyState();
 
    //写入地址是页的开始
    if (Addr == 0)
    {
        //数据小于一页
        if (NumOfPage == 0)
        {
            //写少于一页的数据
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            //EEPROM设为待命状态
            I2C_EE_WaitEepromStandbyState();
        }
        //数据大于等于一页
        else
        {
            while (NumOfPage--)//要写入的页数
            {
                //写一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += I2C_PageSize;
                pBuffer += I2C_PageSize;
            }
            //剩余数据小于一页
            if (NumOfSingle!=0)
            {
                //写少于一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
            }
        }
    }
    //写入地址不是页的开始
    else
    {
        //数据小于一页
        if (NumOfPage== 0)
        {
            //写少于一页的数据
            I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
            //EEPROM设为待命状态
            I2C_EE_WaitEepromStandbyState();
        }
        //数据大于等于一页
        else
        {
            NumByteToWrite -= count;
            //重新计算要写入的页数
            NumOfPage = NumByteToWrite / I2C_PageSize;
            //重新计算不足一页的个数
            NumOfSingle = NumByteToWrite % I2C_PageSize;
 
            if (count != 0)
            {
                //将开始的空间写满一页
                I2C_EE_PageWrite(pBuffer, WriteAddr, count);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += count;
                pBuffer += count;
            }
            //要写入的页数
            while (NumOfPage--)
            {
                //写一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
                WriteAddr += I2C_PageSize;
                pBuffer += I2C_PageSize;
            }
            //剩余数据小于一页
            if (NumOfSingle != 0)
            {
                //写少于一页的数据
                I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
                //EEPROM设为待命状态
                I2C_EE_WaitEepromStandbyState();
            }
        }
    }
}
 
 
void I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
{
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //发送器件地址(写)
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, WriteAddr);
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //通过外设 I2C2发送数据
    I2C_SendData(I2C2, *pBuffer);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //产生 I2C2传输 STOP条件
    I2C_GenerateSTOP(I2C2, ENABLE);
}
 
void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
{
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
 
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //发送器件地址(写)
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
 
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, WriteAddr);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (! I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //写数据
    while (NumByteToWrite--)
    {
        //通过外设 I2C2发送数据
        I2C_SendData(I2C2, *pBuffer);
 
        //指针++
        pBuffer++;
 
        //检测主机发送的字节是否成功(检测EV8)
        while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    }
    //产生 I2C2 传输 STOP条件
    I2C_GenerateSTOP(I2C2, ENABLE);
}
 
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
{
    //EEPROM设为待命状态
    I2C_EE_WaitEepromStandbyState();
    //产生 I2C2传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
    //在一个单一的数据传输情况下读取数据之前禁用的ACK
    if (NumByteToRead==1)
    {
        I2C_AcknowledgeConfig(I2C2, DISABLE);//失能I2C2 的应答功能
    }
 
    //向指定的从 I2C设备传送地址字,选择发送方向
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
 
    //检测主机传输模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
 
    //使能I2C外设
    I2C_Cmd(I2C2, ENABLE);
 
    //通过外设 I2C2发送地址
    I2C_SendData(I2C2, ReadAddr);
 
    //检测主机发送的字节是否成功(检测EV8)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
    //产生 I2C2 传输 START条件
    I2C_GenerateSTART(I2C2, ENABLE);
 
    //通过START的产生,确定主机模式是否成功(检测EV5)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));
 
    //向指定的从 I2C设备传送地址字,选择接收方向
    I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Receiver);
 
    //检测主机接收模式是否成功(检测EV6)
    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
 
    //读取数据
    while (NumByteToRead)
    {
        //检测主机接收的字节是否成功(检测EV8)
        if (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))
        {
            if (NumByteToRead == 2)
            {
                //使能或者失能指定 I2C的应答功能
                I2C_AcknowledgeConfig(I2C2, DISABLE);
            }
 
            if (NumByteToRead == 1)
            {
                //产生 I2C2 传输 STOP条件
                I2C_GenerateSTOP(I2C2, ENABLE);
            }
 
            //返回通过 I2C2最近接收的数据
            *pBuffer = I2C_ReceiveData(I2C2);
 
            //指向下个地址
            pBuffer++;
            NumByteToRead--;
        }
    }
 
    //使能I2C2 的应答功能
    I2C_AcknowledgeConfig(I2C2, ENABLE);
 
}
 
 
void I2C_EE_WaitEepromStandbyState(void)
{
    vu16 SR1_Tmp = 0;
 
    do
    {
        //产生 I2C2传输 START条件
        I2C_GenerateSTART(I2C2, ENABLE);
        //读取指定的 I2C寄存器 I2C_SR1 并返回其值
        SR1_Tmp = I2C_ReadRegister(I2C2, I2C_Register_SR1);
        //向指定的从 I2C设备传送地址字 ,选择发送方向
        I2C_Send7bitAddress(I2C2, EEPROM_ADDRESS, I2C_Direction_Transmitter);
    } while (!(I2C_ReadRegister(I2C2, I2C_Register_SR1) & 0x0002));//地址发送结束
 
    //清除 I2Cx的应答错误标志位
    I2C_ClearFlag(I2C2, I2C_FLAG_AF);
 
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Keil(MDK-ARM)系列教程(七)_菜单