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

📄 sst39vf160.c

📁 44B0+8019系统
💻 C
字号:
#include "..\inc\44b.h"

#include "sst39vf160.h"

#define __WR(addr,data)		*((unsigned short *)(addr<<1))=(unsigned short)data
#define __RD(addr)			*((unsigned short *)(addr<<1))	
#define __RESET()			__WR(0x0,0xf0f0)

//===在sst39vf160_s.s 中定义
extern void ___SST_EraseSector(unsigned int SectorNo);                  //Erase
extern void ___SST_Prog(unsigned int realAddr,unsigned short data);     //编程

//===
void __Sst_EraseSector(unsigned int SectorNo);
void __Sst_Prog(unsigned int realAddr,unsigned short data);
//============================================================
//擦除一个扇区,SectorNo是扇区号地址
//
//=============================================================
void __Sst_EraseSector(unsigned int SectorNo)
{
    unsigned short i;
    unsigned int sector = SectorNo << 12;
    ___SST_EraseSector(SectorNo);

	//判断是否擦除完成
	while(1)
	{
		i = *((volatile unsigned short *)sector)&0x40;
		if(i!=*((volatile  unsigned short *)sector)&0x40)	//D6 == D6
			continue;
		if(*((volatile  unsigned short *)sector)&0x80)	
			break;								//D7 == 1
	}

    //for( i = 0 ; i < 700000 ; i++ ); //delay 3ms

}


//===================================================
//编程一个16位的数据到Flash
//
//========================================================
void __Sst_Prog(unsigned int realAddr,unsigned short data)
{
    unsigned short i;

    ___SST_Prog( realAddr, data);       //调用汇编程序编程

	
	//判断是否编程完成
	while(1)
	{
		i = *(volatile unsigned short *)realAddr&0x40;
		if(i!=*(volatile unsigned short *)realAddr&0x40)		//D6 == D6
			continue;
		if((*(volatile unsigned short *)realAddr&0x80)==(data&0x80))	
			break;					//D7 == D7
	}
    //for( i = 0 ; i < 200 ; i++ ); //delay 7us
}


//=================
unsigned int __SST_SAVErNCACHBE1;
//禁止0000000到02000000地址的数据进入CACHE
void Sst_Start()
{
    __SST_SAVErNCACHBE1 = rNCACHBE1;
    rNCACHBE1 = ( 0x00000000 >> 12 ) | ( (0x02000000 >> 12 ) << 16 );    
}
//还原rNCACHBE1的数据
void Sst_End()
{
    rNCACHBE1 = __SST_SAVErNCACHBE1;
}

//===================================================
//连续编程
//
//========================================================
unsigned int Sst_Program(unsigned int Addr , unsigned short *pBuf , unsigned int Length)
{
    unsigned int howWrite = 0;
    unsigned short *pPAddr,*pData;

    Addr = Addr & 0x1FFFFE;
    
    /*编程*/
    pPAddr = (unsigned short*)Addr;
    pData = pBuf;

    while( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) )
    {
        __Sst_Prog( (unsigned int)pPAddr, *pData );      ///编程一个字节
        pPAddr++;
        pData++;
        howWrite++;
    }

    /*校验*/
    pPAddr = (unsigned short*)Addr;
    pData = pBuf;
    howWrite = 0;

    while( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) && ( (*pPAddr) == (*pData) ) )
    {
        pPAddr++;
        pData++;
        howWrite++;
    }

   if( (howWrite < Length) && ( (unsigned int)pPAddr < 0x00200000) ) return 0;  ///校验不正确时返回0
   
   return 1;
}

//======================================================================
//擦除扇区,每个扇区为2048个字节,但因29F160是16位的,即每个扇区为1024个
//
//如下载英文字库到00F0000~00F0FFF,则SSectors=00F0, ESectors=00F0,
//=============================================-=======================
unsigned short __SST_DATABUF[2048];
unsigned int Sst_Erase(unsigned int SAddr,unsigned int EAddr)
{
    unsigned int i,j,S,E;
    unsigned short *pBuf,*pSsec;
    unsigned int SSectors,ESectors; //开始、结束扇区
    
    SAddr = SAddr & 0x1FFFFE;
    EAddr = EAddr & 0x1FFFFE;

    //开始结束地址出错
    if( EAddr < SAddr ) return 0;

    /*计算起始、结束扇区*/
    SSectors = SAddr >> 12;
    ESectors = EAddr >> 12;


    if( SSectors == ESectors )   //只有1扇区
    {
        //擦除开始扇区
        pBuf = (unsigned short*)(SSectors << 12);
        pSsec = __SST_DATABUF;                   //数组

		
        for( i = 0 ; i < 2048 ; i++ )
        {
            *pSsec++ = *pBuf++;                 //读出将要擦除的全部数据到__SST_DATABUF数组
        }
       
        S = (SAddr >> 1) & 0x07FF;             //字节地址转为半字地址
        E = (EAddr >> 1) & 0x07FF;
        for( i = S ; i <= E ; i++ )
        {
            __SST_DATABUF[i] = 0xFFFF;         //写入数据0FFFF到__SST_DATABUF数组里
        }
        
        __Sst_EraseSector(SSectors);          //擦除扇区SSectors

        return Sst_Program( SSectors << 12 , __SST_DATABUF , 2048);      //将__SST_DATABUF数组编程到FLASH
        return 1;
    }else //多扇区
    {
        //擦除开始扇区
        pBuf = (unsigned short*)(SSectors << 12);
        pSsec = __SST_DATABUF;

        for( i = 0 ; i < 2048 ; i++ )
        {
            *pSsec++ = *pBuf++;
        }

        S = (SAddr >> 1) & 0x07FF;
        E = 0x07FF;
        for( i = S ; i <= E ; i++ )
        {
            __SST_DATABUF[i] = 0xFFFF;
        }

        __Sst_EraseSector(SSectors);
        Sst_Program( SSectors << 12 , __SST_DATABUF , 2048);

        //擦除结束扇区
        pBuf = (unsigned short*)(ESectors << 12);
        pSsec = __SST_DATABUF;

        for( i = 0 ; i < 2048 ; i++ )
        {
            *pSsec++ = *pBuf++;
        }

        S = 0;
        E = (EAddr >> 1) & 0x07FF;
        for( i = S ; i <= E ; i++ )
        {
            __SST_DATABUF[i] = 0xFFFF;
        }

        __Sst_EraseSector(ESectors);

        //擦除中间扇区(一个或多个)
        for( i = SSectors + 1 ; i < ESectors ; i++ )
        {
            __Sst_EraseSector(i);
            //for( j - 0 ; j < 200000 ; j++ );
        }

        //校验是否擦除成功
        pBuf = (unsigned short*)SAddr;
        //for( j - 0 ; j < 600000; j++ );
        while( (unsigned int)pBuf <= EAddr )
        {
            if( *pBuf != 0xFFFF ) return 0;
            pBuf++;
        }

    }
    
    return 1;    
}

		

⌨️ 快捷键说明

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