xwkm 发表于 2013-1-26 01:49:34

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:51:22

本帖最后由 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立马就复位

xwkm 发表于 2013-1-26 21:16:43

问题已经解决。原因是我写的启动代码没有初始zero flag

xwkm 发表于 2013-1-26 21:31:29

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]
查看完整版本: IAP教程里的擦除函数怎么用啊