tonyone 发表于 2013-10-3 11:52:26

请教汇编高人,这段PT2272 模拟解码器的程序要怎么玩得起...

; =========================================================================================
; =========================================================================================
;   PT2272 模拟解码器(接收来自射频解码模块的2262格式串行数据流)
;   管理三位数码管显示器
;   利用AT24C32实现堆栈式掉电缓存保护,通过特殊的清除发射器清除堆栈
;   显示器具有两级亮度变化
;   具有蜂鸣器,新的编码收到后,蜂鸣器鸣响2/3次,显示器高亮,三秒后正常
;
;   CPU: AT89C2051@12MHz
;
;                                COPYRIGHT yanggt@163.net SEP 9, 2004
; =========================================================================================
; =========================================================================================

EESIZE        EQU        16384                ;EEPROM容量(32768/16384/8192/4096/2048/1024/512);原值32768
PWDF        EQU        50H                        ;EEPROM中用于标识历史记录有效
MYA0_3        EQU        00000111B        ;有效识别码,不匹配则不响应;原值00010101
MYCLRL        EQU        00H                        ;主控手机编码值(目前为 0000H)
MYCLRH        EQU        00H                        ;根据A4-A11计算得到(00 D7 D6 D5 D4 D3 D2 D1)(D0)
BELONT        EQU        40                        ;声音鸣响时间
BELOFT        EQU        20                        ;静音时间


SCL        BIT        P3.1                        ;AT24C32(4K字节);原值P3.0
SDA        BIT        P3.0                        ;;原值P3.1

SIGPIN        BIT        P3.3                ;接收信号入口;原值P3.2

BELL        BIT        P3.7                ;蜂鸣器控制;原值P3.3

VSEL        BIT        P3.4                ;LED亮度选择,H=高亮度;原值P1.0


U0E        BIT        P2.5                        ;个位LED位选;原值P3.5
U1E        BIT        P2.4                        ;十位LED位选;原值P3.4
U2E        BIT        P2.3                        ;百位LED位选;原值P3.7

BELLSWBIT   78H                ;蜂鸣器运行期间=1
EEEMPTY BIT   79H                ;EEPROM空标志
BELLON        BIT        7AH                        ;通知蜂鸣器鸣响
CODEOK        BIT        7BH                        ;收到的编码正确
TMK250        BIT        7CH                        ;250us标志,每250us置位一次
SIGING        BIT        7DH                        ;手机发射信号正在持续=1,无信号=0
LEDHIGH BIT        7EH                        ;显示器亮度标志=0:正常;=1:高亮
TOUTMK        BIT        7FH                        ;显示器降低亮度时间已到=1

RBUF81        DATA        20H                        ;后8位第一次采样结果A4-A11
RBUF82        DATA        21H                        ;后8位第二次采样结果A4-A11
RBUF44        DATA        22H                        ;前4位第12次采样结果A0-A3

SIGPOT        DATA        23H                        ;接收引脚上次电平,直接保存P3口全部内容
SIGMSK        EQU                08H                        ;SIG----P3.3;原值P3.2,04H

TCNTL        DATA        24H                        ;定时计数器(4ms时基)
TCNTH        DATA        25H

TMX16        DATA        26H                        ;16*250=4000us=4ms
BELLTM        DATA        27H                        ;鸣响时间

DBUF0        DATA        28H                        ;个位显示缓冲区
DBUF1        DATA        29H                        ;十位
DBUF2        DATA        2AH                        ;百位


EEPTRL        DATA        2BH                        ;EEPROM当前位置指针
EEPTRH        DATA        2CH
EEPOL        DATA        2DH                        ;保存清除指针
EEPOH        DATA        2EH                        ;

RES2F        DATA        2FH                        ;使用其中的标志位

EEBUF        DATA        30H                        ;30-37H, I2C缓冲区

BELLCNT        DATA        38H                        ;鸣响次数计数器(3/2/1)
BELLTMK        DATA        39H

CODEL        DATA        40H                        ;接收到编码低位
CODEH        DATA        41H                        ;高位
CODELKDATA    42H         ;保存上一个编码
CODEHKDATA    43H         ;
CODE1L        DATA        44H
CODE1H        DATA        45H

