赞助论坛
  • 5158阅读
  • 0回复

学习单片机之---51实验板例程序---24c02读写程序 [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-20 15:53:39 
;******************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);
}