注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题

liufan的个人空间 http://home.eeworld.com.cn/space-uid-53362.html [收藏] [复制] [分享] [RSS]

日志

STM32 I2C 读写EEPROM 的源码!

已有 5991 次阅读2014-11-20 15:50 |个人分类:ARM| 开发平台, 网上, 硬件

在网上搜集了一些源码,经过整理,调试没有问题。
硬件平台:STM32F103ZET6
开发平台:keil 4

 #define I2C_EE                      I2C1

 

void I2C_Configuration(void)

{

    I2C_InitTypeDef  I2C_InitStructure;

    GPIO_InitTypeDef  GPIO_InitStructure;

 

    /* GPIOB Periph clock enable */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,    ENABLE); // 开启时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,     ENABLE);

   

    /* eeprom wp Control Pin set */

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_WriteBit(GPIOB, GPIO_Pin_8, Bit_RESET);        // 设置初始化态,取消保护

   

    /* PB6,7 SCL and SDA */

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;  // 复用开漏输出

    GPIO_Init(GPIOB, &GPIO_InitStructure);


    I2C_DeInit(I2C_EE);

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;          

    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

    I2C_InitStructure.I2C_OwnAddress1 = 0x00;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_InitStructure.I2C_ClockSpeed = 100000;       //100K速度

    I2C_Cmd(I2C_EE, ENABLE);  // 开启I2C模块

    I2C_Init(I2C_EE, &I2C_InitStructure); // 写入I2C配置

    /*允许1字节1应答模式*/

    I2C_AcknowledgeConfig(I2C_EE, ENABLE);

}


void I2C_EE_Standby(void)     

{

    vu16 SR1_Tmp;

    do{

        /*起始位*/

        I2C_GenerateSTART(I2C1, ENABLE);

        /*SR1*/

        SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);

        /*器件地址()*/

        I2C_Send7bitAddress(I2C1, I2C_EE_HW_ADDR, I2C_Direction_Transmitter);

    }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

    /**/

    I2C_ClearFlag(I2C1, I2C_FLAG_AF);

    /*停止位*/   

    I2C_GenerateSTOP(I2C1, ENABLE);

}


void I2C_EE_ByteWrite(uint16 mem_addr, uint8 dat)

{

    I2C_EE_ReadArray(&dat, mem_addr, 1);

}

/*************************************************

**函数名:I2C_EE_WriteArray

**功能:写多个字节

**注意事项:字写入同样需要调用忙判断

*************************************************/

void I2C_EE_WriteArray(uint16 mem_addr ,u8* pBuffer,u16 len)

{

    uint8 hw_addr,byte_addr;

   

    if( len == 0 )

        return;

   

    if( mem_addr >= I2C_EE_MAX_BYTE_ADDR )  return;

 

#ifdef _24C04_C08_C16   // 超过256字节,有分页地址

   

    if( mem_addr > 255 )    // eeprom address calc

    {

        hw_addr = I2C_EE_HW_ADDR | (uint8)(mem_addr>>7); // Set target slave address-

    }

    else

    {

        hw_addr = I2C_EE_HW_ADDR;               // Set target slave address

    }

#else

 

    hw_addr = I2C_EE_HW_ADDR;               // Set target slave address

 

#endif

 

    byte_addr = (uint8)mem_addr;

 

 

    /* 起始位 */

    I2C_GenerateSTART(I2C_EE, ENABLE);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT)); 

 

    /* 发送器件地址()*/

    I2C_Send7bitAddress(I2C_EE, hw_addr, I2C_Direction_Transmitter);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

 

    /*发送数据起始地址*/

    I2C_SendData(I2C_EE, byte_addr);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

 

    while(len)

    {

        /* 写一个字节*/

        I2C_SendData(I2C_EE, *pBuffer);

        while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

       

        pBuffer++; // 指向下一个存储空间

        len--;       // 数目调整

    }

   

    /* 停止位*/

    I2C_GenerateSTOP(I2C_EE, ENABLE);

 

    I2C_EE_Standby();

}


uint8 I2C_EE_ByteRead(uint16 mem_addr)

{

    uint8 recd;

    I2C_EE_ReadArray(&recd, mem_addr, 1);

    return recd;

}

/***************************************************

**函数名:I2C_ReadS

**功能:读取24C02多个字节

**注意事项:24C02256字节,8位地址,A0-A2固定为0,从器件地址为EEPROM_ADDR

***************************************************/

void I2C_EE_ReadArray(uint8* pBuffer, uint16 mem_addr , u16 len)

{

    uint8 hw_addr,byte_addr;

   

    if( len == 0 )

        return;

   

    if( mem_addr >= I2C_EE_MAX_BYTE_ADDR )  return;

 

#ifdef _24C04_C08_C16   // 超过256字节,有分页地址

   

    if( mem_addr > 255 )    // eeprom address calc

    {

        hw_addr = I2C_EE_HW_ADDR | (uint8)(mem_addr>>7); // Set target slave address-

    }

    else

    {

        hw_addr = I2C_EE_HW_ADDR;               // Set target slave address

    }

#else

 

    hw_addr = I2C_EE_HW_ADDR;               // Set target slave address

 

#endif

 

    byte_addr = (uint8)mem_addr;

 

    while(I2C_GetFlagStatus(I2C_EE, I2C_FLAG_BUSY));

       

    /*允许1字节1应答模式*/

    I2C_AcknowledgeConfig(I2C_EE, ENABLE);

 

    /* 发送起始位 */

    I2C_GenerateSTART(I2C_EE, ENABLE);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

 

    /*发送器件地址()*/

    I2C_Send7bitAddress(I2C_EE,  hw_addr , I2C_Direction_Transmitter);

    while (!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

 

    /*发送储存地址*/

    I2C_SendData(I2C_EE, byte_addr);

    while (!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*数据已发送*/

       

    /*起始位*/

    I2C_GenerateSTART(I2C_EE, ENABLE);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_MODE_SELECT));

   

    /*器件读*/

    I2C_Send7bitAddress(I2C_EE, hw_addr, I2C_Direction_Receiver);

    while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

   

    while(len)

    {

        if(len==1)

        {

             I2C_AcknowledgeConfig(I2C_EE, DISABLE); //最后一位后要关闭应答的

         I2C_GenerateSTOP(I2C_EE, ENABLE);           //发送停止位

        }

        while(!I2C_CheckEvent(I2C_EE, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */

        *pBuffer = I2C_ReceiveData(I2C_EE);

        pBuffer++; // 指向下一个存储空间

        len--;       // 数目调整

    }

    //再次允许应答模式

    I2C_AcknowledgeConfig(I2C_EE, ENABLE);

}

//  应用代码示例

void I2C_EE_Init(void)

{

    Uint8 buf[4] = {1,2,3,4};

    I2C_Configuration();

I2C_EE_WriteArray(0x0200,       buf,    4);

    I2C_EE_ReadArray(buf,           0x0200, 4);

}


评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-5-26 21:54 , Processed in 0.016936 second(s), 13 queries , Gzip On, Redis On.

Powered by EEWORLD电子工程世界

© 2018 http://bbs.eeworld.com.cn/

返回顶部