出来救救我啊,我在外部RAM调试的时候,ID,察除,写页,没有问题,读页的时候大多死在判忙处,程序飞到0X00000010处,偶尔可以成功一次。但是在内部RAM模式,没有问题。我的电路是直接挂在BANK3上的,读写信号直接相连,片选直接相连,P1。22管脚判忙,A0接CLE。A1接ALE。那位知道是什么原因?我先谢谢
#include <LPC22xx.H>
#include "config.h"
#include "NandFlashK9F2808_base.h"
////////////////宏定义
/*************** 设备命令*****************/
#define NAND_CMD_SEQIN 0x80
#define NAND_CMD_READ0 0x00
#define NAND_CMD_STATUS 0x70
#define NAND_CMD_ERASE1 0x60
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RDID 0x90
#define BLOCK_NUM 1024 // 整个NandFlash 1024块
/*********命令、地址、数据端口************/
#define NF_CMD_ADDR 0x83000001
#define NF_ADD_ADDR 0x83000002
#define NF_DAT_ADDR 0x83000000
#define PAGE_SIZE 512 // 一页512字节
#define NAND_CMD_PAGEPROG 0x10
/********* 读、写数据,写地址,忙等待**********/
#define NF_RD_DATA( ) (* (volatile UINT8 *)(NF_DAT_ADDR) )
#define NF_WR_CMD( cmd ) (*( (volatile UINT8 *)(NF_CMD_ADDR) ) = (UINT8)(cmd) )
#define NF_WR_ADDR( addr ) (*( (volatile UINT8 *)(NF_ADD_ADDR) )= (UINT8)(addr) )
#define NF_WR_DAT( dat ) (*( (volatile UINT8 *)(NF_DAT_ADDR) ) = (UINT8)(dat) )
#define NF_WAIT_BUSY( ) {IO1DIR |= ( 0x01<<22 );IO1SET |= ( 0x01<<22 );IO1DIR &= 0xFFBFFFFF; while( !(IO1PIN&(0x01<<22) ) ); }
void delly(void)
{unsigned int i;
for(i=0;i<5000;i++);
}
/***************************************************************
读NandFlash ID号,返回ID号
ID为:0xEC73
***************************************************************/
static UINT16 NF_GetID( void )
{
UINT16 id=4;
NF_WR_CMD(NAND_CMD_RDID);
while( id--);
id = NF_RD_DATA( )<<8;
id |= NF_RD_DATA( );
return id;
}
/****************************************************************
NandFlash端口初始化,检测ID是否正确
返回: NF_SUCCESS 初始化成功
NF_FAILURE 不成功
****************************************************************/
UINT8 NF_Init(void)
{
// PINSEL2 &= 0xFFFFFFCF; // P2.7~2.0为数据总线,P1.1为OE
// PINSEL2 |= 0x10100; // 使能WE、CS3
// IO2DIR = IO2DIR | (0x01<<18)&0xFFF7FFFF ; //RB input,WP output
if( NF_GetID( ) == 0xEC73 ) // 检测ID
return NF_SUCCESS;
else
return NF_FAILURE;
}
/**************************块擦除********************************
返回: 操作状态 !( nandstatus&1 )
1 操作成功
0 不成功
****************************************************************/
static UINT8 NF_EraseBlock( UINT16 blocknum ) // 单块擦除
{
UINT8 nandstatus ;
UINT16 pagenum;
pagenum = blocknum<<5;
IO2SET |= ( 0x01<<18 ); // WP = 1
NF_WR_CMD( NAND_CMD_ERASE1 ); //写入块檫除建立命令60
NF_WR_ADDR( pagenum&0xff ); //页地址
NF_WR_ADDR( (pagenum>>8)&0xff );
NF_WR_CMD( NAND_CMD_ERASE2 );
NF_WAIT_BUSY( );
IO2CLR |= (0x01<<18); // WP = 0
NF_WR_CMD( NAND_CMD_STATUS );
nandstatus = NF_RD_DATA( );
return !( nandstatus&1 );
}
/*************************写一页数据****************************
pagenum: 页号 buffer: 数据指针
注: 每次写512字节数据
****************************************************************/
static UINT8 WriteOnePage( UINT16 pagenum , UINT8 *buffer ) // 一页内写数据
{
UINT16 i;
UINT8 nandstatus;
// IO2SET |= ( 0x01<<18 ); // WP = 1
NF_WR_CMD(NAND_CMD_READ0);
NF_WR_CMD( NAND_CMD_SEQIN );
NF_WR_ADDR( 0x00 );
NF_WR_ADDR( pagenum & 0xff );
NF_WR_ADDR( (pagenum>>8) & 0xff );
for( i = 0; i <PAGE_SIZE; i++)
NF_WR_DAT( buffer[i] );
NF_WR_CMD( NAND_CMD_PAGEPROG );
NF_WAIT_BUSY( );
NF_WR_CMD( NAND_CMD_STATUS );
nandstatus = NF_RD_DATA( );
// IO2CLR |= (0x01<<18); // WP = 0
return !( nandstatus&1 ); // 返回1成功
}
/************************读一页数据*****************************
pagenum: 页号 buffer: 数据指针
注:每次读出512字节数据
****************************************************************/
static UINT8 ReadOnePage( UINT16 pagenum , UINT8 *buffer1 ) // 读一页数据
{
UINT16 num ;
NF_WR_CMD(NAND_CMD_READ0);
PINSEL2 = PINSEL2&0xFFFCFFFF; // P3.26 总线=>GPIO
IO3DIR |= (0x01<<24); // 输出
IO3CLR |= (0x01<<24); // low
NF_WR_CMD(NAND_CMD_READ0);
NF_WR_ADDR( 0x00 );
NF_WR_ADDR( pagenum & 0xff );
NF_WR_ADDR( (pagenum>>8) & 0xff );
NF_WAIT_BUSY( );
IO3SET |= (0x01<<24); // high
PINSEL2 |= (0x01<<16); // P3.26 CS1
for( num = 0; num<PAGE_SIZE; num++)
buffer1[num] = NF_RD_DATA( );
return NF_SUCCESS;
}
main (void)
{
unsigned char nand;
UINT32 i;
UINT8 array[512];
for(i=0;i<512;i++)
array[i]=0x00;
PINSEL2=PINSEL2&0x0f814914;
while(1) //闪灯循环
{
NF_Init(); //初始化,并读ID号
// nand=NF_EraseBlock(0); //单块檫除子程序32*10+10
// WriteOnePage(1,array);
ReadOnePage(1,array);
IODIR0=0xffffffff;
// PINSEL2 = PINSEL2&0xFFFCFFFF;
IOCLR0=0xffffffff;
delly();
IO0SET=0xffffffff;
delly();
}
} |