注:
#ifndef _eeprom_h_
#define _eeprom_h_
#include
#include
#define EEPROM_ADDRESS 0x57
sbit SDA = P1^2; //EEPROM的数据线
sbit SCL = P1^1; //EEPROM的时钟线
sbit WP = P1^0; //EEPROM的写保护,给低电平标明读写均答应,也便是规范的形式。
extern void EEPROM_Init();
extern unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_write_arr[],unsigned int len);
extern unsigned char read_eeprom_status(unsigned char c_slave_address7bit);
extern unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_read_arr[],unsigned int len);
extern unsigned char EEPROM_Read(unsigned char c_slave_address7bit,unsigned char c_reg_address);
extern unsigned char EEPROM_Write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data);
#endif
再个便是EEPROM.c文件的内容:
#include “eeprom.h”
#include
#include
#include “usart.h”
#define _Nop() _nop_() //界说空指令
static void EEPROM_Stop( void );
static void Delay_us(unsigned int i_delay_count)
{
int j = 0,i;
for(j = 0 ; j < 5; j ++)
for(i = 0 ; i < i_delay_count ; i ++)
;
}
/*******************************************************************************
* I2C电路:
* 单片机 EEPROM
* P10———>WP
* P11———>SCL
* P12———>SDA
*
* A0,A1,A2均经过硬件拉高电平
*
* 我这儿将EEPROM的地址依照如下方法规划:
* 0101 0(A2)(A1)(A0)
* 因而EEPROM的地址为0x57.
*
* copyright by wit_yuan 2016-09-15 at 龙兴园北区
——————————————————————————-*/
void EEPROM_Init()
{
//将WP设置为低电平即可
WP = 0;
//将IIC总线置高即可
SCL = 1;
SDA = 1;
}
/*
*
* EEPROM_Start():
* 内部函数
*
*/
static void EEPROM_Start()
{
SDA=1; //因为上一个SCL状况是0或者是1,要让SDA安稳输出,都能够设置为1
Delay_us(2);
SCL=1; //让SCL发生改变,为0不变,为1则改变,标明数据能够变动了。
Delay_us(2);
SDA=0; //SDA线数据改变,然后能够确保宣布的是start信号。
Delay_us(2);
SCL=0; //将I2C总线钳住,下一个时间SDA能够输出凹凸电平。
Delay_us(4);
}
/*
*
* EEPROM_Send_Byte():
* 内部函数
*
*/
static void EEPROM_Send_Byte( unsigned char txd)
{
unsigned char t;
// SDA_OUT();
SCL=0;//拉低时钟开端数据传输
Delay_us(2);
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
SDA=1;
else
SDA=0;
txd<<=1;
Delay_us(2);
SCL=1;
Delay_us(2);
SCL=0;
Delay_us(2);
}
}
/*
*
* EEPROM_Read_Byte():
* 内部函数
*
*/
static unsigned char EEPROM_Read_Byte()
{
unsigned char i,u_receive=0;
// SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL=0;
Delay_us(4);
SCL=1;
Delay_us(1);
u_receive<<=1;
if(SDA)
u_receive++;
}
return u_receive;
}
/*
*
* EEPROM_Ack():
* 内部函数
* 2016-09-16 edited for 8051. by wit_yuan
*/
static void EEPROM_Ack()
{
SCL=0;
Delay_us(2);
//////add 2016-09-16 by wit_yuan///////////
SDA = 1;
Delay_us(1);
SDA=0;
Delay_us(1);
SCL=1;
Delay_us(1);
SCL=0;
Delay_us(4);
//////add 2016-09-16 by wit_yuan///////////
SDA = 1;
Delay_us(1);
}
/*
*
* EEPROM_Wait_Ack():
* 内部函数
*
*/
static unsigned char EEPROM_Wait_Ack()
{
unsigned char ucErrTime=0;
SCL=0;
Delay_us(1);
while(SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
EEPROM_Stop();
return 1; //超时,标明数据传输有问题
}
}
SCL=1;
Delay_us(1);
SCL=0;//时钟输出0
Delay_us(2);
return 0;
}
/*
*
* EEPROM_No_Ack():
* 内部函数
*
*/
static void EEPROM_No_Ack()
{
SCL=0;
Delay_us(2);
SDA=1;
Delay_us(1);
SCL=1;
Delay_us(1);
SCL=0;
Delay_us(4);
}
/*
*
* EEPROM_Stop():
* 内部函数
*
*/
static void EEPROM_Stop()
{
SDA=0; //上一个状况的SCL=0,这个状况设置SDA=0,意图是让状况能回转
Delay_us(2);
SCL=1; //该时间设置SCL=1,然后就能够让数据安稳在改状况下。
Delay_us(2);
SDA=1;
Delay_us(4);
}
unsigned char EEPROM_Write(unsigned char c_slave_address7bit,unsigned char c_reg_address,unsigned char u_data)
{
unsigned char u_wait_err = 0;
EEPROM_Start();
EEPROM_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Send_Byte(c_reg_address);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Send_Byte(u_data);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Stop();
if( u_wait_err == 0)
return 0;
return 1;
}
unsigned char EEPROM_Read(unsigned char c_slave_address7bit,unsigned char c_reg_address)
{
unsigned char u_temp;
unsigned char u_wait_err = 0;
EEPROM_Start();
EEPROM_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Send_Byte(c_reg_address);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Start();
EEPROM_Send_Byte((c_slave_address7bit << 1)+1);
u_wait_err |= EEPROM_Wait_Ack();
u_temp = EEPROM_Read_Byte( );
EEPROM_No_Ack();//不需要呼应
EEPROM_Stop();
return u_temp;
}
unsigned char eeprom_continue_read(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_read_arr[],unsigned int len)
{
unsigned char u_wait_err = 0;
int i = 0;
EEPROM_Start();
EEPROM_Send_Byte(c_slave_address7bit << 1);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Send_Byte(c_reg_address);
u_wait_err |= EEPROM_Wait_Ack();
EEPROM_Start();
EEPROM_Send_Byte((c_slave_address7bit << 1)+1);
u_wait_err |= EEPROM_Wait_Ack();
for(i = 0 ; i < len - 1 ; i ++)
{
c_continue_read_arr[i] = EEPROM_Read_Byte( );
EEPROM_Ack();
}
c_continue_read_arr[len-1] = EEPROM_Read_Byte( );
//u_wait_err |= EEPROM_Wait_Ack();
EEPROM_No_Ack();//不需要呼应
EEPROM_Stop();
if(u_wait_err == 0)
return 0;
return 1;
}
unsigned char eeprom_continue_write(unsigned char c_slave_address7bit,unsigned char c_reg_address,
unsigned char c_continue_write_arr[],unsigned int len)
{
unsigned int i;
unsigned int i_err = 0;
EEPROM_Start();
EEPROM_Send_Byte(c_slave_address7bit << 1);
i_err |= EEPROM_Wait_Ack();
EEPROM_Send_Byte(c_reg_address);
i_err |= EEPROM_Wait_Ack();
for( i = 0 ; i < len ; i ++ )
{
EEPROM_Send_Byte(c_continue_write_arr[i]);
i_err |= EEPROM_Wait_Ack();
}
EEPROM_Stop();
if(i_err == 0)
return 0;
return 1;
}
unsigned char read_eeprom_status(unsigned char c_slave_address7bit)
{
unsigned int i = 0;
int i_ret = 0;
do
{
EEPROM_Start();
EEPROM_Send_Byte(c_slave_address7bit << 1);
i_ret = EEPROM_Wait_Ack();
i ++;
if(i >= 10000)
{
EEPROM_Stop();
return 1;//标明无呼应
}
}while(i_ret);
EEPROM_Stop();
return 0;//标明操作序列完毕
}
#ifndef _usart_h_
#define _usart_h_
#include
#include
extern void UART_Init(void);
extern void Send_String(unsigned char *u_string);
extern void Send_UHex(unsigned char u_tx);
#endif
然后是usart.c文件的内容:
#include “usart.h”
/*————————————————
串口通讯初始化
————————————————*/
void UART_Init(void)
{
SCON = 0x50; // SCON: 形式 1, 8-bit UART, 使能接纳
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TR1 = 1; // TR1: timer 1 翻开
TI = 1;
}
/*
* Send_UChar:
* 发送单个字符
*
*
*/
void Send_UChar(unsigned char u_tx)
{
SBUF = u_tx;
while(!TI);
TI = 0;
}
/*
* Send_String:
* 发送字符串
*
*
*/
void Send_String(unsigned char *u_string)
{
while(*u_string)
{
Send_UChar(*u_string);
u_string++;
}
}
void Send_UHex(unsigned char u_tx)
{
unsigned char u_high;
unsigned char u_low;
u_high = u_tx/16 ;
u_low = u_tx%16 ;
if((u_high >= 10) && (u_high <= 15))
{
u_high = (u_high – 10) + A;
}
else
{
u_high = u_high + 0;
}
if((u_low >= 10) && (u_low <= 15))
{
u_low = (u_low – 10) + A;
}
else
{
u_low = u_low + 0;
}
Send_UChar(u_high);
Send_UChar(u_low);
Send_UChar( );
}
/*——————————————————————————-
* 称号:51单片机操控EEPROM
* 晶振运用11.0592M
*
* I2C电路:
* 单片机 EEPROM
* P10———>WP
* P11———>SCL
* P12———>SDA
*
* A0,A1,A2均经过硬件拉高电平
*
* copyright by wit_yuan 2016-09-15 at 龙兴园北区
——————————————————————————-*/
#include
#include
#include
#include “usart.h”
unsigned char g_c_continue_write[16];
unsigned char g_c_continue_read_array[16];
/*————————————————
主函数
————————————————*/
void main (void)
{
unsigned char value,i;
UART_Init();
EEPROM_Init();
Send_String(“——————–app run—————–\n”);
#if 0
EEPROM_Write(EEPROM_ADDRESS,0,0×02);
for(i = 0 ; i < 100 ; i ++);
for(i = 0 ; i < 100 ; i ++);
for(i = 0 ; i < 100 ; i ++);
value = EEPROM_Read(EEPROM_ADDRESS,0);
Send_String(“\n value :”);
Send_UHex(value);
Send_String(“\n “);
#else
#if 1
Send_String(“array :\n”);
for(i = 0 ; i < 16 ; i ++)
{
g_c_continue_write[i] = i + 1;
Send_UHex(g_c_continue_write[i]);
}
Send_String(“\n”);
Send_String(“write array : \n”);
value = eeprom_continue_write(EEPROM_ADDRESS,0,g_c_continue_write,16);
Send_String(“read write status : \n”);
#if 1
value = read_eeprom_status(EEPROM_ADDRESS);
Send_String(“\n status :”);
Send_UHex(value);
Send_String(“\n “);
#endif
#endif
#if 1
Send_String(“read array : \n”);
eeprom_continue_read(EEPROM_ADDRESS,0,g_c_continue_read_array,16);
Send_String(“read:\n”);
for(i = 0 ; i < 16 ; i ++)
{
Send_UHex(g_c_continue_read_array[i]);
}
Send_String(“\n”);
value = EEPROM_Read(EEPROM_ADDRESS,0x0D);
Send_String(“\n value :”);
Send_UHex(value);
Send_String(“\n “);
#endif
#endif
Send_String(“\n ———-app end—————-\n”);
while (1) //主循环
{
}
}