; =========================================================================================

; =========================================================================================
        ORG        0000H
        LJMP        START

; =========================================================================================
;   250us进入一次,每16次(4ms)切换一次显示位
; =========================================================================================
        ORG        000BH                        ;定时器0中断入口,独占 R7
TM0SUB: SETB        TMK250
TM0_4MS:DJNZ        TMX16, TM0_E
        MOV        TMX16, #10H

        JNB        BELLSW, TM0_CLY
        DJNZ        BELLTM, TM0_CLY
        SETB        BELLON

TM0_CLY:JB        TOUTMK, TM0_0                ;每4ms执行一次
        DJNZ        TCNTL, TM0_0
        DJNZ        TCNTH, TM0_0
        SETB        TOUTMK

TM0_0:        CJNE        R7, #0, TM0_1                ;当前显示位
        CLR        U2E
        MOV        P0, DBUF0
        INC        R7
        SETB        U0E
        RETI

TM0_1:        CJNE        R7, #1, TM0_2
        CLR        U0E
        MOV        P0, DBUF1
        INC        R7
        SETB        U1E
        RETI

TM0_2:        CLR        U1E
        MOV        P0, DBUF2
        MOV        R7, #0
        SETB        U2E
        RETI
TM0_E:        RETI


; =========================================================================================

; =========================================================================================
START:        MOV        P0, #0FFH                ;关闭显示器,正常亮度
CLR P2.0
CLR P2.1
CLR P2.2
        CLR        BELLON
      CLR   BELL

        ACALL        EECHK                        ;检查EEPROM,确定指针,提取其中最后一个历史记录号码
        ACALL        TOBUF

        MOV        TMX16, #10H                ;中断计数寄存器置初始值16
        SETB        TOUTMK                        ;延迟定时器处于停止状态
        CLR        U0E
        CLR        U1E
        CLR        U2E
        MOV        R7, #00H                ;从第一位开始显示

        MOV        TMOD, #12H                ;TIMER0, MODE 2, TIMER1, MODE 1
        MOV        TL0, #06H
        MOV        TH0, #06H                ;时间=250us
        SETB        TR0
        SETB        ET0
        SETB        EA

        MOV        A, #6-1                 ;开机时蜂鸣器自动鸣响
        ACALL        BELL_S
        MOV        BELLTM, #BELONT-20

        ACALL        LEDOFF
        CLR        LEDHIGH                 ;关闭高亮度
        MOV        SIGPOT, #00H                ;假设开始时接收引脚=0
        CLR        SIGING
        SETB        F0
;=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
MAIN:   JNB   BELLSW, MAIN_S0
      ACALL        BELL_M

MAIN_S0:JNB        LEDHIGH, MAIN_00         ;显示器普通亮度,不检查标志
        JNB        TOUTMK, MAIN_0
        ACALL        LEDOFF                        ;显示器回到正常亮度
        CLR        LEDHIGH
        JB        EEEMPTY, MAIN_0                ;没有尚未确认的编码
        AJMP        MAIN_01

MAIN_00:JB        EEEMPTY, MAIN_0                ;没有尚未确认的编码
      JNB        TOUTMK, MAIN_0
      MOV   A, #2-1
        ACALL        BELL_S                        ;鸣响
MAIN_01:MOV        TCNTL, #LOW(5000/4)        ;高亮度持续3000ms=3s后恢复
        MOV        TCNTH, #HIGH(5000/4)
        CLR        TOUTMK
        MOV        BELLTM, #30

MAIN_0: MOV        A, P3                        ;监视SIG引脚电平变化
        XCH        A, SIGPOT
        XRL        A, SIGPOT
        ANL        A, #SIGMSK
        JZ        MAIN                        ;A=0表示引脚电平无变化

        SETB        F0
        ACALL        GETCOD                        ;开始接收,出错后直接返回
        JC        MAIN                        ;接收代码无效,舍弃。
        ACALL        FIND
        JC        MAIN                        ;C=1,表示代码无效,什么也不发生
        MOV        CODE1L, CODEL
        MOV        CODE1H, CODEH

        CLR        F0
        ACALL        GETCOD                        ;开始接收,出错后直接返回
        SETB        F0
        JC        MAIN                        ;接收代码无效,舍弃。
        ACALL        FIND
        JC        MAIN                        ;C=1,表示代码无效,什么也不发生
        MOV        B, A
        MOV        A, CODE1L
        XRL        A, CODEL
        JNZ        MAIN_0D
        MOV        A, CODE1H
        XRL        A, CODEH
        JZ        MAIN_0C

