www.pudn.com > AT89C2051.rar > AT89C2051.ASM


;模拟串行通讯程序 
 
 io_rxd  equ  p3.2           ;模拟rxd,中断接收 
 io_txd  equ  p1.0           ;模拟txd 
 ar_sbuf equ  7eh            ;模拟串行接收存储单元 
 at_sbuf equ  7fh            ;模拟串行发送存储单元 
 a_ri    bit  0                    ;模拟串行接收标志位,a_ri="1",表示已接收新数据 
 a_ti    bit  1                    ;模拟串行发送标志位,a_ti="1",表示已发送新数据 
 
         org 0000h 
             ljmp start        ;复位入口 
         org 0003h 
             ljmp a_asi          ;模拟串行接收中断入口 
 
         org 0030h 
start:   mov sp,#30h 
              setb px0            ;置模拟串行接收(int0)最高级中断 
         setb ex0             ;允许int0中断 
         setb ea              ;总中断允许 
;...... 
main: 
;...... 
         mov at_sbuf,#0      ;将要发送的数据存入at_sbuf 
         lcall a_aso            ;调模拟串行发送子程序 
;...... 
         ljmp main 
 
;模拟串行接收中断程序 
a_asi:   push psw             ;psw保护入栈 
         push acc             ;acc保护入栈 
        setb rs0              ;更换工作寄存器组 
        setb rs1              ;或使用其它未被使用的工作寄存器组 
        mov r7,#8            ;接收8位数据位 
;接收起始位 
        lcall a_delay05t ;调1/2位周期延时子程序 
        lcall a_test_bit  ;调逻辑检测子程序 
        jnc a_asi2            ;起始位正确转a_asi2,起始位逻辑应为“0” 
;程序返回出口 
a_asi1:  pop acc                ;acc保护出栈 
         pop psw               ;psw保护出栈 
         reti                      ;开中断返回 
;接收8位数据位 
a_asi2:  lcall a_delay10t ;调位周期延时子程序        
         lcall a_test_bit  ;调逻辑检测子程序 
         rrc a                     ;数据位暂存于累加器中 
         djnz r7,a_asi2       ;8位数据未接收完循环至a_asi2 
;接收终止位 
         lcall a_delay10t  ;调位周期延时子程序      
         lcall a_test_bit  ;调逻辑检测子程序 
         jnc a_asi1             ;终止位不正确转a_asi1 
             setb a_ri               ;模拟串行接收标志位a_ri置位 
         mov ar_sbuf,a      ;8位接收数据存入模拟串行接收存储器ar_sbuf 
             sjmp a_asi1           ;转中断出口返回 
 
;模拟串行发送子程序 
a_aso:   clr ea                   ;禁止所有中断 
a_aso1:  mov r4,#9            ;8位数据+1位终止位 
         clr io_txd            ;模拟串口输出逻辑"0",输出起始位 
          nop 
              mov a,at_sbuf     ;模拟发送数据存储器内容送累加器 
         setb c                  ;终止位在c中,置终止位 
a_aso2:  lcall a_delay10t1  ;调位周期延时子程序 
          rrc a                        ;取发送逻辑至c中 
          mov io_txd,c           ;由模拟串行口发送 
          djnz r4,a_aso2        ;未发送完循环至a_aso2 
              lcall a_delay10t1  ;调位周期延时子程序 
          setb a_ti                 ;模拟串新接收标志位置位 
          setb ea                    ;开中断 
          ret                           ;返回 
 
;模拟串行接收逻辑检测子程序,三取二 
a_test_bit: jb io_rxd,a_test_bit1   ;第1次检测为“1”,转a_test_bit1 
                    jnb io_rxd,a_test_bitl ;两次检测都为“0”,转a_test_bitl 
                    jb io_rxd,a_test_bith   ;第3次检测为"1",转a_test_bith 
a_test_bitl:clr c                              ;检测逻辑在c中,c清零 
             ret                                 ;返回 
a_test_bit1:jb io_rxd,a_test_bith   ;两次检测都为“1”,转a_test_bith 
                     jnb io_rxd,a_test_bitl ;第3次检测为"0",转a_test_bitl 
a_test_bith:setb c                            ;检测逻辑在c中,c置位 
              ret                                ;返回 
 
;模拟串行通讯程序延时子程序 
;时钟频率=11.0592MHz,波特率=9600pbs 
 
A_DELAY05T: MOV R5,#12 
A_DELAY05T1:DJNZ R5,$ 
            RET 
A_DELAY10T: MOV R5,#38 
            NOP 
            SJMP A_DELAY05T1 
A_DELAY10T1:MOV R5,#42 
            SJMP A_DELAY05T1