单片机 STM32 HAL 闪存 AT24C02

#include "AT24Cxx.h"
/**********************************************************************/
// 功能描述: 初始化EEPROM(定义时钟,数据对应的端口及PIN脚,和操作速度)
// 输入参数:无
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
void AT24CxxInit(const IIC_PIN *PIN)
{
    IIC_Init(PIN);
//  GPIO_PortClock(PIN.WP.port,true);
//  GPIO_PinConfigure(PIN.WP.port,PIN.WP.num,GPIO_PIN_OUT_MODE,IIC_IO_SPEED);
//  GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_DISABLE);  //写保护使能
}
/**********************************************************************/
// 功能描述: EEPROM单字节写操作
// 输入参数:addr:数据存储地址   ch:待写入数据
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxWriteByte(const IIC_PIN *PIN, uint16_t addr, uint8_t ch)
{
    IIC_STATUS status;

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);
    status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)  //地址是否超过8位,越过,加入高位地址写操作
    IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF)); //超过,写高位地址
    status |= IIC_Wait_ACK(PIN);
#endif
    IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF)); //低位地址写入
    status |= IIC_Wait_ACK(PIN);
    IIC_WriteByte(PIN, ch);  //数据写入
    status |= IIC_Wait_ACK(PIN);
    IIC_Stop(PIN);   //停止
    if(status)
    {
        return(IIC_WRITE_ERR);
    }
    else
    {
        return(IIC_OK);
    }
}

/**********************************************************************/
// 功能描述: EEPROM多字节写操作
// 输入参数:addr:数据存储地址   *str:待写入数据串首指针  len:写入数据长度
// 输出参数:无
// 返 回 值:无
// 编写时间:2014.11.26
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxWriteStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str,
                           uint16_t len)
{
    uint16_t i;
    IIC_STATUS status;

    //GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_ENABLE);
    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);
    status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
    IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
    status |= IIC_Wait_ACK(PIN);
#endif
    IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
    status |= IIC_Wait_ACK(PIN);

    for(i = 0; i < len; i++)
    {
        if (((addr + i) % PAGE_LENGTH == 0) && (i > 0))
        {
            //判断是地址是否到达分页,是则完成页写。启动新页写操作
            IIC_Stop(PIN);
            //status |= IIC_Wait_ACK(PIN);
            osDelay(10);              //两个写操作之间,(参见芯片手册,最小值为5ms)
            IIC_Start(PIN);
            IIC_WriteByte(PIN, PIN->ADDR);
            status |= IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
            IIC_WriteByte(PIN, (uint8_t)(((addr + i) >> 8) & 0xFF));
            status |= IIC_Wait_ACK(PIN);
#endif
            IIC_WriteByte(PIN, (uint8_t)((addr + i) & 0xFF));
            status |= IIC_Wait_ACK(PIN);
        }

        IIC_WriteByte(PIN, *str++);
        status |= IIC_Wait_ACK(PIN);
    }
    IIC_Stop(PIN);
    //GPIO_PinWrite(PIN.WP.port,PIN.WP.num,AT24Cxx_WRITE_DISABLE);
    osDelay(10);
    if(status)
    {
        return (IIC_WRITE_ERR);
    }
    else
    {
        return (IIC_OK);
    }
}
/**********************************************************************/
// 功能描述: EEPROM单字节读操作
// 输入参数:addr:数据存储地址
// 输出参数:无
// 返 回 值:读取到的数据
// 编写时间:2014.11.26
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxReadByte(const IIC_PIN *PIN, uint16_t addr, uint8_t *data)
{
    uint8_t ch;
    IIC_STATUS status;

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);
    status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
    IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
    status |= IIC_Wait_ACK(PIN);
#endif
    IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
    status |= IIC_Wait_ACK(PIN);
    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR | 0x01);
    status |= IIC_Wait_ACK(PIN);
    IIC_ReadByte(PIN, &ch);
    IIC_NACK(PIN);
    IIC_Stop(PIN);
    *data = ch;
    if(status)
    {
        return (IIC_READ_ERR);
    }
    else
    {
        return (IIC_OK);
    }
}

/**********************************************************************/
// 功能描述: EEPROM多字节读操作
// 输入参数:addr:数据存储地址   len:读取长度
// 输出参数:*str:存储缓冲区首指针
// 返 回 值:读取到的数据
// 编写时间:2014.11.26
// 作    者:胡安勤
// 修改记录:
/**********************************************************************/
IIC_STATUS AT24CxxReadStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len)
{
    uint16_t i;
    IIC_STATUS status;

    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR);
    status = IIC_Wait_ACK(PIN);
#if ( ADDR_LENGTH == 2)
    IIC_WriteByte(PIN, (uint8_t)((addr >> 8) & 0xFF));
    status |= IIC_Wait_ACK(PIN);
#endif
    IIC_WriteByte(PIN, (uint8_t)(addr & 0xFF));
    status |= IIC_Wait_ACK(PIN);
    IIC_Start(PIN);
    IIC_WriteByte(PIN, PIN->ADDR | 0x01);
    status |= IIC_Wait_ACK(PIN);
    for(i = 0; i < len; i++)
    {
        if(i != 0 )
        {
            IIC_ACK(PIN);
        }
        IIC_ReadByte(PIN, str++);
    }
    IIC_NACK(PIN);
    IIC_Stop(PIN);
    if(status)
    {
        return (IIC_READ_ERR);
    }
    else
    {
        return (IIC_OK);
    }
}


#ifndef _AT24CXX_HEAD_
#define _AT24CXX_HEAD_
#include "main.h"
#include "stdio.h"
#include "stdint.h"
#include "hal_iic.h"
#include "cmsis_os.h" //FreeRTOS系统中调用osDelay()

#define PAGE_LENGTH   64       //C01,C02为8字节,C04及以上为16字节,C64 32
#define ADDR_LENGTH   2        //地址长度C01,C02为1个字节,C04及以上为2字节
#define AT24Cxx_ADDR  0xA0     //定义器件地址

#define AT24Cxx_WRITE_ENABLE    0x00  //使能数据写入
#define AT24Cxx_WRITE_DISABLE   0x01  //禁止数所写入


void AT24CxxInit(const IIC_PIN *PIN);
IIC_STATUS AT24CxxWriteByte(const IIC_PIN *PIN, uint16_t addr, uint8_t ch);
IIC_STATUS AT24CxxReadByte(const IIC_PIN *PIN, uint16_t addr, uint8_t *data);
IIC_STATUS AT24CxxWriteStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len);
IIC_STATUS AT24CxxReadStr(const IIC_PIN *PIN, uint16_t addr, uint8_t *str, uint16_t len);

#endif

24C02中文(商家版).pdf

24c02串行储存器中文官方资料手册.pdf

IIC介绍.docx

猜你喜欢

转载自blog.csdn.net/qq_29246181/article/details/105475318