高速案例构造汇编器 负载DPTR快速-8051



我目前正在为8051 IC(特别是AT89C4051(实现串行例程,而我剩下的堆栈空间或内存不多,为了让我实现不错的baud在串行端口(38K或更高(上的速率,我需要进行高速案例构造,因为在我的串行端口中断程序中,我正在构建数据包并检查有效性。

假设我们在串行中断中,R0是要接收数据的内存空间的地址。假设开始地址为40H

所以我们在这里进行了很多比较:

通过许多比较进行分支

serial:
    mov A,SBUF
    mov @R0,A
    mov A,R0
    anl A,#07h ;our packet is 8 bytes so get current packet # based on what we stored so far
    cjne A,#0h,nCheckMe ;this gets scanned if A=7... waste 2 clock cycles
        //We're working on first byte 
        ajmp theend
    nCheckMe:    
    cjne A,#1h,nCheckThem ;this gets scanned if A=7... waste 2 clock cycles
        //We're working on second byte 
        ajmp theend
    nCheckThem:    
    ...
    cjne A,#7h,nCheckEnd
        //We're working on last byte 
        ajmp theend
    nCheckEnd:    
    theend:
    inc R0
reti

首先,上面的代码可能是实用的,但是随着数据包中的当前字节增加增加,例程每次运行2个时钟周期,因为额外的" CJNE"指令处理。例如,如果我们处于第七字节,那么" CJNE"将发生多次,因为它必须扫描每种情况,从而添加缓慢。

通过跳跃分支

现在,我想到了只使用跳跃,但我不知道如何在高速上加载DPTR,因为即使某些其他过程使用dptr的值,也可以调用中断。

我想到了这个代码:

serial:
    mov A,SBUF
    mov @R0,A
    mov A,R0
    anl A,#07h ;our packet is 8 bytes so get current packet # based on what we stored so far
    swap A ;multiply A times 16 and
    rr A ;divide A by 2 so we get address times 8 since each block uses 8 bytes of code space.
    mov R3,DPH ;save DPTR high byte without breaking stack
    mov R6,DPL ;save DPTR low byte
    mov dptr,#table
    jmp @A+DPTR
    theend:
    mov DPL,R6 ;restore DPTR low byte
    mov DPH,R3 ;restore DPTR high byte
    inc R0     ;move on to next position
reti
table:
;insert 8 bytes worth of code for 1st case
;insert 8 bytes worth of code for 2nd case
;insert 8 bytes worth of code for 3rd case
...
;insert unlimited bytes worth of code for last case

在我的代码中,R3和R6是免费的,因此我用它们来存储旧的DPTR值,但是这些MOV说明以及加载新的DPTR值每个循环每个周期为10个周期总计(包括还原旧值(。/p>

是否有一种更快的方法来处理8051汇编代码中的案例构造,以使我的串行例程更快地处理?

如果可能的话,请勿在ISR中运行逻辑。如果您坚持认为,您也许可以将DPTR分配给ISR,并且仅在非常短的常规代码中使用中断。另外,推动 ret技巧可以起作用。

这是一种链接方法,每个处理的字符都为下一步设置地址。如果您可以确保步骤在同一256字节块中,则只需要更新低字节即可。总开销是8个周期,但是您还为算术保存了4个周期,因此这是6个周期的胜利。

.EQU PTR, 0x20  ; two bytes of SRAM
; Initialize PTR to address of step1 
serial:
    push PTR
    push PTR+1
    ret
step1:
    ; do stuff
    mov PTR, #low8(step2)
    reti
last_step:
    ; do stuff
    mov PTR, #low8(step1)
    reti

最新更新