⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 自己写的操作Flash Am29F400BT 的程序
💻 C
字号:
/*----------Copyright 2006-2010 武汉菱电汽车电子有限公司-----------------------
 * 项目名称: 汽车诊断仪
 * 开发工具: uV2 Keil C51
 * 程序名称: flash.c
 * 作者:     朱坤
 * 写作时间: 2006/03/02
 *
 * 程序说明:
 *    提供操作 Flash 的基本功能
 *    1、复位flash:void ResetFlash(void)
 *    2、擦除扇区: bit EraseSector(u16 wSA)
 *    3、全片擦除: bit EraseFlash(void)
 *    4、读Flash:   u8 ReadFlash(u16 wPA)
 *    5、编程Flash:bit WriteFlash(u16 wPA, u8 uPD)
 *    6、初始化:    void InitFlash(void)
 *    返回 TRUE 表示操作成功,FLASE 表示操作失败
 *
 * 修改记录:
 *
 *---------------------------------------------------------------------------*/
//#pragma SRC
//#pragma SMALL
//#pragma OPTIMIZE(SIZE)

#include "flash.h"

/*-----------------------------------------------------------------------------
 * Read  1 RA  RD
 * Reset 1 XXX F0
 * Autoselect
 * Manufacturer ID
 *   Word 4 555 AA 2AA 55 555 90 X00 01
 *   Byte   AAA    555    AAA
 * Device ID(Top Boot Block)
 *   Word 4 555 AA 2AA 55 555 90 X01 22D2
 *   Byte   AAA    555    AAA    X02 D2
 * Device ID(Bottom Boot Block)
 *   Word 4 555 AA 2AA 55 555 90 X01 22D8
 *   Byte   AAA    555    AAA    X02 D8
 * Sector Protect Verify
 *   Word 4 555 AA 2AA 55 555 90 (SA) X02 XX00
 *                                        XX01
 *   Byte   AAA    555    AAA    (SA) X04 00
 *                                        01
 * CFI Query (Note 10)
 *   Word 1 555 98
 *   Byte   AAA
 * Program
 *   Word 4 555 AA 2AA 55 555 A0 PA PD
 *   Byte   AAA    555    AAA
 * Unlock Bypass
 *   Word 3 555 AA 2AA 55 555 20
 *   Byte   AAA    555    AAA
 * Unlock Bypass Program  2 XXX A0 PA PD
 * Unlock Bypass Reset    2 XXX 90 XXX 00
 * Chip Erase
 *   Word 6 555 AA 2AA 55 555 80 555 AA 2AA 55 555 10
 *   Byte   AAA    555    AAA    AAA    555    AAA
 * Sector Erase
 *   Word 6 555 AA 2AA 55 555 80 555 AA 2AA 55 SA 30
 *   Byte   AAA    555    AAA    AAA    555
 * Erase Suspend  1 XXX B0
 * Erase Resume   1 XXX 30
 * --------------------------------------------------------------------------*/

/* 检查操作是否完成 */
BOOLEAN ToggleBitI(void)
{
  u8 uData1,uData2;
  //u8 i;

  uData1 = XBYTE[Addr_Flash];
  //i = 255;
  //while(i--){
  while(1){
    WD_Refresh(); /* 刷新看门狗 */

    uData2 = XBYTE[Addr_Flash];
    if (((uData1 ^ uData2) & 0x40) == 0){   /* D6 */
      return TRUE;
    } else if ((uData2 & 0x20) == 0x20){    /* D5 */
      uData1 = XBYTE[Addr_Flash];
      uData2 = XBYTE[Addr_Flash];
      if (((uData1 ^ uData2) & 0x40) == 0){ /* D6 */
        return TRUE;
      } else {             /* 操作错误 */
        ResetFlash();      /* 复位 */
        return FALSE;
      }
    }
    uData1 = uData2;
  }
  return FALSE;
}

/* Program
 *   Byte 4 AAA AA 555 55 AAA A0 PA PD
 *   这儿假设已经设置 Flash 的页地址  */
BOOLEAN WriteFlash(u16 wPA, u8 uPD)
{
  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  XBYTE[Addr_Flash|0x0AAA] = 0x0A0;
  XBYTE[wPA] = uPD;

  /* 检查是否完成 */
  ToggleBitI();

  if (XBYTE[wPA] == uPD){
    return TRUE;
  }
  return FALSE;
}

/* Sector Erase
 *   Byte 6 AAA AA 555 55 AAA 80 AAA AA 555 55 SA 30
 *   这儿假设已经设置 Flash 的页地址  */