MAIN_0D:MOV        CODE1L, CODEL
        MOV        CODE1H, CODEH
        CLR        F0
        ACALL        GETCOD                        ;开始接收,出错后直接返回
        SETB        F0
        JC        MAIN                        ;接收代码无效,舍弃。
        ACALL        FIND
        JC        MAIN                        ;C=1,表示代码无效,什么也不发生
        MOV        B, A
        MOV        A, CODE1L
        XRL        A, CODEL
        JNZ        MAIN_E
        MOV        A, CODE1H
        XRL        A, CODEH
        JNZ        MAIN_E

MAIN_0C:MOV        A, B
        JNZ        MAIN_1                        ;A=1:主控手机,转去退栈
        MOV        BELLCNT, #4-1
      MOV   A, CODEL
      XRL   A, CODELK
      JNZ   MAIN_0A
      MOV   A, CODEH
      XRL   A, CODEHK
      JZ      MAIN_0B

;这里可以进行编码过滤=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

MAIN_0A:MOV        BELLCNT, #6-1
      ACALL        EEPUSH                        ;其他手机,转去保存、显示
        ACALL        TOBUF
MAIN_0B:SETB        TOUTMK
        MOV        TCNTL, #LOW(3000/4)        ;高亮度持续3000ms=3s后恢复
        MOV        TCNTH, #HIGH(3000/4)
        CLR        TOUTMK
        SETB        LEDHIGH                 ;显示器进入高亮状态
      MOV   A, BELLCNT
        ACALL        BELL_S                        ;鸣响
        MOV        BELLTM, #BELONT
        AJMP        MAIN

MAIN_1: MOV        A, CODEL                ;核对手机号码
        XRL        A, #MYCLRL
        JNZ        MAIN_E
        MOV        A, CODEH
        XRL        A, #MYCLRH
        JNZ        MAIN_E
        ACALL        EEPOP                        ;执行退栈操作

MAIN_E:        AJMP        MAIN


; =========================================================================================
;        主程序结束



; =========================================================================================
BELL_S: MOV   BELLCNT, A
      SETB        BELLSW
        CLR        BELL ;SETB
        RET


; =========================================================================================
BELL_M: JBC        BELLON, BELLM
        RET
BELLM:        MOV        A, BELLCNT
BELLM0:        JNB        ACC.0, BELLM1
        MOV        BELLTM, #BELOFT                ;A.0=1,正在鸣响,应该关闭
        CLR        BELL
        AJMP        BELLM9
BELLM1:        MOV        BELLTM, #BELONT                ;静音状态,应该打开
        SETB        BELL
BELLM9:        DJNZ        BELLCNT, BELLME
        CLR        BELLSW
        CLR        BELL
BELLME:        RET


; =========================================================================================
LEDOFF: ANL        DBUF0, #0FFH
        ANL        DBUF1, #0FFH
        ANL        DBUF2, #0FFH
        RET

; =========================================================================================

; =========================================================================================
TM1SET: CLR        TR1                        ;1,ACALL=2
        CLR        TF1                        ;1
        MOV        TL1, DPL                ;2
        MOV        TH1, DPH                ;2
        SETB        TR1                        ;1
        RET                                ;2, TOTAL=2+1+1+2+2+1+2=11us

; =========================================================================================
;接收代码,收到两个相同的编码即认可。
;发射结束后接收下一个。
; =========================================================================================
GETCOD: NOP

GETC_S: MOV        DPTR, #65535-50000        ;在50ms内搜索至少持续4ms的低电平        [***]
        ACALL        TM1SET
