汇编源码是:
;WRS是写入程序
;将(R1)指示的(R7)个片内字节写入EEPROM中写入首址由(R0)指示
;(R7) <=8时比较保险
WR_SPROM: LCALL STAT_SPROM ;发出起始信号
MOV A, #0A0H ;发出写命令(10100000)
LCALL OUTB_SPROM
JC WBE ;无回答,结束操作
MOV A, R2 ;发出EEPROM首址
LCALL OUTB_SPROM
JC WBE ;无回答,结束操作
MOV A, R1 ;发出EEPROM首址
LCALL OUTB_SPROM
JC WBE ;无回答,结束操作
WR1: MOV A, @R0 ;取一字节内容
LCALL OUTB_SPROM ;写入EEPROM中
JC WBE ;无回答,结束操作
INC R0 ;指向下一字节
DJNZ R7, WR1 ;写完全部字节
WBE: LJMP STOP_SPROM ;发出结束信号
;
CLR_AT24CXX: LCALL STAT_SPROM ;发出起始信号
MOV A, #0A0H ;发出写命令
LCALL OUTB_SPROM
JC CLR_WBE ;无回答,结束操作
MOV A, R2 ;发出EEPROM首址
LCALL OUTB_SPROM
JC CLR_WBE ;无回答,结束操作
MOV A, R1 ;发出EEPROM首址
LCALL OUTB_SPROM
JC CLR_WBE ;无回答,结束操作
MOV R7, #16
CLR_WR1: MOV A, #0FFH ;取一字节内容
LCALL OUTB_SPROM ;写入EEPROM中
JC CLR_WBE ;无回答,结束操作
DJNZ R7, CLR_WR1 ;写完全部字节
CLR_WBE: LJMP STOP_SPROM ;发出结束信号
;
;RDS是读出程序
;将(R1)指示的(R7)个EEPROM字节读入片内RAM中首址由(R0)指示
;(R7) <=20时比较保险
RD_SPROM: LCALL STAT_SPROM ;发出起始信号
MOV A, #0A0H ;发出写命令
LCALL OUTB_SPROM
JC RDE ;无回答,结束操作
MOV A, R2 ;发出EEPROM首址(high_byte)
LCALL OUTB_SPROM
JC RDE ;无回答,结束操作
MOV A, R1 ;发出EEPROM首址(low_byte)
LCALL OUTB_SPROM
JC RDE ;无回答,结束操作
LCALL STOP_SPROM ;发出结束信号
DB 0,0
LCALL STAT_SPROM ;再次发出起始信号
MOV A, #0A1H ;发出读命令
LCALL OUTB_SPROM
JC RDE ;无回答,结束操作
RD1: MOV B, #8 ;每移出8位组成一字节
RD2: CLR SCL ;输出一个时钟脉冲
CLR SCL
DB 0,0
;DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
SETB SCL
SETB SCL
DB 0,0
;DB 0,0,0,0;,0,0,0,0,0;,0,0,0,0,0,0,0
MOV C, SDA ;读入一位
RLC A ;拼装到累加器中
DB 0,0
DJNZ B, RD2 ;拼完一字节
MOV @R0, A ;存入片内
INC R0 ;调整片内地址
CLR SCL ;时钟脉冲拉低
CJNE R7, #1, RD3 ;是最后一字节吗?
SETB SDA ;最后一字节不给回答信号
SETB SDA
SJMP RD4
RD3: CLR SDA ;准备好回答信号
CLR SDA
RD4: DB 0,0
SETB SCL ;时钟脉冲上升沿
SETB SCL
DB 0,0,0 ;等待EEPROM读取回答信号
DB 0,0,0
CLR SCL ;回答完毕
CLR SCL
SETB SDA ;准备读入下一字节
SETB SDA
DJNZ R7, RD1 ;直到读完全部字节
CLR C
RDE: LJMP STOP_SPROM ;发出结束信号
;OUTB是向EEPROM发出一字节信息的子程序
OUTB_SPROM: MOV B, #8 ;一字节包含8位
OUT1: CLR SCL ;将时钟线拉低
CLR SCL
RLC A ;移出一位
MOV SDA, C ;放到数据线上
SETB SCL ;将时钟线升高
SETB SCL
DB 0,0 ;等到一位信息送入EEPROM中
DB 0,0
DJNZ B, OUT1 ;发送完8位
CLR SCL ;将时钟线拉低
CLR SCL
SETB SDA ;准备接受回答信号
SETB SDA
SETB SCL ;将时钟线升高
SETB SCL
DB 0,0
MOV C, SDA ;接受回答信号
CLR SCL ;将时钟线拉低
CLR SCL
RET ;回答信号在进位标志中
;STAT是起始信号
STAT_SPROM: SETB SDA ;将数据线升高
SETB SDA
SETB SCL ;将时钟线升高
SETB SCL
DB 0,0 ;延时
DB 0,0
CLR SDA ;将数据线拉低,发出起始信号
CLR SDA
DB 0,0
DB 0,0
CLR SCL ;将时钟线拉低
CLR SCL
RET
;STOP是结束信号
STOP_SPROM: CLR SCL ;将时钟线拉低
CLR SCL
CLR SDA ;将数据线拉低
CLR SDA
DB 0,0
SETB SCL ;将数据线升高
SETB SCL
DB 0,0
DB 0,0
SETB SDA ;将数据线升高,发出结束信号
SETB SDA
RET
SPROM_DELAY: PUSH 03H
PUSH 04H
MOV R3, #30 ;延时,等待写入操作结束
MOV R4, #0
TTT: DJNZ R4, TTT
DJNZ R3, TTT
POP 04H
POP 03H
RET
WR_10_PARA_SPROM:
MOV A, DOPROG
MOV B,#10H
MUL AB
ADD A,#10H
PUSH ACC
MOV A,B
ADDC A,#00H
PUSH ACC
MOV R0, #PARA
POP ACC
MOV R2,A
POP ACC
MOV R1,A
MOV R7,#9
LCALL WR_SPROM
LCALL SPROM_DELAY ;延时,等待写入操作结束
MOV R0, #DOPROG
MOV R1, #01H
MOV R2, #00H
MOV R7, #01H
LCALL WR_SPROM
LCALL SPROM_DELAY ;延时,等待写入操作结束
RET
WR_5LOC_PARA_SPROM:
MOV R0, #HEADLEFTLOCATION
MOV R1, #08H
MOV R2, #00H
MOV R7, #5
LCALL WR_SPROM
LCALL SPROM_DELAY ;延时,等待写入操作结束
RET
WR_HLEFTLOC: MOV R0, #HEADLEFTLOCATION
MOV R1, #08H
MOV R2, #00H
MOV R7, #01H
LCALL WR_SPROM
LCALL SPROM_DELAY ;延时,等待写入操作结束
RET
RD_10_PARA_SPROM:
MOV A,DOPROG
MOV B,#10H
MUL AB
ADD A,#10H
PUSH ACC
MOV A,B
ADDC A,#00H
MOV R2,A
POP 01H
MOV R0, #PARA
MOV R7,#9
LCALL RD_SPROM
LCALL SPROM_DELAY
RET
RD_5LOC_PARA_SPROM:
MOV R0, #HEADLEFTLOCATION
MOV R1, #08H
MOV R2, #00H
MOV R7, #5
LCALL RD_SPROM
LCALL SPROM_DELAY ;延时,等待写入操作结束
RET
我现在改写的是:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define OP_WRITE 0xa0 // 器件地址以及写入操作
#define OP_READ 0xa1 // 器件地址以及读取操作
sbit SDA = P3^5;
sbit SCL = P3^4;
uchar data Acc_data,B_data,temp_data_time7,temp_data_time6,temp_data_time1,temp_data_time0;
uchar data temp_data_time5,temp_data_time4,temp_data_time3,temp_data_time2;
uchar data DOPROG,PARA,HEADLEFTLOCATION;
uchar temp,temp1;
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/**********************************************************
开始位
**********************************************************/
void start()
{
SDA = 1;
SCL = 1;
delayNOP();
SDA = 0;
delayNOP();
SCL = 0;
}
/**********************************************************
停止位
**********************************************************/
void stop()
{
SDA = 0;
delayNOP();
SCL = 1;
delayNOP();
SDA = 1;
}
/**********************************************************
从AT24C02移出数据到MCU
**********************************************************/
uchar shin()
{
uchar i,read_data;
for(i = 0; i < 8; i++)
{
SCL = 1;
read_data < <= 1;
// read_data |= (uchar)SDA;
read_data |= SDA;
SCL = 0;
}
return(read_data);
}
/**********************************************************
从MCU移出数据到AT24C02
**********************************************************/
bit shout(uchar write_data)
{
uchar i;
bit ack_bit;
for(i = 0; i < 8; i++) // 循环移入8个位
{
SDA = (bit)(write_data & 0x80);
_nop_();
SCL = 1;
delayNOP();
SCL = 0;
write_data < <= 1;
}
SDA = 1; // 读取应答
delayNOP();
SCL = 1;
delayNOP();
ack_bit = SDA;
SCL = 0;
return ack_bit; // 返回AT24C02应答位
}
/**********************************************************
在指定地址addr处写入数据write_data
**********************************************************/
void write_II2C_data(uchar addr, uchar write_data,uchar data_length)
{
uchar i;
start();
shout(OP_WRITE);
for(i=0;i <data_length;i++)
{
shout(addr);
shout(write_data);
stop();
addr++;
}
delayms(10); // 写入周期
}
/**********************************************************
在当前地址读取
**********************************************************/
uchar read_current()
{
uchar read_data;
start();
shout(OP_READ);
read_data = shin();
stop();
return read_data;
}
/**********************************************************
在指定地址读取
**********************************************************/
uchar read_II2C_data(uchar random_addr,uchar data_length)
{uchar read_data,i;
start();
shout(OP_WRITE);
for(i=0;i <data_length;i++)
{
shout(random_addr);
start();
shout(OP_READ);
read_data = shin();
random_addr++;
stop();
}
return read_data;
//return(read_current());
}
/********************************************************/
/*
/* 延时t毫秒
/* TIME_II2C_Delay
/*
/********************************************************/
void TIME_II2C_Delay(uint t)
{
uint k;
do
{
for(k=0; k <125; k++) {}
}
while(t--);
}
/*****************************************
WR_10_PARA_SPROM:
功能: 10个参数储入
创建: 2008年4月25日 创建人:
修改: 修改人
修改: 修改人:
*****************************************/
void WR_10_PARA_SPROM (void)
{
uchar temp;
temp=DOPROG;
temp_data_time0=PARA;
temp_data_time1=0X0000;
temp_data_time7=9;
write_II2C_data(temp_data_time1,temp_data_time0, temp_data_time7);
TIME_II2C_Delay(2);
temp_data_time0=DOPROG;
temp_data_time1=0X0001;
temp_data_time7=1;
write_II2C_data(temp_data_time1,temp_data_time0, temp_data_time7);
TIME_II2C_Delay(2);
}
/*****************************************
WR_5LOC_PARA_SPROM:
功能: 五个位置参数
创建: 2008年4月25日 创建人:
修改: 修改人
修改: 修改人:
*****************************************/
void WR_5LOC_PARA_SPROM(void)
{
temp_data_time0=HEADLEFTLOCATION;
temp_data_time1=0X0008;
temp_data_time7=5;
write_II2C_data(temp_data_time1,temp_data_time0, temp_data_time7);
TIME_II2C_Delay(2);
}
/*****************************************
WR_HLEFTLOC:
功能: 五个位置参数
创建: 2008年4月25日 创建人:
修改: 修改人
修改: 修改人:
*****************************************/
void WR_HLEFTLOC(void)
{
temp_data_time0=HEADLEFTLOCATION;
temp_data_time1=0X0008;
temp_data_time7=1;
write_II2C_data(temp_data_time1,temp_data_time0, temp_data_time7);
TIME_II2C_Delay(2);
}
/*****************************************
RD_10_PARA_SPROM:
功能:
创建: 2008年4月25日 创建人:
修改: 修改人
修改: 修改人:
*****************************************/
void RD_10_PARA_SPROM(void)
{
temp_data_time0=PARA;
temp_data_time1=0X0001;
temp_data_time7=9;
read_II2C_data(temp_data_time1,temp_data_time7);
TIME_II2C_Delay(2);
}
/*****************************************
RD_5LOC_PARA_SPROM:
功能:
创建: 2008年4月25日 创建人:
修改: 修改人
修改: 修改人:
*****************************************/
void RD_5LOC_PARA_SPROM(void)
{
temp_data_time0=HEADLEFTLOCATION;
temp_data_time1=0X0008;
temp_data_time7=5;
read_II2C_data(temp_data_time1,temp_data_time7);
TIME_II2C_Delay(2);
}