⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 urmv37.asm

📁 软件 模拟IIC总线读写数据
💻 ASM
字号:
;使用AT89x51
;12M晶振

;单片机内存分配申明
;P1     EQU 90H
H_DATA EQU 30H ;测距数据高8位
L_DATA EQU 31H ;数据低8位
RW     EQU 32H ;IIC第9位
ACK_F  EQU 33H ;ACK信号寄存
ADDR   EQU 34H ;读超声波数据指令
SDA    EQU 96H
SCL    EQU 97H 

;主程序
ORG 0000H
LCALL MIAN
ORG 0040H
MIAN:
        LCALL SERIAL;串口初始化
        LCALL IIC_START;调用IIC开始
        NOP
        MOV ADDR,#150;指定读超声波指令
        LCALL SEND_BYTE;发送指令
        NOP
        SETB RW;第9位置位
        LCALL SEND_BIT9RW;发送第9位
        NOP
        LCALL IIC_ACK;读ACK
        JNB ACK_F,DISPLAY;读ACK失败,不向下执行
        LCALL R_TOWBYTE;读16位数据

        CLR TI
        MOV A,H_DATA
        MOV SBUF,A; 高位通过串口发送出去

        JNB TI,$
        CLR TI
        MOV A,L_DATA
        MOV SBUF,A; 低位通过串口发送出去
        LJMP MIAN;

;IIC启动子程序
IIC_START:
          CLR SCL
          LCALL DELAY;调用56us延时
          SETB SDA
          LCALL DELAY
          SETB SCL
          LCALL DELAY
          CLR SDA
          LCALL DELAY
          CLR SCL
          RET

;发送1比特读超声波数据指令
SEND_BYTE:
          MOV A,ADDR;保存指令
          MOV R0,#1;8位数据
     SEND:
          CLR SCL
          LCALL DELAY
          MOV ADDR,A
          ANL A,#80H;第一位
          JZ CLR1
          SETB SDA;高电平送入SDA
          AJMP CHE
     CLR1:
          CLR SDA;低电平送入SDA
      CHE:
          MOV A,ADDR
          RL A   ;A寄存左移一位
          LCALL DELAY
          SETB SCL
          LCALL DELAY
          DJNZ R0,SEND;R0-1不为0跳转
          CLR SCL
          RET

;发送第9位RW
SEND_BIT9RW:
            MOV C,RW;保存RW
            CLR SCL
            LCALL DELAY
            JC RWA;A不为0跳转,SDA=1否则=0
            CLR SDA
            AJMP RWB
        RWA:
            SETB SDA
        RWB:
            LCALL DELAY
            SETB SCL
            LCALL DELAY
            CLR SCL
            SETB SDA
            LCALL DELAY
            SETB SCL
            RET

;读取ACK应答信号
IIC_ACK:
        CLR TR0;关定时器
        CLR TF0;中断溢出
        MOV TL0,#0FFH;设初值
        MOV TH0,#0FEH
        SETB TR0;开定时器
    DDA:
        MOV C,SDA;读ACK
        JNC DDB;SDA=0跳转
        JNB TF0,DDA;未溢出(TF0=0)跳转,溢出超时继续执行
        CLR ACK_F;读ACK失败
	AJMP MIAN;从头开始
    DDB:
        CLR TR0;关定时器
        CLR TF0;中断溢出
        MOV TL0,#0FFH;设初值
        MOV TH0,#0FEH
        SETB TR0;开定时器
    DDC:
        MOV C,SDA;读ACK
        JC DDD;SDA=1跳转
        JNB TF0,DDC;未溢出(TF0=0)跳转,溢出超时继续执行
        CLR ACK_F;读ACK失败
	AJMP MIAN;从头开始
    DDD:
        LCALL DELAY
        SETB ACK_F;读ACK成功
        RET

;接收16位超声波数据
R_TOWBYTE:
          MOV R2,#2;读高低2次
          MOV R1,#30H;高存入30,低存入31
      RTA:
          MOV R3,#8;读8位
      RTB:
          CLR C
          MOV C,SDA;数据存入c
          RRC A;带进位c循环右移一位
          LCALL DELAY
          CLR SCL
          LCALL DELAY
          DJNZ R3,RTB;R3-1不为0跳转
          MOV @R1,A;高8位存入30
          INC R1;地址转为31
          DJNZ R2,RTA;R1-1不为0跳转
          RET


;完成通讯初始化设置
SERIAL:
       MOV SCON,#50H;设置成串口1方式
       MOV TMOD,#20H;波特率发生器T1工作在模式2上
       MOV PCON,#80H;波特率翻倍为2400x2=4800BPS
       MOV TH1,#0F3H;预置初值(按照波特率2400BPS预置初值)
       MOV TL1,#0F3H;预置初值(按照波特率2400BPS预置初值)

       SETB TR1;启动定时器T1
       SETB ES;
       SETB EA;
       RET
       
       

;定时56us
DELAY:
      MOV R5,#1
 LOOP:
      NOP
      NOP
      DJNZ R5,LOOP
      RET


;TAB: DB 0C0H,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF,0xBF
END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -