📄 eeprom.txt
字号:
#ifdef _EEPROM_BSP_C_
/*---------参数定义--------------*/
#define SDA_IN P3DIR &=~BIT3 // P3.3 IN
#define SDA_OUT P3DIR |=BIT3 // P3.3 OUT
#define SDA_LOW P3OUT &=~BIT3 // sda=0
#define SDA_HIGH P3OUT |=BIT3 // sda=1
#define SCL_IN P3DIR &=~BIT4 // P3.4 IN
#define SCL_OUT P3DIR |=BIT4 // P3.4 OUT
#define SCL_LOW P3OUT &=~BIT4
#define SCL_HIGH P3OUT |=BIT4
#define SDA P3IN & BIT3
#define MAX_Bytes 2048 //最大字节
#define E2ERROR BIT0 //E2PROM ERRORFLAG
uint16_t ERROR_FLAG;
//#define SomeNOP(); {_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();} //3US
//#define SomeNOP(); {_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();} //2US
#define SomeNOP();
{_NOP();_NOP();}//_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();} //1US
#define E2pDeviceSlaveAddr 0xa0 //e2prom的从地址
/*-------变量定义---------------*/
/*-------函数说明---------------*/
void EEPROM_WRITE_BYTE (uint16_t ADDR,uint8_t DATA);
void EEPROM_WRITE_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers);
uint8_t EEPROM_READ_BYTE (uint16_t ADDR);
void E2PROM_READ_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers);
//xzw uint8_t FM24C16_Check (void);
#else
/*---------参数定义-------------*/
/*--------变量定义--------------*/
/*--------函数说明---------------*/
extern void EEPROM_WRITE_BYTE (uint16_t ADDR,uint8_t DATA);
extern void EEPROM_WRITE_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers);
extern uint8_t EEPROM_READ_BYTE (uint16_t ADDR);
extern void E2PROM_READ_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers);
//xzw extern uint8_t FM24C16_Check (void);
#endif
//*************************************************
// DEMO,Driver
// Built with IAR Embedded Workbench Version:1.26B
//*************************************************#define _EEPROM_BSP_C_
#include "SYS_main.h"
/*-------------------------------------------------
调用方式:void EE_I2C_START (void)
函数说明:私有函数,I2C专用
-----------------------------------------------------*/
void EE_I2C_START (void)
{
SDA_OUT;
SCL_OUT;
SDA_HIGH;
SCL_HIGH;
SomeNOP();SomeNOP();SomeNOP();
SDA_LOW;
SomeNOP();SomeNOP();SomeNOP();
SCL_LOW;
SomeNOP();SomeNOP();SomeNOP();
}
/*-------------------------------------------------
调用方式:void EE_I2C_STOP (void)
函数说明:私有函数,I2C专用
-------------------------------------------------------*/
void EE_I2C_STOP (void)
{
SDA_OUT;
SCL_OUT;
SDA_LOW;
SomeNOP();SomeNOP();SomeNOP();
SCL_HIGH;
SomeNOP();SomeNOP();SomeNOP();
SDA_HIGH;
SomeNOP();SomeNOP();SomeNOP();
}
/*-------------------------------------------------
调用方式:void EE_I2C_ACK (void)
函数说明:私有函数,I2C专用,向接收器发送应答信号
----------------------------------------------*/
void EE_I2C_ACK (void)
{
SDA_OUT;
SCL_OUT;
SDA_LOW;
SomeNOP(); SomeNOP();SomeNOP();
SCL_HIGH;
SomeNOP(); SomeNOP();SomeNOP();
SCL_LOW;
// SomeNOP(); SomeNOP();SomeNOP();
}
/*-------------------------------------------------
调用方式:void EE_I2C_NOACK (void)
函数说明:私有函数,I2C专用,向接收器发送非应答信号
----------------------------------------------------*/
void EE_I2C_NOACK (void)
{
SDA_OUT;
SCL_OUT;
SDA_HIGH; SomeNOP();SomeNOP();SomeNOP();
SCL_HIGH; SomeNOP();SomeNOP();SomeNOP();
SCL_LOW;
//SomeNOP(); SomeNOP();SomeNOP();
}
/*-------------------------------------------------
调用方式:uint8_t EE_I2C_TX_BYTE (uint8_t DATA)
函数说明:私有函数,I2C专用,单字节写,并测试应答位,返回为1,写入成功,否则失败或器件坏
------------------------------------------------------------------------*/
uint8_t EE_I2C_TX_BYTE (uint8_t DATA)
{
uint8_t Rn=8,ackFG;
SDA_OUT;
SCL_OUT;
while(Rn--)
{
SCL_LOW;SomeNOP(); //1us+xus
if (DATA&0x80)
SDA_HIGH;
else
SDA_LOW;
DATA<<=1;
SCL_HIGH;
SomeNOP(); //1us+xus
}
SCL_LOW;
SDA_HIGH;
SDA_IN; //设为输入口,等待应答信号
SomeNOP();SomeNOP();//1us+2us
SCL_HIGH;
SomeNOP();SomeNOP();SomeNOP(); //3us
if(SDA) ackFG = 0; //判断是否接收到应答信号
else ackFG = 1;
SCL_LOW;
SomeNOP();SomeNOP();SomeNOP(); //3us
return(ackFG);
}
/*-----------------------------------------------------------
调用方式:uint8_t EE_I2C_RX_BYTE (void)
函数说明:私有函数,I2C专用,单字节读
-------------------------------------------------------------*/
uint8_t EE_I2C_RX_BYTE (void)
{
uint16_t Rn=8,DATA;
SDA_HIGH;
SDA_IN; // 端口为输入
SCL_OUT;
while(Rn--)
{
DATA<<=1;
SCL_LOW; SomeNOP();SomeNOP();SomeNOP(); //3us
SCL_HIGH;SomeNOP();//1us+xus
if (SDA)
DATA++;
}
SCL_LOW; SomeNOP();SomeNOP();SomeNOP(); //3us
return DATA;
}
/*-------------------------------------------------
调用方式:void EEPROM_WRITE_BYTE (uint16_t ADDR,uint8_t DATA)
函数说明:EEPROM的固定地址单字节写,如果是铁电,无需写入延时
----------------------------------*/
void EEPROM_WRITE_BYTE (uint16_t ADDR,uint8_t DATA)
{
uint8_t SlaveADDR;
SlaveADDR = 0xA0|((ADDR>>7)&0x0e);
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR); // E2PROM 片选
EE_I2C_TX_BYTE (ADDR);
EE_I2C_TX_BYTE (DATA);
EE_I2C_STOP ();
/*
while(1) //等待写时序(约10ms,用铁电时不用延时)
{
EE_I2C_START () ;
if(EE_I2C_TX_BYTE (SlaveADDR)) break;
_NOP();
} */
}
/*-------------------------------------------------
调用方式:void EEPROM_WRITE_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers)
函数说明:EEPROM的多字节写,StartAddr:起始地址, RdData:内容的首地址,Numbers:多字节,如果是铁电,无需写入延时
----------------------------------------------*/
void EEPROM_WRITE_MULTIBYTES (uint16_t StartAddr,uint8_t *RdData, uint16_t Numbers)
{
uint8_t SlaveADDR;
SlaveADDR = 0xA0|((StartAddr>>7)&0x0e);
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR); // E2PROM 片选
EE_I2C_TX_BYTE (StartAddr);
while(Numbers--)
{
EE_I2C_TX_BYTE (*RdData);
RdData++;
}
EE_I2C_STOP ();
/*
while(1) //等待写时序(约10ms,用铁电时不用延时)
{
EE_I2C_START () ;
if(EE_I2C_TX_BYTE (SlaveADDR)) break;
_NOP();
} */
}
/*-------------------------------------------------
调用方式:uint8_t EEPROM_READ_BYTE (uint16_t ADDR)
函数说明:EEPROM的固定地址单字节读
--------------------------------------------------------------*/
uint8_t EEPROM_READ_BYTE (uint16_t ADDR)
{
uint8_t SlaveADDR,DATA_R;
SlaveADDR = 0xA0|((ADDR>>7)&0x0e);
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR);
SomeNOP();
EE_I2C_TX_BYTE (ADDR);
SomeNOP();
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR+1);
SomeNOP();
DATA_R=EE_I2C_RX_BYTE();
EE_I2C_NOACK();
EE_I2C_STOP ();
return DATA_R;
}
/*-------------------------------------------------
调用方式:void E2PROM_READ_MULTIBYTES (uint16_t StartAddr, uint8_t *RdData, uint16_t Numbers)
函数说明:EEPROM的固定地址单字节读
--------------------------------------*/
void E2PROM_READ_MULTIBYTES (uint16_t StartAddr,uint8_t *RdData, uint16_t Numbers)
{
uint8_t SlaveADDR;
SlaveADDR = 0xA0|((StartAddr>>7)&0x0e);
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR); //片选
EE_I2C_TX_BYTE (StartAddr); //ROM首地址(0-2047)
EE_I2C_START ();
EE_I2C_TX_BYTE (SlaveADDR+1); //读
while(Numbers>1)
{
*RdData =EE_I2C_RX_BYTE();
EE_I2C_ACK(); //应答
Numbers--;
RdData++;
}
*RdData =EE_I2C_RX_BYTE();
EE_I2C_NOACK(); //非应答
EE_I2C_STOP ();
}
/*-------------------------------------------------
调用方式:void FM24C16_Check (void)
函数说明:FM24C16测试,分别写入0x55和0xaa,返回1正确,否则失败或器件坏
--------------------------------------------------------------------------*/
/*xzw uint8_t FM24C16_Check (void)
{
uint16_t ADDRESS;
uint8_t j,DATAW=0x55;
uint8_t DATAR;
for(ADDRESS=0;ADDRESS<MAX_Bytes;ADDRESS++)
{
FEED_DOG ( ); //喂狗
for(j=0;j<2;j++)//写0xaa和0x55
{
EEPROM_WRITE_BYTE(ADDRESS,DATAW);
DATAR=EEPROM_READ_BYTE(ADDRESS);
if(DATAR^DATAW) //写入和读出的不相同
{
for(ADDRESS=0;ADDRESS<MAX_Bytes;ADDRESS++)
{
EEPROM_WRITE_BYTE(ADDRESS,0);
FEED_DOG ( );
}
return(0) ;
}
DATAW =~DATAW;
}
DATAW = 0x55;
}
// _NOP();
return(1);
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -