如何使用内联汇编写入闪存?
我正在使用带有PIC18F87J11的 MPLAB C18编译器,我正在尝试使用内联汇编将一些值保存到闪存中,这是C和汇编代码的组合。
看起来我可以正确地写入和读取闪存,但是一旦我重新启动PIC然后尝试读取我之前从特定地址保存的内容,我就得不到相同的值。 我将0x09
保存到0xB22A
地址。 就像我说的,如果我保存值然后立即读取它,一切都正确,但重置PIC后我得到0x00
。
我不是永久保存到闪存或这里真的发生了什么?
这是我的代码:
擦除内存行
_asm MOVLW 0x00 MOVWF TBLPTRU,BANKED MOVLW 0xB2 MOVWF TBLPTRH,BANKED MOVLW 0x2A MOVWF TBLPTRL,BANKED _endasm EECON1bits.FREE = 1; INTCONbits.GIE = 0; _asm MOVLW 0x55 MOVWF EECON2,BANKED MOVLW 0xAA MOVWF EECON2,BANKED _endasm EECON1bits.WR = 1; INTCONbits.GIE = 1;
写入闪存
_asm MOVLW 0x00 MOVWF TBLPTRU,BANKED MOVLW 0xB2 MOVWF TBLPTRH,BANKED MOVLW 0x2A MOVWF TBLPTRL,BANKED MOVLW 0x09 MOVWF TABLAT,BANKED TBLWTPOSTINC MOVLW 0x09 MOVWF TABLAT,BANKED TBLWT _endasm EECON1bits.WPROG = 1; EECON1bits.WREN = 1; INTCONbits.GIE = 0; _asm MOVLW 0x55 MOVWF EECON2,BANKED MOVLW 0xAA MOVWF EECON2,BANKED _endasm EECON1bits.WR = 1; INTCONbits.GIE = 1; EECON1bits.WPROG = 0; EECON1bits.WREN = 0;
从flash memeory读取
_asm MOVLW 0x00 MOVWF TBLPTRU,BANKED MOVLW 0xB2 MOVWF TBLPTRH,BANKED MOVLW 0x2A MOVWF TBLPTRL,BANKED READ_WORD: TBLRDPOSTINC MOVF TABLAT, 0,BANKED MOVWF WORD_EVEN,ACCESS TBLRDPOSTINC MOVF TABLAT, 0,BANKED MOVWF WORD_ODD,ACCESS _endasm printf("\r\n"); PrintChar(WORD_EVEN); printf("\r\n"); PrintChar(WORD_ODD);
原始代码可以在第6章的数据表中找到,但请记住我必须稍微修改它才能与C一起使用。我不确定ACCESS
和BANKED
之间有什么区别,因为我怀疑它们可能是与问题有关。
看起来你已经找到了解决方案:问题在于使用BANKED
。
EECON2
等是驻留在bank 15中的特殊function寄存器(SFR)。访问它们的最快方法是使用ACCESS
,它在计算地址时忽略bank寄存器。
它看起来像您使用的汇编语言, ACCESS
表示0, BANKED
表示1. movwf
指令中需要其中一个值。 数据表使用其示例中的实际数字,而不是符号常量。
数据表还解释了RAM的存储方式。
基本上,存在作为寄存器,其保持4位表示存储体0到15.该数字被添加到给予指令的8位数,以给出所有12位。 这允许更快的执行。 要存储在正确的位置,您需要先将此寄存器设置为正确的存储区。
其中两个存储区0和15也映射到通用寄存器和特殊function寄存器。 由于这些是最经常使用的,因此快速获取它们的方法是在指令中使用一个标志来忽略计算地址中的存储区寄存器,然后直接转到所需的GPR或SFR。
您的问题是您正在设置标志以使用寄存器所在的不同存储区。