GETC_S0:MOV        R6, #16                 ;16*250us=4000us=4ms
GETC_S1:CLR        TMK250
GETC_S2:JB        TF1, GETC_E                ;这里超时认为目前无发射器工作,或上次发射已结束。
        JB        SIGPIN, GETC_S0
        JNB        TMK250, GETC_S2
        DJNZ        R6, GETC_S1

        MOV        R5, #4*2                ;首先接收A0-A3,共4位,8个采样点

        MOV        DPTR, #65535-8000        ;在接下来的8ms内必须出现上升沿                [***]
        ACALL        TM1SET
GETC_0: JB        TF1, GETC_E                ;这里超时认为目前无发射器工作,或上次发射已结束。
        JNB        SIGPIN, GETC_0
;        JB        SIGING, GETC_F                ;上次发射尚未结束,直接返回,不接收编码。
;        AJMP        GETC_20
        JNB        SIGING, GETC_20                ;上次发射尚未结束,直接返回,不接收编码。
        JNB        F0, GETC_20
        AJMP        GETC_F

GETC_1P:MOV        DPTR, #65535-1250+11+2        ;在接下来的1250us内必须出现低电平        [***]
        ACALL        TM1SET
GETC_1: JB        TF1, GETC_F                ;超时
        JB        SIGPIN, GETC_1

        MOV        DPTR, #65535-1250+11+2        ;在接下来的1250us内必须出现上升沿        [***]
        ACALL        TM1SET
GETC_2: JB        TF1, GETC_F                ;超时
        JNB        SIGPIN, GETC_2
GETC_20:MOV        DPTR, #65535-500+11+2        ;固定延迟500us后采样
        ACALL        TM1SET
        JNB        TF1, $

        MOV        C, SIGPIN                ;采样接收信号
        MOV        A, RBUF44
        RLC        A
        MOV        RBUF44, A

        DJNZ        R5, GETC_1P                ;循环接收4个数据位,进行8次采样


        MOV        R5, #8*2                ;接收A4-A11,共8个数据位,16个采样点
        MOV        R0, #RBUF81                ;RBUF81存放第一次采样值
GETC_3P:MOV        DPTR, #65535-1250+11+2        ;在接下来的1250us内必须出现低电平        [***]
        ACALL        TM1SET
GETC_3: JB        TF1, GETC_F                ;超时
        JB        SIGPIN, GETC_3

        MOV        DPTR, #65535-1250+11+2        ;在接下来的1250us内必须出现上升沿        [***]
        ACALL        TM1SET
GETC_4: JB        TF1, GETC_F                ;超时
        JNB        SIGPIN, GETC_4
GETC_40:MOV        DPTR, #65535-500+11+2        ;固定延迟500us后采样
        ACALL        TM1SET
        JNB        TF1, $

        MOV        C, SIGPIN                ;采样接收信号
        MOV        A, @R0
        RLC        A
        MOV        @R0, A
        XRL        00H, #RBUF81                ;在RBUF81和RBUF82之间切换
        XRL        00H, #RBUF82

        DJNZ        R5, GETC_3P                ;循环接收8个数据位,进行16次采样
        SETB        SIGING
        CLR        C
        RET

GETC_E: CLR        SIGING
GETC_F: SETB        C
        RET

; =========================================================================================

; =========================================================================================
FIND:        MOV        A, RBUF44                ;分析代码
        CJNE        A, #MYA0_3, FIND_E

        MOV        R4, RBUF81
        MOV        R5, RBUF82

        MOV        R6, #7
        MOV        R0, #00H
        MOV        R1, #00H
FIND_L: MOV        A, R0                        ;结果乘以 3
        CLR        C
        RLC        A
        MOV        B, A
        MOV        A, R1
        RLC        A
        XCH        A, B
        ADD        A, R0
        MOV        R0, A
        MOV        A, B
        ADDC        A, R1
        MOV        R1, A                        ;结果乘以 3 结束

        MOV        A, R4
        RLC        A
        MOV        R4, A                        ;D7-->C
        MOV        A, R5
        RL        A
        MOV        R5, A
        ANL        A, #01H                 ;D7-->A.0
        ADDC        A, R0                        ;A.0+C+R0
        MOV        R0, A
        MOV        A, R1
        ADDC        A, #00H
        MOV        R1, A
        DJNZ        R6, FIND_L                ;确定A4-A10的编码结果

        CLR        A
        MOV        C, RBUF81.0                ;分析代码,确定是否主控手机
        MOV        ACC.0, C
        MOV        C, RBUF82.0
        ADDC        A, #00H                 ;A=(0,1,2)。A=0:非主控手机;A=1:主控手机;A=2:无效手机
        JB        ACC.1, FIND_E                ;A=2!
      MOV        CODEL, R0
        MOV        CODEH, R1
        CLR        C
        RET                                ;A=0/1

