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

📄 copyer.c

📁 SST39VFXXX系列闪存拷贝机
💻 C
字号:
#include "STC5X.H"
#include <intrins.h>
#include <absacc.h>

sbit SFLS =  P4^1;    //FLASH选择
sbit CHIP =  P3^2;    //外接跳线芯片选择,置0为4MbitFLASH,置1为2MbitFLASH,可由程序自定义不同的FLASH
sbit BUZ  =  P1^7;    //指示灯
sbit STAR =  P1^3;    //启动按钮

sbit A16  =  P1^0;    //FLASH高于bit15地址
sbit A17  =  P1^2;
sbit A18  =  P1^1;

#define   S_HZK          SFLS = 0
#define   S_SAV          SFLS = 1

#define   PAGE0  A18=0; A17=0; A16=0;
#define   PAGE1  A18=0; A17=0; A16=1;
#define   PAGE2  A18=0; A17=1; A16=0;
#define   PAGE3  A18=0; A17=1; A16=1;
#define   PAGE4  A18=1; A17=0; A16=0;
#define   PAGE5  A18=1; A17=0; A16=1;
#define   PAGE6  A18=1; A17=1; A16=0;
#define   PAGE7  A18=1; A17=1; A16=1;
#define   PAGER  A18=1; A17=1; A16=0;
#define   PAGEM  A18=1; A17=1; A16=1;

#define  BAUT9600     0xf4           //9600@22.1184M/6T
#define  FALSE        0
#define  TRUE         1
#define  false        0
#define  true         1

//这里如果有字符串写起来会更简洁
unsigned char code  EraseChip[18] = {0x0d,0x0a,'E','r','a','s','e',' ','c','h','i','p','.','.','.','.','.','.'};
unsigned char code  StartProgrammer[21] = {0x0d,0x0a,'S', 't', 'a','r','t',' ','p','r','o','g','r','a','m','.','.','.','.','.','.'};
unsigned char code  VerifyChip[19] = {0x0d,0x0a,'V','e','r','i','f','y',' ','c','h','i','p','.','.','.','.','.','.'};
unsigned char code  ProSuc[22] = {0x0d,0x0a,'V','e','r','i','f','y',' ','s','u','c','c','e','s','s','f','u','l','l','y','.'};
unsigned char code  ProFail[16] = {0x0d,0x0a,'V','e','r','i','f','y',' ','f','a','i','l','e','d','.'};
unsigned char code  Dot[1] = '.';
unsigned char       ledlen,ledfls,ledon;
    
/*================================================================
 * 函 数 名:  inichip
 * 参    数:  none
 * 功能描述:
 *            初始寄存器
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:21
===================================================================*/
void inichip(void)
 {
   SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr (REN=1)
   TMOD  = 0x21;       //TMOD: timer 1, mode 2, 8-bit reload

   TH1   = BAUT9600;   //Baud:4800  fosc=11.0592MHz
   IE    = 0xA0;       //EA - ET2 ES ET1 EX1 ET0 EX0
   TCON  = 0x54;       //TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0       //外部中断1为跳变触发

   T2CON=0x04;
   TH2 = 0x4b;               // 定时器初值
   TL2 = 0xfd;
   TR2 = 1;

   AUXR=0x03;               //禁用内部扩展RAM
 }
 
/*================================================================
 * 函 数 名:  timer2Int
 * 参    数:  none
 * 功能描述:
 *            定时器2中断处理
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:21
===================================================================*/
void timer2Int(void) interrupt 5
 {
   TF2 = 0;     // 溢出标志必须由软件清零
   EXF2 = 0;    // 捕获标志必须由软件清零
   TH2 = 0x4b;  // 定时器初值50mS
   TL2 = 0xfd;

   if(ledlen)          //这里由于不缺资源,这几句效率可能不高,呵呵
     --ledlen;
     else
       {
         if(ledon)
           {
             BUZ = !BUZ;
             ledlen = ledfls;
           }
       }
 }
 
/*================================================================
 * 函 数 名:  SendPackageToCom
 * 参    数:  dat: 要发送的数据指针; slen: 长度
 * 功能描述:
 *            查询方式发送数据串
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:22
===================================================================*/
void SendPackageToCom(unsigned char *dat, unsigned char slen)
 {
   unsigned char i;
   TI=0;
   i=0;
   while(i<slen)
     {
       SBUF=dat[i];
       while(!TI);           //Sending.......
       TI=0;
       ++i;
     }
 }
 
/*================================================================
 * 函 数 名:  TurnChipAdr
 * 参    数:  cadr: FLASH高于A15地址
 * 功能描述:
 *            选择高地址
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:22
===================================================================*/
void TurnChipAdr(unsigned char cadr)
 {
   switch(cadr)
     {
       case 0:
              PAGE0;
              break;
       case 1:
              PAGE1;
              break;
       case 2:
              PAGE2;
              break;
       case 3:
              PAGE3;
              break;
       case 4:
              PAGE4;
              break;
       case 5:
              PAGE5;
              break;
       case 6:
              PAGER;
              break;
       case 7:
              PAGEM;
              break;
     }
 }
 
/*================================================================
 * 函 数 名:  Delay_1_0Milli_Seconds
 * 参    数:  none
 * 功能描述:
 *            延时10mS
 * 返 回 值:  none
 * 作    者:  ucore
 * 修改日期:  2006.11.29
===================================================================*/
void Delay_10_Milli_Seconds()
 {
   unsigned int i;
//   WDT_CONTR = 0x34;
   i=4000;
   while(i)--i;                      //10ts
 }

/*================================================================
 * 函 数 名:  Check_Toggle_Ready
 * 参    数:  dst: 地址
 * 功能描述:
 *            查询FLASH忙状态
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:22
===================================================================*/
void Check_Toggle_Ready (unsigned int Dst)
 {
   unsigned char Loop = TRUE;
   unsigned char PreData;
   unsigned char CurrData;
   unsigned long TimeOut = 0;

   PAGE0;
   PreData = XBYTE[Dst];
   PreData = PreData & 0x40;
   while ((TimeOut< 0x07FFFFFF) && (Loop))
     {
       CurrData = XBYTE[Dst];
       CurrData = CurrData & 0x40;
       if (PreData == CurrData)
               Loop = FALSE;   //ready to exit the while loop
       PreData = CurrData;
//       WDT_CONTR = 0x34;
       TimeOut++;
     }
 }

/*================================================================
 * 函 数 名:  Program_One_Byte
 * 参    数:  SrcByte: 数据 hadr:地址16-18 Dst: 地址A0-A15 
 * 功能描述:
 *            往FLASH写入一个字节
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:26
===================================================================*/
void Program_One_Byte(unsigned char SrcByte,unsigned char hadr,unsigned int Dst)
{
   PAGE0;
   XBYTE[0x5555]=0xaa;
   XBYTE[0x2aaa]=0x55;
   XBYTE[0x5555]=0xa0;

   TurnChipAdr(hadr);

   XBYTE[Dst] = SrcByte;             // transfer the byte to destination
   Check_Toggle_Ready(Dst);    //wait for TOGGLE bit to get ready
}

/*================================================================
 * 函 数 名:  Erase_One_Sector
 * 参    数:  e_adr: 扇区地址 (39SF040:128,39SF020:64)
 * 功能描述:
 *            擦除一个扇区
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:22
===================================================================*/
int Erase_One_Sector(unsigned char e_adr)
{
        unsigned int  tmp;
        /*  Issue the Sector Erase command to 39VF040   */
        PAGE0;
        tmp=(e_adr%16)*0x1000;
        TurnChipAdr(e_adr/16);
        XBYTE[0x5555]=0xaa;
        XBYTE[0x2aaa]=0x55;
        XBYTE[0x5555]=0x80;
        XBYTE[0x5555]=0xaa;
        XBYTE[0x2aaa]=0x55;
        XBYTE[tmp] =0x30;                   /* write data 0x30 to the address       */

        Delay_10_Milli_Seconds();       /* check DATABOOK for the most  */
        Delay_10_Milli_Seconds();       /* check DATABOOK for the most  */
        Delay_10_Milli_Seconds();       /* check DATABOOK for the most  */
                                        /* accurate value -- Tse        */
}

/*================================================================
 * 函 数 名:  main
 * 参    数:  none
 * 功能描述:
 *            主函数
 * 返 回 值:  none
 * 作    者:  uCore
 * 修改日期:  2008-10-21 00:15
===================================================================*/
void main(void)
 {
   unsigned char sectors; 
   unsigned int raddr,waddr;
   unsigned char idata datbuf[128];
   unsigned char i,j;
   unsigned char pages;

   inichip();
   if(CHIP)                  //FLASH型号查询
     sectors = 64;           //256K,64扇区
     else
       sectors = 128;        //512K

   BUZ = 1;
   while(1)
     {
       STAR = 1;
       if(!STAR)            //启动
         {    
           ledon = 1;       //点亮LED,
           ledfls = 20;     //每秒开关一次
           SendPackageToCom(EraseChip,18);
           for(i=0; i<sectors; ++i)  //擦除
             {
               Erase_One_Sector(i);
               SendPackageToCom(Dot,1);
             }
           
           SendPackageToCom(StartProgrammer,21);
           pages = sectors/16;
           for(i=0; i<pages; ++i)                     //写入
             {
               raddr = 0;
               waddr = 0;
               do{
                   //read;
                   TurnChipAdr(i);
                   S_HZK;                       //选择源
                   j = 0;
                   while(j<128)                         //读128byte
                     {
                       datbuf[j] = XBYTE[raddr+j];
                       ++j;
                     }
                   raddr = raddr + 128;
                   
                   //write
                   S_SAV;                    //选中目标
                   j = 0;
                   while(j<128)                         //读128byte
                     {
                       Program_One_Byte(datbuf[j],i,waddr+j);
                       ++j;
                     }
                   waddr = waddr + 128;
                   if(raddr%4096==0)
                     SendPackageToCom(Dot,1);
                 }while(raddr != 0);
             }
           SendPackageToCom(VerifyChip,19);
           pages = sectors/16;
           for(i=0; i<pages; ++i)               //校验
             {
               raddr = 0;
               TurnChipAdr(i);
               do{
                   //read;
                   S_HZK;
                   j = 0;
                   while(j<128)                         //读128byte
                     {
                       datbuf[j] = XBYTE[raddr+j];
                       ++j;
                     }
                   
                   //write
                   S_SAV;
                   j = 0;
                   while(j<128)                         //读128byte
                     {
                       if(datbuf[j] != XBYTE[raddr+j])goto FAIL;           //校验失败,退出
                       ++j;
                     }
                   raddr = raddr + 128;
                   if(raddr%4096==0)
                     SendPackageToCom(Dot,1);
                 }while(raddr != 0);
             }
FAIL:
           if((i == pages) && (raddr == 0))               //成功
             {
               SendPackageToCom(ProSuc,22);               
               ledon = 0;                                  //关闭LED
             }
             else
               {
                 SendPackageToCom(ProFail,16);
                 ledfls = 10;                              //出错,LED闪烁速度加快
               }
         }
     }
 }

⌨️ 快捷键说明

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