这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » LPC2210,flash 关于LPC2210的flash操作?奇怪,请周立功高

共2条 1/1 1 跳转至

LPC2210,flash 关于LPC2210的flash操作?奇怪,请周立功高手回答一下!

院士
2006-09-17 18:14:16     打赏
LPC2210,flash 关于LPC2210的flash操作?奇怪,请周立功高手回答一下!



关键词: LPC2210     flash     关于     操作     奇怪     请周    

院士
2006-12-22 22:43:00     打赏
2楼
ARM2200开发板中,flash的地址线A0~A17分别连接到LPC2210的A1~A18,那么实际上从CPU发出读写地址时要把地址左移一位才行吧,例如:

  flash地址   cpu发送的读写地址          (假设基址设在0x81000000)
   0x0000        0x81000000
   0x0001        0x81000002
   0x0002        0x81000004

  那么这样cpu的外部bank1(0x81000000)地址岂不不连续了?实际应该应该不是这样啊,我哪里理解错了呢?

  但是ARM2200远程序写flash和擦除flash又确实显示地左移了一位啊,程序如下:

#define  FLASH_ADDR    0x81000000
#define  GetAddr(addr)    (volatile uint16  *)(FLASH_ADDR|(addr<<1))  //这个宏负责左移
uint8  ChipErase(void)
{  volatile uint16  *ip;
   uint16  temp1,temp2;

   ip = GetAddr(0x5555);
   ip[0] = 0xaaaa;            // 第一个写周期,地址0x5555,数据0xAA
   ip = GetAddr(0x2aaa);
   ip[0] = 0x5555;            // 第二个写周期,地址0x2aaa,数据0x55
   ip = GetAddr(0x5555);
   ip[0] = 0x8080;            // 第三个写周期,地址0x5555,数据0x80
   ip = GetAddr(0x5555);
   ip[0] = 0xaaaa;            // 第四个写周期,地址0x5555,数据0xAA
   ip = GetAddr(0x2aaa);
   ip[0] = 0x5555;            // 第五个写周期,地址0x2aaa,数据0x55
   ip = GetAddr(0x5555);
   ip[0] = 0x1010;            // 第六个写周期,地址0x5555,数据0x10

   while (1)                // 等待操作完成 (若擦除操作没有完成,每次读操作DQ6会跳变)
   {  temp1 = *ip;
      temp2 = *ip;
      if (temp1 == temp2)
      {  if (temp1 != 0xffff)
         {  return(FALSE);
         }
         else
         {  return(TRUE);
         }
      }
   }
   return(TRUE);
}

还有一个疑问就是关于扇区擦除:
   如果地址确实需要左移一位,那么扇区擦除的地址也应该左移一位啊,flash扇区地址为A12~A17,那对应的cpu地址应该在A13~A18啊,可是我试过了,实际的擦除地址仍然对应cpu地址应该在A12~A17,这就奇怪了,为什么这时候又不用左移一位了呢? 1: re1.EasyARM2200开发板的外部Ram和Flash都是16位的。故访问外部Ram和Flash时候,地址线A0是没有用的。
2.擦写Flash时,如果要读取Flash的物理地址0x5555上的数据,那么ARM外部存储器总线上就得送出FLASH_ADDR|(0x5555<<1)的地址信号,这样flash扇区地址A0~A18上才会出现0x5555的地址信号。 2: 麻烦再详细一下,看我下面的理解到底错在哪了?请zlg高手帮忙!是这样的啊,我也是这样理解的啊。

一句话总结就是:
       flash上的地址线A0~A17最终对应LPC2210的地址线A1~A18。

如果正常操作都要左移的话,我就能理解,但为什么下面情况没有左移:

   1、写flash
uint8  WordProgram(uint32 Addr, uint16 Data)
{  volatile uint16  *ip;
   uint16  temp1,temp2;

   ip = GetAddr(0x5555);    // 转换地址0x5555
   *ip = 0xaaaa;            // 第一个写周期,地址0x5555,数据0xAA
   ip = GetAddr(0x2aaa);
   *ip = 0x5555;            // 第二个写周期,地址0x2aaa,数据0x55
   ip = GetAddr(0x5555);
   *ip = 0xa0a0;            // 第三个写周期,地址0x5555,数据0xA0
   ip = (volatile uint16  *)(FLASH_ADDR_BASE|Addr);
   *ip = Data;                // 第四个写周期,地址Addr,数据Data
   
   while (1)                // 等待操作完成 (若编程操作没有完成,每次读操作DQ6会跳变)
   {  temp1 = *ip;            
      temp2 = *ip;
      if (temp1 == temp2)
      {  if (temp1 != Data)
         {  return(FALSE);
         }
         else
         {  return(TRUE);
         }
      }
   }
   
   return(TRUE);
}

注意上面第四个写周期没有用GetAddr宏,这个宏会把flash的写地址左移一位。
但这一条没有左移:ip = (volatile uint16  *)(FLASH_ADDR_BASE|Addr);
但写入flash写入的数据是正确的,如果把这个地址左移了写入flash的数据反而是错误的。Addr就是flash的实际地址,是字对齐的。

  2、起始读flash的操作也没有左移地址,如:
*(uint16 *0x80000002)实际读到的就是0x80000002的flash内容,而按照上面说的左移一位,读0x80000002处的flashLPC2210上的地址应该是0x80000004啊。

  3、扇区擦除时,扇区号出现在sst39sf160的地址线A12~A17,而实际从LPC2210输出的地址中,sst39sf160的扇区号也出现在A12~A17,按照前面说的应该左移一位出现在A13~A18才对啊。 3: re请大侠再漏一次面啊?
这个问题我实在是想不通,帮帮忙! 4: re你的程序在调用函数WordProgram(uint32 Addr, uint16 Data)对Flash操作的时候,Addr是已经是偶数地址了(所以A0实际上是没有用的),如果你再对Addr进行左移一位,那么就写到其他地址上去了。
5: re还是不能明白,烦请版主详细点。

尤其是扇区擦除时,扇区号应该出现在sst39sf160的地址线A12~A17,而按照实际电路图的接法,从LCP2210出来的flash扇区的地址线应该左移一位,即在LPC的地址线A13~A18才对。

可我实际写程序的时候发现flash扇区号的地址也要出现在LPC2210的A12~A18扇区擦除才正常。

到底是什么地方出了问题?

请版主详细讲讲。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]