FIND_E: SETB        C
        RET

; =========================================================================================

; =========================================================================================
EECHK:        MOV        EEPTRL, #00H                ;0000H记录不用,因为0000H用于判断EEPROM是否空
        MOV        EEPTRH, #00H
        MOV        EEBUF, #00H
        MOV        EEBUF+1, #00H

EECHK0:        MOV        CODEL, EEBUF                ;放到编码缓冲区
        MOV        CODEH, EEBUF+1
        ANL        CODEH, #0FH
        MOV        DPL, EEPTRL                ;读取栈底的两个字节
        MOV        DPH, EEPTRH
        INC        DPTR
        INC        DPTR                        ;指向下一个记录,但是暂时不修改指针
        MOV        A, DPH
        ADD        A, #HIGH(65536-EESIZE)        ;???
        JC        EECHK9                        ;已经检查完所有记录空间。
        MOV        EEPOL, DPL
        MOV        EEPOH, DPH                ;暂时保存在这里
        MOV        R0, #EEBUF
        MOV        B, #02H
        ACALL        I2CD_R
        MOV        A, EEBUF+1
        ANL        A, #0F0H
        XRL        A, #PWDF
        JNZ        EECHK9
        MOV        EEPTRL, EEPOL
        MOV        EEPTRH, EEPOH
        AJMP        EECHK0

EECHK9:        CLR        EEEMPTY                        ;假设非空
        MOV        A, EEPTRL
        ORL        A, EEPTRH
        JNZ        EECHKE
        SETB        EEEMPTY                        ;声明EEPROM空
EECHKE:        RET


; =========================================================================================

; =========================================================================================
EEPUSH: MOV        EEBUF, CODEL                ;写入EEPROM栈,采用实栈顶
        MOV        EEBUF+1, CODEH
        ORL        EEBUF+1, #PWDF                ;标志,50H
        MOV        DPL, EEPTRL
        MOV        DPH, EEPTRH
        INC        DPTR                        ;每个记录进入,指针加 2
        INC        DPTR
        MOV        A, DPH                        ;进行堆栈溢出检查
        ADD        A, #HIGH(65536-EESIZE)
        JC        EEPUSHE
        ANL        DPL, #0FEH
        MOV        EEPTRL, DPL
        MOV        EEPTRH, DPH
        MOV        R0, #EEBUF
        MOV        B, #02H
        ACALL        I2CD_W
        CLR        EEEMPTY                        ;声明EEPROM非空
EEPUSHE:RET


; =========================================================================================

; =========================================================================================
EEPOP:        MOV        A, EEPTRL                ;EEPROM退出操作
        ORL        A, EEPTRH
        JZ        EEPOPB

EEPOP0: MOV        EEPOL, EEPTRL
        MOV        EEPOH, EEPTRH

        CLR        C                        ;指针减 2,指向上一个数据
        MOV        A, EEPTRL
        SUBB        A, #02H
        MOV        EEPTRL, A
        MOV        A, EEPTRH
        SUBB        A, #00H
        MOV        EEPTRH, A                ;指针已经更新

        MOV        A, EEPTRL                ;检查退出一个记录后,堆栈是否变空?
        ORL        A, EEPTRH
        JNZ        EEPOP1
        MOV        CODEL, A
        MOV        CODEH, A
        SETB        EEEMPTY                        ;声明EEPROM空
        AJMP        EEPOP9

EEPOP1: MOV        DPL, EEPTRL                ;读取栈顶记录
        MOV        DPH, EEPTRH
        MOV        R0, #EEBUF
        MOV        B, #02H
        ACALL        I2CD_R
        MOV        CODEL, EEBUF                ;放到编码缓冲区
        MOV        CODEH, EEBUF+1
        ANL        CODEH, #0FH                ;屏蔽掉标志

EEPOP9: MOV        EEBUF, #00H                ;清除刚才已经退栈的记录
        MOV        EEBUF+1, #00H
        MOV        DPL, EEPOL
        MOV        DPH, EEPOH
        MOV        R0, #EEBUF
        MOV        B, #02H
        ACALL        I2CD_W

        ACALL        TOBUF                        ;送到显示缓冲区
        ACALL        LEDOFF
EEPOPB: MOV   A, #2-1
      ACALL        BELL_S                        ;鸣响
;        MOV        BELLTM, #30
EEPOPE: RET


; =========================================================================================

; =========================================================================================
TOBUF:        MOV        A, CODEL                ;填写显示缓冲区
        MOV        B, CODEH                ;/100
        MOV        R2, #00H
TOBUF_0:CLR        C
        SUBB        A, #100
        XCH        A, B
        SUBB        A, #00H
        XCH        A, B
        JC        TOBUF_8
        INC        R2
        AJMP        TOBUF_0
TOBUF_8:ADD        A, #100
        MOV        B, #10
        DIV        AB
        MOV        DPTR, #FONT
        MOVC        A, @A+DPTR
        MOV        DBUF1, A
        MOV        A, B
        MOVC        A, @A+DPTR
        MOV        DBUF0, A
        MOV        A, R2
        MOVC        A, @A+DPTR
        MOV        DBUF2, A
      MOV   CODELK, CODEL
      MOV   CODEHK, CODEH
        RET


; =========================================================================================

; =========================================================================================
DELAY:        PUSH        ACC                        ;延迟时间=A*10ms
        MOV        A, #20
DLY1:        PUSH        ACC
        MOV        A, #250
        DJNZ        ACC, $                        ;500us
        POP        ACC
        DJNZ        ACC, DLY1
        POP        ACC
        DJNZ        ACC, DELAY
        RET


;======= I2C 子程序        =================================================================
;        I2CD_W, I2CD_R                ;LAYER 1
;        I2C_O,        I2C_I                ;LAYER 2
;        I2C_BG, I2C_ED                ;LAYER 3
;========================================================================================
;        向存储器写入几个字节,最多8个字节。
;        入口:DPTR 要写的EEPROM存储单元地址。
;              R0   指向要写入字节在RAM的首地址。
;              B    写入字节个数。
;        出口:如果 C=1,说明写出错。

I2CD_W: ACALL        I2C_BG
        MOV        A, #10100000B        ;写命令
        ACALL        I2C_O
        JC        I2CD_WE         ;C=1, 未收到 ACK 位,出错,不再继续处理,直接返回

        MOV        A, DPH
        ACALL        I2C_O
        JC        I2CD_WE

        MOV        A, DPL
        ACALL        I2C_O
        JC        I2CD_WE

I2CD_WL:MOV        A, @R0
        ACALL        I2C_O
        JC        I2CD_WE
        INC        R0
        DJNZ        B, I2CD_WL

        ACALL        I2C_ED
        CLR        C
        RET
I2CD_WE:ACALL        I2C_ED
        SETB        C
        RET


; =========================================================================================
;        从 EEPROM 读入几个字节
;        入口:DPTR 要读的存储单元地址。
;              R0   指向要读缓冲区在RAM的首地址。
;              B    读入字节个数。
;        出口:读到的内容在缓冲区中,如果 C=1,说明读出错。
I2CD_R: ACALL        I2C_BG
        MOV        A, #10100000B        ;先发送[写]命令
        ACALL        I2C_O
        JC        I2CD_RE         ;C=1, 未收到 ACK 位,出错,不再继续处理,直接返回

        MOV        A, DPH                ;发送地址低位
        ACALL        I2C_O
        JC        I2CD_RE

        MOV        A, DPL                ;发送地址低位
        ACALL        I2C_O
        JC        I2CD_RE

        ACALL        I2C_BG
        MOV        A, #10100001B        ;发送读命令
        ACALL        I2C_O
        JC        I2CD_RE

