C++ 无法写入闪存程序存储器(PIC18F4620)
我正试图把一些数据写入闪存程序存储器。我阅读了数据表并遵循了步骤。我还为rom数组编辑了链接器脚本。下面是我用C写的闪存程序内存序列的代码。我正试图写入地址0xFF00C++ 无法写入闪存程序存储器(PIC18F4620),c++,pic18,flash-memory,C++,Pic18,Flash Memory,我正试图把一些数据写入闪存程序存储器。我阅读了数据表并遵循了步骤。我还为rom数组编辑了链接器脚本。下面是我用C写的闪存程序内存序列的代码。我正试图写入地址0xFF00 TBLPTR = 0x3fc000; // start of erase seq EECON1 = 0b10010100; //EEPGD = 1, FREE = 1, WREN = 1, INTCONbits.GIE =
TBLPTR = 0x3fc000; // start of erase seq
EECON1 = 0b10010100; //EEPGD = 1, FREE = 1, WREN = 1,
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
TBLPTRU = 0x3F; // start of write seq
TBLPTRH = 0xC0;
TBLPTRL = 0x00;
for(i = 0; i<64; i++)
{
TABLAT = dispData0[i];
TBLPTRL = i;
}
EECON1 = 0b10000100; // EEPGD = 1, WREN = 1
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
TBLPTR = 0x00ff00;
dispData3[0] = TABLAT;
TBLPTR++;
dispData3[1] = TABLAT;
你的代码有两个问题。第一种情况是,您试图在地址
0x3FC000
处擦除和写入闪存,同时尝试在地址0x00FF00
处读取闪存。第二个问题是,从TBLLAT
读取和写入实际上并不执行读取或写入操作。它只是一个暂存寄存器,要执行读或写操作,需要使用TBLRD
或TBLWT
指令。这些指令在C中不可用,因此需要使用内联汇编:
TBLPTR = 0x00FF000 // start of write seq
for(i = 0; i<64; i++) {
TABLAT = dispData0[i];
_asm TBLWTPOSTINC _endasm // write TBLLAT to flash; increment TBLPTR
}
...
TBLPTR = 0x00FF00;
_asm TBLRDPOSTINC _endasm // read flash into TBLLAT; increment TBLPTR
dispData3[0] = TABLAT;
_asm TBLRDPOSTINC _endasm
dispData3[1] = TABLAT;
TBLPTR=0x00FF000//开始写入顺序
对于(i=0;iis EECON2 volitile?否则编译器可能会优化对它的写入。出于某种原因,它没有读回我刚才写入的数据。我将3fc000用于tblptr,因为数据表说明,对于写入,16位msb决定地址(?)5 lsb是64个内存寄存器。对于擦除,5 lsb被忽略。这就是为什么我在写入0xff00时使用0x3fc000。我不明白为什么你会认为这意味着需要将地址乘以64。这只意味着在擦除时忽略地址的低5位。将TBLPTR设置为0x00FF00
,0x00FF01
,或0x00FF3F
执行擦除操作将擦除0x00FF00
和0x00FF3F
之间闪存中的所有64个字节。写入低位5位时不会被忽略,TBLPTR
为0x00FF01
写入闪存中的地址0x00FF01
内存。我明白了。谢谢你的澄清。无论如何,回读是不正确的。我怀疑是配置位。我读了关于CPn、WRTn和EBTRn的第23节,我禁用了所有这些。这可能是个问题吗?
TBLPTR = 0x00FF000 // start of write seq
for(i = 0; i<64; i++) {
TABLAT = dispData0[i];
_asm TBLWTPOSTINC _endasm // write TBLLAT to flash; increment TBLPTR
}
...
TBLPTR = 0x00FF00;
_asm TBLRDPOSTINC _endasm // read flash into TBLLAT; increment TBLPTR
dispData3[0] = TABLAT;
_asm TBLRDPOSTINC _endasm
dispData3[1] = TABLAT;