将汇编转换为C [使用PIC18写入存储器]

Amm*_*mar 1 c microcontroller assembly pic

我正在尝试写入PIC18F87J11上的闪存,但我在理解汇编时遇到了问题.我的PIC的数据表只有汇编,我正在使用C编译器.我想知道是否有人可以帮助我将这部分代码翻译成C语言.此代码可在此处找到,第7.5节.

MOVLW CODE_ADDR_UPPER ; Load TBLPTR with the base address
MOVWF TBLPTRU
MOVLW CODE_ADDR_HIGH
MOVWF TBLPTRH
MOVLW CODE_ADDR_LOW
MOVWF TBLPTRL
MOVLW DATA0
MOVWF TABLAT
TBLWT*+
MOVLW DATA1
MOVWF TABLAT
TBLWT*
PROGRAM_MEMORY
BSF EECON1, WPROG ; enable single word write
BSF EECON1, WREN ; enable write to memory
BCF INTCON, GIE ; disable interrupts
MOVLW H'55'
MOVWF EECON2 ; write H'55'
MOVLW H'AA'
MOVWF EECON2 ; write H'AA'
BSF EECON1, WR ; start program (CPU stall)
BSF INTCON, GIE ; re-enable interrupts
BCF EECON1, WPROG ; disable single word write
BCF EECON1, WREN ; disable write to memory
Run Code Online (Sandbox Code Playgroud)

我知道这不是一个典型的问题,但如果我能得到一些帮助就会很棒.

emb*_*guy 7

将其分解为几个步骤可能是最容易的.我要做的第一件事是看一下在查看装配之前需要完成什么的概述.这可以在你的参考文献的 7.5.2中找到.

重要的是要注意,当WPROG位置1并且必须已经擦除存储器位置时,才能启用执行字写操作的功能.以下是步骤:

  1. 加载表指针寄存器,包含要写入的数据的地址.
  2. 将2个字节写入保持寄存器并执行表写操作.
  3. 将WREN位(EECON1 <2>)置1以使能字节写操作.
  4. 禁用中断.
  5. 将H'55'写入EECON2.
  6. 将H'AA写入EECON2.
  7. 设置WR位.这将开始写周期.
  8. 在写入Tiw期间,CPU将停止运行(参见参数D133A).
  9. 重新启用中断.

然后,为了清楚起见,我们可以将装配分解为给定的步骤.我还评论了每行代码,以便您可以看到程序集正在做什么(我不会在实际代码中执行此操作,因为它只会分散注意力).

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.
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

其余步骤包含在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. 
Run Code Online (Sandbox Code Playgroud)

由于我没有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;
}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!

  • 你是一个比我更好的人.非常善于你为Ammar打破这个. (4认同)