|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
我现在用的nand flash是三星的K9K8G08U0A,通过单片机的GPIO口与之连接、进行控制,我想通过单片机直接对flash的全部地址进行擦除操作,但不成功,发现只擦除了一部分,大部分的内容没有被擦除,还有一个现象是每次擦除时失败的块数是一定的,即对每片8192个块擦除时反应的擦除失败的块数每次都是一样的,感觉好像是地址的问题,也不知道具体原因在哪里,请各位帮忙看一下代码,是否有什么错误,谢谢。
另外,如果谁有现成的代码,能否将有关擦除的部分发给我一份作为参考呢,再次谢谢!我的邮箱是 jyarmy@163.com
我的单片机的型号是Luminary的LM3S3749,共有60路GPIO,flash的控制信号(ALE,CLE,WE,RE,WP,R/B)、片选信号及8路IO全部连接到单片机的GPIO口上。
一共使用了8片K9K8G08U0A,控制信号和IO信号全部共用,8路片选分别接到MCU的GPIO E口上,从PE0到PE7;GPIO A的PA2接RE,PA3接WE,PA4接R/B,PA5接WP,PA6接CLE,PA7接ALE;GPIO D的PD0到PD7分别与IO0到IO7连接。下面是代码:
/*
写命令.
cmd_char : 命令字符
*/
void cmd_send(unsigned char cmd_char)
{
/*
0 1 1 x 0 1 0 0 = 0x64
ALE CLE WP# R/B WE# RE#
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 */
GPIOPinWrite(PA, Pin7 | Pin6 | Pin5 | Pin3 | Pin2 , 0x64); //CLE=1,ALE=0,准备写命令
GPIOPinWrite(PD, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 , cmd_char);// 把命令写入IO
SysCtlDelay(1);//may be
GPIOPinWrite(PA, Pin3, (1<<3));//拉高WE#
SysCtlDelay(1);
GPIOPinWrite(PA, Pin6, 0x0);//CLE置低
}
/*擦除一个block
ulAddr:32位的地址 其中A18~A30起作用 ; CEx=0,1,2...7 片先信号
成功返回0 失败返回1 */
unsigned char block_erase(unsigned long ulAddr, int CEx)
{
long result=0;
unsigned char ucAddr=( ulAddr >> 12 );//A12~A19
unsigned long pins[8]={ Pin0, Pin1, Pin2, Pin3, Pin4, Pin5, Pin6, Pin7 };
/* 初始化:
0 0 1 x 1 1 0 0 = 0x2C
ALE CLE WP# R/B WE# RE#
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 */
GPIOPinWrite(PA, Pin7 | Pin6 | Pin5 | Pin3 | Pin2 ,0x2C);
GPIOPinWrite(PE, pins[CEx] , 0x0); //拉低CE#
SysCtlDelay(3);
cmd_send(0x60);//发送0x60命令
// SysCtlDelay(1);
/* 写地址:
1 0 1 x 0 1 0 0 = 0xA4
ALE CLE WP# R/B WE# RE#
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 */
GPIOPinWrite(PA, Pin7 | Pin6 | Pin5 | Pin3 | Pin2 , 0xA4); //CLE=0,ALE=1,准备写地址
GPIOPinWrite(PD, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 , ucAddr); //A12~A19
SysCtlDelay(1);
GPIOPinWrite(PA, Pin3, (1<<3));//拉高WE#
SysCtlDelay(1);
GPIOPinWrite(PA, Pin3, (0<<3));//拉低WE#
SysCtlDelay(1);
ucAddr=(ulAddr >> 20);
GPIOPinWrite(PD, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 , ucAddr); //A20~A27
SysCtlDelay(1);
GPIOPinWrite(PA, Pin3, (1<<3));//拉高WE#
SysCtlDelay(1);
GPIOPinWrite(PA, Pin3, (0<<3));//拉低WE#
SysCtlDelay(1);
ucAddr=(ulAddr >> 28);
GPIOPinWrite(PD, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 , ucAddr); //A28~A30
SysCtlDelay(1);
GPIOPinWrite(PA, Pin3, (1<<3));//拉高WE#
SysCtlDelay(1);
cmd_send(0xD0);//写命令0xD0
SysCtlDelay(4);// 应大于TWB 6大约为120ns
// GPIOPinWrite(PA, Pin6, 0x0);//CLE置低
while( result!= 0x10) //读R/B , 等待其变为高电平
result=GPIOPinRead(PA,Pin4);
cmd_send(0x70);//发送0x70命令,准备读
SysCtlDelay(5);// 应大于TWHR==60ns
/* 准备读:
0 0 1 x 1 1 0 0 = 0x3C
ALE CLE WP# R/B WE# RE#
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 */
GPIOPinWrite(PA, Pin7 | Pin6 | Pin5 | Pin3 | Pin2 , 0x3C); //CLE=0,ALE=0
GPIOPinWrite(PA, Pin2, 0x0);// RE# 置低
GPIOPinTypeGPIOInput( PD, Pin0 ) ; //PD0即IO0 置为输入
if( 0x00==GPIOPinRead(PD,Pin0))
ucAddr=0;//擦除成功
else
ucAddr=1;//擦除失败
GPIOPinWrite(PA, Pin2, 0xFF);//RE# 置高
GPIOPinTypeGPIOOutput( PD, Pin0 ) ;// PD0置为输出
GPIOPinWrite(PE, pins[CEx] , 0xFF); //CE#置高
SysCtlDelay(5);
return ucAddr;
}
//将flash复位
//CEx=0,1,2...,7 表示片选信号
void flash_reset(int CEx)
{
unsigned long result=0;
/* 初始化:
0 0 1 x 1 1 0 0 = 0x2C
ALE CLE WP# R/B WE# RE#
PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 */
GPIOPinWrite(PA, Pin7 | Pin6 | Pin5 | Pin3 | Pin2 ,0x2C);
GPIOPinWrite(PE, (0x00000001 << CEx) , 0x0);
SysCtlDelay(3);
cmd_send(0xFF);//reset command
SysCtlDelay(3);
while( result!= 0x10) //读R/B , 等待其变为高电平
result=GPIOPinRead(PA,Pin4);
GPIOPinWrite(PE, (0x00000001 << CEx) , 0xFF);
SysCtlDelay(3);
}
// 对8片flash进行擦除
int main(void)
{
unsigned short i,j;
unsigned long block_addr;
unsigned char result;
int good, bad, totle;
//使能GPIO端口
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOD );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOE );
SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF );//control port PF4 PF5 PF6
//置相应GPIO端口为输入输出
GPIOPinTypeGPIOOutput( PA, Pin2 | Pin3 | Pin5 | Pin6 | Pin7 ); //PA2 3 4 5 6 7
GPIOPinTypeGPIOInput(PA, Pin4);//PA4为输入
GPIOPinTypeGPIOOutput( PE, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 ) ;// PE0~7 as CE#
GPIOPinTypeGPIOOutput( PD, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 ) ;// PD0~7 as I/O
GPIOPinTypeGPIOOutput( PF, Pin4 | Pin5 | Pin6 );//PF4 5 6
SysCtlDelay(8000000);
GPIOPinWrite(PE, Pin0 | Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7, 0xFF);//片选先全置高
for(j=0;j<8;j++){
block_addr=0x0;
good=0; bad=0;
flash_reset(j);
for(i=0;i<8192;i++){
result=block_erase( block_addr, j );
if(result==0)
good++;
else
bad++;
block_addr += 0x40000;
}
SysCtlDelay(2);
totle=good+bad;
}
} |
|