将其分解为几个步骤可能是最简单的。我要做的第一件事是在查看装配之前查看需要完成的总体概述。这可以在您的参考资料的 7.5.2 中找到。
重要的是要注意,当 WPROG 位被设置并且存储器位置必须已经被擦除时,执行字写入的能力被启用。以下是步骤:
- 将要写入的数据的地址装入表指针寄存器。
- 将 2 个字节写入保持寄存器并执行表写入。
- 将 WREN 位(EECON1<2>)置 1 以使能字节写入。
- 禁用中断。
- 将 H'55' 写入 EECON2。
- 将 H'AA' 写入 EECON2。
- 设置 WR 位。这将开始写周期。
- CPU 将在 Tiw 写入期间停止(参见参数 D133A)。
- 重新启用中断。
然后,为了清楚起见,我们可以将组件分解为给定的步骤。我还注释了每一行代码,以便您可以看到程序集在做什么(我永远不会在实际代码中这样做,因为它只会分散注意力)。
1. 用要写入的数据地址加载表指针。
MOVLW CODE_ADDR_UPPER ;Move the value CODE_ADDR_UPPER to the working register.
MOVWF TBLPTRU ;Move the working register to TBLPTRU.
MOVLW CODE_ADDR_HIGH ;Move the value CODE_ADDR_HIGH to the working register.
MOVWF TBLPTRH ;Move the working register to TBLPTRH
MOVLW CODE_ADDR_LOW ;Move the value CODE_ADDR_LOW to the working register.
MOVWF TBLPTRL ;Move the working register to TBLPTRL.
2. 将 2 个字节写入保持寄存器并执行表写入。
MOVLW DATA0 ;Move DATA0 to the working register.
MOVWF TABLAT ;Move the working register to TABLAT.
TBLWT*+ ;Write the data stored in TABLAT to the position
;defined in TBLPTR and then, increment TBLPTR.
MOVLW DATA1 ;Move DATA1 to the working register.
MOVWF TABLAT ;Move the working register to TABLAT.
TBLWT* ;Write the data stored in TABLAT to the position defined in TBLPTR.
其余步骤包含在 PROGRAM_MEMORY 部分中。
PROGRAM_MEMORY ; This is just a label.
;STEP 3
BSF EECON1, WPROG ;Set the WPROG bit in the EECON1 register.
BSF EECON1, WREN ;Set the WREN bit in the EECON1 register.
;STEP 4
BCF INTCON, GIE ;Clear the GIE bit in the INTCON register.
;STEP 5
MOVLW H'55' ;Move 0x55 to the working register
MOVWF EECON2 ;Write 0x55 to EECON2 register.
;STEP 6
MOVLW H'AA' ;Move 0xAA to the working register.
MOVWF EECON2 ;Write 0xAA to the EECON2 register.
;STEP 7 AND 8
BSF EECON1, WR ;Set the WR bit in the EECON1 register.
;STEP 9
BSF INTCON, GIE ;Set the GIE bit in the INTCON register.
BCF EECON1, WPROG ;Clear the WPROG bit in the EECON1 register.
BCF EECON1, WREN ;Clear the WREN bit in the EECON1 register.
由于我既没有 PIC 编译器也没有 IDE,我知道下面的 C 代码并不完美(请随意编辑)。但是,这应该让您很好地了解如何基于汇编示例构建 C 代码。
static void FlashWriteWord(unsigned int store_addr, unsigned char * data)
{
/* 1. Load Table Pointer with the address of the data to be written. */
TBLPTR = store_addr;
/* 2. Write the 2 bytes into the holding registers and perform a table write. */
TABLAT = data;
_asm
TBLWTPOSTINC /* Table writes are performed as inline assembly functions. */
_endasm
data++;
_asm
TBLWT /* Table writes are performed as inline assembly functions. */
_endasm
/* 3. Set the write enable bit to enable byte writes. */
EECON1bits.WPROG = 1;
EECON1bits.WREN = 1;
/* 4. Disable interrupts. */
INTCONbits.GIE = 0;
/* 5. Write H'55' to EECON2. */
EECON2 = 0x55;
/* 6. Write H'AA' to EECON2. */
EECON2 = 0xAA;
/* 7. Set the WR bit. This will begin the write cycle. */
/* 8. The CPU will stall for the duration of the write for Tiw (see Parameter D133A). */
EECON1bits.WR = 1;
/* 9. Re-enable interrupts. */
INTCONbits.GIE = 1;
EECON1bits.WPROG = 0;
EECON1bits.WREN = 0;
}
希望有帮助!