得技通电子单片机编程器
 

编程器

|

 

编程器驱动

|

 

pic单片机

|

 

烧录器

|

 

ARM

|

 

yamaichi

|

 

TI

|

 

BGA

|

 

SOT

|

 

nand flash

 

仿真器

|

 

编程器软件

|

 

avr单片机

|

 

适配器

|

 

DSP

|

 

enplas

|

 

aries

|

 

QFP

|

 

CSP

|

 

nor flash

 

测试座

|

 

ARM仿真器

|

 

51单片机

|

 

老化座

|

 

keil

|

 

wells-cti

|

 

meritec

|

 

QFN

|

 

PGA

|

 

superpro

 

单片机

|

 

51仿真器

|

 

单片机学习

|

 

IC插座

|

 

Socket

|

 

3m textool

|

 

TSOP

|

 

SOP

|

 

MLF

|

 

HI-LO

 

开发板

|

 

单片机编程器

|

 

单片机组成

|

 

80C51

|

 

Adapter

|

 

plastronics

|

 

PLCC

|

 

DIP

|

 

ssop

|

 

NEC

设为首页  加入收藏

热线电话

0755-61361222

0755-83681644

0755-83681447

 首页 | 公司简介 | 新闻中心 | 产品中心 | 最近更新 | 编程器软件下载 | 编程器驱动下载 | 联系我们 | 解决方案 | 留言板 | 推荐商品 | 下载资料 | 【站内资料搜索】 
 您当前的位置: 首页>>编程器>>NOR Flash编程
Flash烧录器/编程器
 
 

NOR Flash编程

        Nor Flash与Nand flash的不同之处在于Nor Flash的地址和数据线是不共用的,所以Nor Flash比较象ROM,是可以按地址自由读的,这样就非常适合存储代码,在开机时从Nor Flash中取代码来执行。在我的板子上有16M的Intel的Nor Flash E28F128J3A150,以此为例来研究一下Nor Flash的一些常用操作。E28F128J3A150每个sector是128k,擦除是按扇区操作了。

        首先来看下E28F128J3A150与s3c2410的接口吧。
        一般情况下ROM与s3c2410的接口我们可以在s3c2410的手册上看到,如下图所示

         仔细看下16位和8位数据接口在地址线连接上的区别吧,16位的地址线是要移位的,A1接到A0上,这当然是比较容易理解的,位宽大了一倍,地址就少了一条。对于E28F128J3A150其实也是这样,不过又有点不一样,仔细看看E28F128J3A150的手册吧。下面给出接线图。

    不同之处E 28F 128J 3A 150貌似并没有移位,其实只是因为E 28F 128J 3A 150A1就相对于别的16ROMA0,其A0就相当于他们的A(-1)是用来指示8位地址的,所以还是一样的。

来看看Flash操作的命令集吧

以几个比较重要的操作来说明比较容易懂

首先就是Read Identifier Codes

先给定我们的flash开始的地址吧,flash_addr=ioremap(0x0,0x1000000);

物理地址从0x0开始的0x1000000( 16M )地址空间,这样得到了可访问的虚拟地址flash_addr

很简单,看命令表,先写一个命令      writew(0x90,flash_addr);

然后把Manufacture Code读回来              readw(flash_addr);

接着再读Device Code                       readw(flash_addr+2);

细节部分还是参考手册吧

其实内核已经MTD驱动完全支持Nor Flash的操作,所以不必要自己再写了。

不过在JTAG烧写flash的程序中可以加入对我们自己的flash的支持。

来看看其中对E 28F 128J 3A 150的烧写代码,分析一下。

int Strata_CheckID(int targetAddr)             //返回Manufacture Code

{

    _WR(targetAddr, 0x0090);   

    return _RD(targetAddr);                      //_WR和_RD都是半字操作

}

int Strata_CheckDevice(int targetAddr)       //返回Device Code

{

    _WR(targetAddr, 0x0090);

    return _RD(targetAddr+0x2);

}

看着Block Erase Flowchart再对照着Block Erase的函数看就比较能完全看懂了

void Strata_EraseSector(int targetAddress)