BOOLEAN EraseSector(u16 wSA)
{
  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  XBYTE[Addr_Flash|0x0AAA] = 0x80;
  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  if ((wSA & 0x7fff)!= 0){
    XBYTE[wSA] = 0x30;
  } else {
    XBYTE[Addr_Flash|0xAAA]  = 0x10;
  }

  /* 检查是否完成 */
  return ToggleBitI();
}

/* 初始化
 * Autoselect
 * Manufacturer ID
 *   Word 4 555 AA 2AA 55 555 90 X00 01
 *   Byte   AAA    555    AAA
 * Device ID(Top Boot Block AM29F160D)
 *   Word 4 555 AA 2AA 55 555 90 X01 22D2
 *   Byte   AAA    555    AAA    X02 D2
 * Device ID(Bottom Boot Block AM29F160D)
 *   Word 4 555 AA 2AA 55 555 90 X01 22D8
 *   Byte   AAA    555    AAA    X02 D8
 * Sector Protect Verify
 *   Word 4 555 AA 2AA 55 555 90 (SA) X02 XX00
 *                                        XX01
 *   Byte   AAA    555    AAA    (SA) X04 00
 *                                        01 */
u16 InitFlash(void)
{
  u16 i;

  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  XBYTE[Addr_Flash|0x0AAA] = 0x90;

  i = (XBYTE[Addr_Flash|0x02] * 256) + XBYTE[Addr_Flash|0x00];

  ResetFlash();      /* 复位 */

  return i;
}

/* Chip Erase
 *   Byte 6 AAA AA 555 55 AAA 80 AAA AA 555 55 AAA 10 */
/*
bit EraseFlash(void)
{
  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  XBYTE[Addr_Flash|0x0AAA] = 0x80;
  XBYTE[Addr_Flash|0x0AAA] = 0x0AA;
  XBYTE[Addr_Flash|0x555]  = 0x55;
  XBYTE[Addr_Flash|0xAAA]  = 0x10;

  // 检查是否完成
  return ToggleBitI();
}
*/

/* 编程 Flash
 * dPA: 编程起始地址[注意: 线性地址,不考虑分区]
 * upPD: 被编程的数据指针, 数据限定在外存[xdata]当前页内
 * uLen: 被编程的数据字节数[若为 0,则不执行编程操作]
 *
 * 本过程没有检查 Flash 地址是否超过允许范围,
 * 也没有检测被编程的数据字节数是否超出允许范围,
 * 所有参数都需要调用者保证合法。                      */
/*
bit ProgramFlash(FourBytes dAddr, u8 xdata *upPD, u16 uLen)
{
  u8 uPage;
  u8 uOldPage;
  bit bResult;

  // 设置 Flash 的页地址
  uOldPage = GetCurrentBank();
  uPage = dAddr.b_form.hl << 1;
  if ((dAddr.b_form.lh & 0x80) != 0x00){
    uPage++;
  }
  SwitchBank(uPage);

  // 数据最大长度不允许超过 16K
  bResult = TRUE;
  if ((uLen > Len_SRAM) ||
      (upPD < (u8 xdata *)Addr_SRAM)||
      ((upPD+uLen) >= (u8 xdata *)(Addr_SRAM+Len_SRAM))){
    bResult = FALSE;
  }

  while(bResult && (uLen-- != 0x0000)){

    // 如果到了扇区[Sector]的开头位置,擦除扇区
    // 我只支持 Bottom Boot Block 型的 flash
    if ((dAddr.b_form.ll == 0x00) &&
        ((dAddr.b_form.lh == 0x00) ||
         ((dAddr.b_form.hl == 0x00) &&
          ((dAddr.b_form.lh == 0x40) ||
           (dAddr.b_form.lh == 0x60) ||
           (dAddr.b_form.lh == 0x80))))){
      bResult = EraseSector(dAddr.w_form.lo|Addr_Flash);
    }

    if (bResult){
      bResult = WriteFlash(dAddr.w_form.lo|Addr_Flash, *upPD++);

      // 如果到了分区[BANK]的开头,切换分区
      if ((dAddr.w_form.lo & 0x7fff) == 0x7fff){
        SwitchBank(++uPage);
      }
    }

    dAddr.d_form++;
  }

  // 恢复 Flash 当前活动页
  SwitchBank(uOldPage);
  return bResult;
}
*/

/*----------Copyright 2006-2010 武汉菱电汽车电子有限公司---------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -