Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用内联汇编写入闪存?_C_Assembly_Embedded_Microcontroller_Pic - Fatal编程技术网

C 如何使用内联汇编写入闪存?

C 如何使用内联汇编写入闪存?,c,assembly,embedded,microcontroller,pic,C,Assembly,Embedded,Microcontroller,Pic,我正在使用MPLAB C18编译器,并尝试使用内联汇编将一些值保存到闪存中,内联汇编是C和汇编代码的组合 _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

我正在使用MPLAB C18编译器,并尝试使用内联汇编将一些值保存到闪存中,内联汇编是C和汇编代码的组合

_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;
看起来我可以正确地写入和读取闪存,但只要我关闭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  
_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  
_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  
_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  
_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;
_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);
从闪存存储器读取

_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;
_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
之间的区别,因为我怀疑它们可能与问题有关

看起来您已经找到了解决方案:问题在于如何使用
银行

_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;
EECON2
等是驻留在气缸组15中的特殊功能寄存器(SFR)。访问它们的最快方法是使用
access
,它在计算地址时忽略银行寄存器

_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;
在您使用的汇编语言中,
ACCESS
表示0,
BANKED
表示1。
movwf
指令中需要这些值之一。数据表在其示例中使用实际数字,而不是符号常量

_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;
数据表还解释了RAM的存储方式

_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;
基本上,有一个as寄存器,它保存4位,表示组0到15。这个数字在给指令的8位数字前加上前缀,给出全部12位。这允许更快的执行。要存储在正确的位置,需要先将此寄存器设置为正确的银行

_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;
其中两个组0和15也映射到通用寄存器和特殊功能寄存器。因为这些是最常用的,所以快速获取它们的方法是在指令中使用一个标志,在计算地址时忽略银行寄存器,直接转到所需的GPR或SFR

_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  
_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;