使用 addwf pic18f2x 将值添加到 PCL 时重置 PCH

Reset of PCH when adding a value to PCL using addwf pic18f2x

我试图通过向程序计数器添加特定索引来在程序集中使用简单查找 table。它似乎在 PCL 的范围内工作(所以直到 0xff)但是之后,当 PCH 开始播放时 PCH 只是在 [= 之后重置17=]指令。

如何防止 PCH 添加后重置?我是否需要以某种方式操纵 PCLATHPCLATU,以便 PCH 保持其值。

我正在使用带有 mpasm 汇编器的 pic18f25k50。

所以这个查找 table 工作正常:

TABLE_GET_VALUE
    movf    index, 0 ; memory location = 0x9E 
    mullw   4
    movf    PRODL, 0
    addwf   PC
    movf    0x20, 0
    return
    movf    0x21, 0
    return
    movf    0x22, 0
    return
    movf    0x23, 0
    return
    movf    0x24, 0
    return
    movf    0x25, 0
    return
    movf    0x26, 0
    return
    movf    0x27, 0
    return
    movf    0x28, 0
    return      ; memory location = 0xC8

而这个将程序重置回第一条指令:

TABLE_GET_COEFFICIENT
    movf    index, 0    ; memory location 0x108
    mullw   4
    movf    PRODL, 0
    addwf   PC
    movf    0x30, 0
    return
    movf    0x31, 0
    return
    movf    0x32, 0
    return
    movf    0x33, 0
    return
    movf    0x34, 0
    return
    movf    0x35, 0
    return
    movf    0x36, 0
    return
    movf    0x37, 0
    return
    movf    0x38, 0
    return      ; memory location 0x132

所以我找到了答案。

显然,当您写入 PCL 时,PCLATHPCLATU 的内容会直接写入 PCHPCU。这意味着在此过程中锁存器永远不会更新为当前值。更新 PCLATHPCLATU 的一种方法是阅读 PCL。这会触发锁存器更新为当前值,这意味着稍后写入 PCL 时会复制 wright 值。

像这样:

TABLE_GET_COEFFICIENT
    movf    index, 0    ; memory location 0x108
    mullw   4
    movf    PC, 0       ; writing te PC value just for updating latches
    movf    PRODL, 0
    addwf   PC
    movf    0x30, 0
    return
    movf    0x31, 0
    return
    movf    0x32, 0
    return
    movf    0x33, 0
    return
    movf    0x34, 0
    return
    movf    0x35, 0
    return
    movf    0x36, 0
    return
    movf    0x37, 0
    return
    movf    0x38, 0
    return      ; memory location 0x132

数据中的更多信息 sheet:3.1.1 和 5.1.1

这是对 table 查找 PIC18F 控制器进行编码的完整方法的一个示例。

;------------------------------------------------------------------------------ 
; MAIN PROGRAM 
;------------------------------------------------------------------------------ 
MAIN_CODE CODE              ; let linker place main program 

Main: 
    movlw   8
    call    TableOneLookup
    bra     Main

;------------------------------------------------------------------------------ 
;
; TableOneLookup
;
; Description: Look up data in table placed in code space
;
; Input:  WREG = byte offset in table
;
; Output: WREG = byte from table
;
;------------------------------------------------------------------------------ 
TABLE_ONE_CODE  code
TableOneLookup:
    push
    clrf    TOSU
    clrf    TOSH
    movwf   TOSL                ; Save offset in to TableOne
    addwf   TOSL,F              ; Double offset in to TableOne
    rlcf    TOSH,F              ; Propagate carry
    movlw   LOW(TabelOne)       ; Add TableOne address low byte
    addwf   TOSL,F
    movlw   HIGH(TabelOne)      ; Add TableOne address high byte
    addwfc  TOSH,F
    movlw   UPPER(TabelOne)     ; Add TableOne address upper byte
    addwfc  TOSU,F
    return                      ; Branch in to TableOne
TabelOne:
    DT      0x30
    DT      0x31
    DT      0x32
    DT      0x33
    DT      0x34
    DT      0x35
    DT      0x36
    DT      0x37
    DT      0x38
    end

有更好的方法可以使用专为程序内存读取操作设计的汇编语言操作码。