-- 24C02的字节读写程序(带显示)
;***********************************************************************
;** 硕恒电子 **
;** www.shdz.com **
;** **
;******************51实验板例程序---24c02读写程序****************
ORG 0000H
a_bit equ 20h ;数码管个位数存放内存位置
b_bit equ 21h ;数码管十位数存放内存位置
SCL BIT P3.4 ;定义24C02的串行时钟线
SDA BIT P3.5 ;定义24C02的串行数据线
WRADR EQU 10100000B ;写指令代码
READR EQU 10100001B ;读指令代码
BYTE_ADDR EQU 30H ;数据地址(24C02)
BYTE_DAT EQU 31H ;待写数据
DATAOUT EQU 32H ;读出的数据
LJMP START
ORG 0100H
START:
MOV BYTE_ADDR,#00H ;存放地址为00
MOV BYTE_DAT,#31 ;入例数据31
LCALL BYTE_WR
LCALL SELECT_RD
DISE: LCALL DISPLAY
AJMP DISE
BYTE_WR:
ACALL START_BIT ;送起始位
MOV A,#WRADR ;写指令代码
ACALL SHIFT8
ACALL SLAVE_ACK ;送从应答
MOV A,BYTE_ADDR ;字节地址
ACALL SHIFT8
ACALL SLAVE_ACK
RE1: MOV A,BYTE_DAT ;字节数据
ACALL SHIFT8
ACALL SLAVE_ACK
JC RE1
ACALL STOP_BIT ;停止位
ACALL ACK_POL ;调应答检测等写周期结束
RET
;**************************************
;应答检测
;**************************************
ACK_POL:
MOV R3,#40H ;限制最大时间
ACK_LOOP:
DJNZ R3,DONE_YET
SJMP DN_ACKPOL
DONE_YET:
ACALL START_BIT
MOV A,#WRADR
ACALL SHIFT8
ACALL SLAVE_ACK
JC ACK_LOOP ;无应答循环
DN_ACKPOL:
ACALL STOP_BIT
RET
;*****************************************
;起始位
;*****************************************
START_BIT:
SETB SDA
NOP
SETB SCL
NOP
CLR SDA
NOP
CLR SCL
RET
;******************************************
;停止位
;******************************************
STOP_BIT: CLR SDA
NOP
SETB SCL
NOP
SETB SDA
CLR SCL
RET
;读、写数据
SHIFT8: MOV R7,#8
SH01: RLC A
MOV SDA,C
SETB SCL
CLR SCL
DJNZ R7,SH01
RET
SLAVE_ACK:
NOP
NOP
CLR SCL
NOP
SETB SDA
NOP
NOP
SETB SCL
NOP
NOP
MOV C,SDA ;保存应答位接收成功C为0
CLR SCL
RET
;*********************************************
;无需应答
;********************************************
NO_ACK: SETB SDA
NOP
SETB SCL
NOP
CLR SCL
RET
;*********************************************
;读任意地址
;*********************************************
SELECT_RD:
ACALL START_BIT ;送起始位
MOV A,#WRADR ;位从地址
ACALL SHIFT8
ACALL SLAVE_ACK ;送从应答
MOV A,BYTE_ADDR ;字节地址
ACALL SHIFT8
ACALL SLAVE_ACK
ACALL START_BIT ;新起始位
MOV A,#READR
ACALL SHIFT8
ACALL SLAVE_ACK
MOV R7,#8
CLOCK8: SETB SCL
NOP
MOV C,SDA
CLR SCL
MOV A,DATAOUT
RLC A
MOV DATAOUT,A
DJNZ R7,CLOCK8 ;读八位数据存DATAOUT 中
ACALL NO_ACK
ACALL STOP_BIT
RET
DISPLAY:
AB1: MOV R3,#50
TIME1: MOV A,DATAOUT ;将DATAOUT中的十六进制数转换成10进制
MOV B,#100 ;10进制/10=10进制
DIV AB
CJNE A,#1,NE1
MOV P1,#0FEH
AJMP WW
NE1: CJNE A,#2,EQ0
MOV P1,#0FCH
AJMP WW
EQ0: MOV P1,#0FFH
WW: MOV A,B
MOV B,#10
DIV AB
MOV B_BIT,A ;十位在a
MOV A_BIT,B ;个位在b
MOV DPTR,#NUMTAB ;指定查表启始地址
MOV R0,#4
DPl1: MOV R1,#250 ;
DPLOP: MOV A,A_BIT ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P0,A ;送出个位的7段代码
CLR P2.7 ;开个位显示
ACALL DELY1 ;显示1毫秒
SETB P2.7 ;关闭个位显示,防止鬼影
MOV A,B_BIT ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P0,A ;送出十位的7段代码
CLR P2.6 ;开十位显示
ACALL DELY1 ;显示1毫秒
SETB P2.6 ;关闭十位显示,防止鬼影
M33: DJNZ R3,TIME1 ;2毫秒循环执行250次,时间约0.5秒
RET
DELY1: MOV R4,#2 ;1毫秒延时子程序
D11: MOV R5,#248
DJNZ R5,$
DJNZ R4,D11
RET
DELAY10:MOV R4,#20 ;10毫秒延时子程序
D12: MOV R5,#248
DJNZ R5,$
DJNZ R4,D12
RET
;实验板上的7段数码管0~9数字的共阴显示代码
NUMTAB:DB 0CFH,03H,5DH,5BH,93H,0DAH,0DEH,43H,0DFH,0DBH
END
///////////////////////////////////////////////////
/*===========================/
24C01存储器I2C总线实验 C语言例子 (转载)
/ ============================
#include
#include
sbit SDA=0x90;
sbit SCL=0x91;
//函数声明
unsigned char i2c_read(unsigned char);
void i2c_write(unsigned char,unsigned char);
void i2c_send8bit(unsigned char);
unsigned char i2c_receive8bit(void);
void i2c_start(void);
void i2c_stop(void);
bit i2c_ack(void);
//=======================================================
void main(void)
{
unsigned char dd;
i2c_write(0x00,0x55);
_nop_();
dd=i2c_read(0x00);
for(;;)
{}
}
/*=======================================================
i2c_write(地址,数据),写一个字节
=======================================================*/
void i2c_write(unsigned char Address,unsigned char Data)
{
do{
i2c_start();
i2c_send8bit(0xA0);
}while(i2c_ack());
i2c_send8bit(Address);
i2c_ack();
i2c_send8bit(Data);
i2c_ack();
i2c_stop();
return;
}
/*=======================================================
i2c_read(地址,数据),写一个字节
=======================================================*/
unsigned char i2c_read(unsigned char Address)
{
unsigned char c;
do{
i2c_start();
i2c_send8bit(0xA0);
}while(i2c_ack()); //=1,表示无确认,再次发送
i2c_send8bit(Address);
i2c_ack();
do{
i2c_start();
i2c_send8bit(0xA1);
}while(i2c_ack());
c=i2c_receive8bit();
i2c_ack();
i2c_stop();
return(c);
}
//=======================================================
//发送开始信号
void i2c_start(void)
{
SDA = 1;
SCL = 1;
SDA = 0;
SCL = 0;
return;
}
//发送结束信号
void i2c_stop(void)
{
SDA = 0;
SCL = 1;
SDA = 1;
return;
}
//发送接收确认信号
bit i2c_ack(void)
{
bit ack;
SDA = 1;
SCL = 1;
if (SDA==1)
ack = 1;
else
ack = 0;
SCL = 0;
return (ack);
}
//送八位数据
void i2c_send8bit(unsigned char b)
{
unsigned char a;
for(a=0;a<8;a++)
{
if ((b<
SDA = 1;
else
SDA = 0;
SCL = 1;
SCL = 0;
}
return;
}
//接收八位数据
unsigned char i2c_receive8bit(void)
{
unsigned char a;
unsigned char b=0;
for(a=0;a<8;a++)
{
SCL = 1;
b=b<<1;
if (SDA==1)
b=b|0x01; //按位或
SCL = 0;
}
return (b);
}