I2CD_IB:MOV        DPL, #08H        ;取得一个字节
        SETB        SDA
I2CD_IL:SETB        SCL                ;SCL=1
        NOP
        MOV        C, SDA                ;MCU 采样 SDA,送到 C 中
        RLC        A                ;C->ACC.0
        CLR        SCL                ;SCL=0
        DJNZ        DPL, I2CD_IL        ;得到的一个字节在 ACC 中
        MOV        @R0, A
        INC        R0
        MOV        A, B
        XRL        A, #01H
        JZ        I2CD_GO
        CLR        SDA
        NOP
I2CD_GO:SETB        SCL
        NOP
        CLR        SCL
        DJNZ        B, I2CD_IB        ;取得不止一个字节

        ACALL        I2C_ED
        CLR        C
        RET
I2CD_RE:ACALL        I2C_ED
        SETB        C
        RET

; =========================================================================================
;向 IIC 总线发送一个字节
I2C_O:        PUSH        B
        MOV        B, #08H
I2C_OLP:RLC        A                ;ACC.7 -> C
        MOV        SDA, C
        SETB        SCL                ;SCL=1
        NOP
        CLR        SCL                ;SCL=0
        DJNZ        B, I2C_OLP
        SETB        SDA                ;准备接收 ACK 位
        SETB        SCL                ;SCL=1,
        NOP
        MOV        C, SDA
        CLR        SCL
        POP        B
        RET                        ;C=1, 未收到 ACK 位,出错, C=0, 收到 ACK 位,正常

; =========================================================================================
I2C_BG: SETB        SCL                ;确保SCL=HIGH
        CLR        SDA                ;向 IIC 总线发送开始位
        NOP
        CLR        SCL
        RET

; =========================================================================================
I2C_ED: CLR        SDA
        SETB        SCL
        NOP
        SETB        SDA                ;向 IIC 总线发送停止位
        RET


; =========================================================================================
;最好显示000-999=1000个,否则容易造成误解,这里显示全部2187个,0-9,A-F,H,L,P,U,Y
; =========================================================================================
FONT:       
        DB        0C0H                        ;"0"
        DB        0F9H                        ;"1"
        DB        0A4H                        ;"2"
        DB        0B0H                        ;"3"
        DB        099H                        ;"4"
        DB        092H                        ;"5"
        DB        082H                        ;"6"
        DB        0F8H                        ;"7"
        DB        080H                        ;"8"
        DB        090H                        ;"9"
        DB        088H                        ;"A"
        DB        083H                        ;"B"
        DB        0C6H                        ;"C"
        DB        0A1H                        ;"D"
        DB        086H                        ;"E"
        DB        08EH                        ;"F"
        DB        089H                        ;"H"
        DB        0F0H                        ;"J"
        DB        0C7H                        ;"L"
        DB        08CH                        ;"P"
        DB        0C1H                        ;"U"
        DB        08DH                        ;"Y"

; =========================================================================================
        END

tonyone 发表于 2013-10-3 11:56:17

源程序来自网络。
原理图在上面,现在的现象是3个数码管都显示0,按遥控器没有任何反应。
不知道eeprom要不要填内容

咖啡可乐 发表于 2013-10-3 12:43:22

不知道楼主的金牌会员是怎么来的

duanll 发表于 2013-10-3 15:04:43

本帖最后由 duanll 于 2013-10-3 17:09 编辑

同问,楼主有何秘方能快速拿到金牌会员资格?{:lol:}

难道楼主的ID被人偷了??

cxning 发表于 2013-10-4 16:15:29

楼主给点莫元吧.
问问题又不给莫元,太勾了!

cxning 发表于 2013-10-4 16:16:48

duanll 发表于 2013-10-3 15:04 static/image/common/back.gif
同问,楼主有何秘方能快速拿到金牌会员资格?

难道楼主的ID被人偷了?? ...

楼主发了74个主题,拿到金牌很正常,只要发的贴有人气.

tonyone 发表于 2013-10-6 23:08:55

我只能说有些人的脑袋装在裤裆里了。
页: [1]
查看完整版本: 请教汇编高人,这段PT2272 模拟解码器的程序要怎么玩得起...