{

    unsigned long ReadStatus;

    unsigned long bSR5;

    unsigned long bSR7;

    _WR(targetAddress, 0x0020);      //擦除命令first cycle

    _WR(targetAddress, 0x00d0);    //擦除命令second cycle

    _WR(targetAddress, 0x0070);      //读状态寄存器命令

    ReadStatus=_RD(targetAddress);  //读状态寄存器

bSR7=ReadStatus & (1<<7);

while(!bSR7 )       //需要判断状态寄存器的第7位

    {

        _WR(targetAddress, 0x0070);

        ReadStatus=_RD(targetAddress);

        bSR7=ReadStatus & (1<<7);

    }

    _WR(targetAddress, 0x0070);

    ReadStatus=_RD(targetAddress); 

bSR5=ReadStatus & (1<<5);          

if (bSR5==0)

    {

        printf("Block @%xh Erase O.K. \n",targetAddress);

    }

    else

    {

        _WR(targetAddress, 0x0050);      //// Clear Status Register

        error_erase=1;  

    }

_RESET();  //就相当于_WR(targetAddress, 0x00ff),回到Read Array的状态。

}

很清晰的流程吧。

Byte/Word Program Flowchart

 

共两种Program方式可以把数据写到Flash中,一般也只用到这种就可以了

int Strata_ProgFlash(U32 realAddr,U16 data)

{

    unsigned long ReadStatus;

    unsigned long bSR4; 

    unsigned long bSR7;   

    _WR(realAddr, 0x0040);

    _WR(realAddr, data);

    _WR(realAddr, 0x0070);

    ReadStatus=_RD(realAddr);

    bSR7=ReadStatus & (1<<7);

    while(!bSR7)

    {

        _WR(realAddr, 0x0070);

        ReadStatus=_RD(realAddr);

        bSR7=ReadStatus & (1<<7);

    }

    _WR(realAddr, 0x0070);

    ReadStatus=_RD(realAddr);

    bSR4=ReadStatus & (1<<4);

    if (bSR4==0)

    {

        //printf("Successful Program!!\n");

    }

    else

    {

        _WR(realAddr, 0x0050);      // Clear Status Register

        error_program=1;        

    }

    _RESET();

    return 0;

}

以上这种写会很慢,以致于JTAG烧写相当得慢。

 

int Strata_unprotect_sector(int targetAddr)         //去除sector的写保护
{
   int SR7,SR3,SR4,SR5,ReadStatus;
   int res=0;
   _WR(targetAddr,0x0050); //Clear Status Register
   _WR(targetAddr,0x0060); //First bus cycle
   _WR(targetAddr,0x00D0); //Second bus cycle
   _WR(targetAddr,0x0070);
   ReadStatus=_RD(targetAddr);
   SR7=ReadStatus & (1<<7);
   while(!SR7)
   {
     _WR(targetAddr,0x0070);
     ReadStatus=_RD(targetAddr);
     SR7=ReadStatus & (1<<7);
   }                                                                       
     _WR(targetAddr,0x0070);
     ReadStatus=_RD(targetAddr);
     SR3=ReadStatus & (1<<3);
     SR4=ReadStatus & (1<<4);
     SR5=ReadStatus & (1<<5);
     if(SR3) {printf("Voltage Range Error"); res=-1;}
     if(SR4 && SR5) {printf("Command Sequence Error"); res=-2;}
     if(SR5) {printf("Clear Block Lock-Bits Error"); res=-3;}
     _RESET();
     return res;
}

另外按照write to buffer的流程自己写了一个函数,没有test,不想再去烧写了,太烦了,就这样好了。

void Strata_buffer_program(int blockAddress,int tagetAddress,U16* buf)

{

    unsigned long ReadStatus;

    unsigned long bSR4;    

    unsigned long bSR7;

    int i;

       do {

              _WR(blockAddress, 0x00E8);

        _WR(blockAddress, 0x0070);

        ReadStatus=_RD(blockAddress);

        bSR7=ReadStatus & (1<<7);

       } while(!bSR7);

    _WR(blockAddress, 0x 001F );

       for(i=0;i<=0x 1F ;i++)

              _WR(targetAddress+2*i, *(buf+i));

       _WR(blockAddress, 0x00D0);

       do {

        _WR(blockAddress, 0x0070);

        ReadStatus=_RD(blockAddress);

        bSR7=ReadStatus & (1<<7);

       } while(!bSR7);

    _WR(blockAddress, 0x0070);

    ReadStatus=_RD(blockAddress); 

    bSR4=ReadStatus & (1<<4); 

    if (bSR4==0)

    {

        //printf("Successful Program!!\n");

    }

    else

    {

        _WR(blockAddress, 0x0050);

        error_program=1;

    }

    _RESET(); 

}

↑Top

 

Copyright (c) 2007 www.8051faq.com.cn Inc. All Rights Reserved.
深圳得技通电子有限公司 版权所有
ADD:深圳市深南中路赛格广场37楼3703室 TEL: 0755-61361234 E-mail:sale7-djt@aaa.cn
粤ICP备09055445号-2