IAP教程里的擦除函数怎么用啊
void EFLASH_erase(unsigned char ucAddress) //擦除是按页擦除的……不是象AVR一样擦除。郁闷ing{ //擦除扇区
/* Wait for completion of previous write */
while(EECR & (1 << EEPE));
/* Set up Address register */
EEARH = ucAddress;
/* Set up EFLASH erase Operation */
EECR |= (1 << EEPM2) | (1 << EEPM0);
EECR &= ~(1 << EEPM1);
/* Write logic one to EEMPE*/
EECR |= (1 << EEMPE);
/* Start EEPROM programming by writing EEPE */
EECR |= (1 << EEPE);
}
每次执行到置位EEPE的时候都会发生一次系统复位。我确保在调用该函数前调用了cli。但是依然没办法。不过如果注释掉EECR那一行就没有问题。
不知为什么执行EEPE的时候会发生系统复位。另外就是那个ucAddress直接是用页号吗? 本帖最后由 xwkm 于 2013-1-26 01:57 编辑
这个是gcc生成的汇编代码。貌似没啥不对劲的
00001a86 <EFLASH_erase>:
1a86: f9 99 sbic 0x1f, 1 ; 31
1a88: fe cf rjmp .-4 ; 0x1a86 <EFLASH_erase>
1a8a: 82 bd out 0x22, r24 ; 34
1a8c: 8f b3 in r24, 0x1f ; 31
1a8e: 80 69 ori r24, 0x90 ; 144
1a90: 8f bb out 0x1f, r24 ; 31
1a92: fd 98 cbi 0x1f, 5 ; 31
1a94: fa 9a sbi 0x1f, 2 ; 31
1a96: 00 00 nop
1a98: 08 95 ret
每次一置位EEPE立马就复位 问题已经解决。原因是我写的启动代码没有初始zero flag void EraseAP()
{//擦除AP区域
//这里比较危险,非常容易自宫
//流程,从0擦到bootloader的开始值(保存INT0和RESET的中断值)。然后调用prog写回去
unsigned int i;
wdt_disable();
cli();//关闭中断
for(i=0;i<8;i++)
{//把原来的中断向量表读入内存
cache=pgm_read_byte(i);
}
PORTA=0x00;
for(i=0;i<((BOOT_START-1)/SECTOR_SIZE);i++)
{
EFLASH_erase(i);//擦除扇区
}
/*EFLASH_write(0,0x0c,0x94);
EFLASH_write(2,0x76,0x0b);
EFLASH_write(4,0x0c,0xae);
EFLASH_write(6,0x76,0x0b);*/
for(i=0;i<8;i+=2)
{
EFLASH_write(i,cache,cache);
}
//sei();//开中断
}
这段代码在我的bootloaderHID里面仅仅用于擦除APP区。bootloader仍然控制INT0和RESET向量
页:
[1]