打印
[STM32]

stm32GPIO读写nandflash(K9F1G08U0B)

[复制链接]
1890|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
司空落星|  楼主 | 2014-2-17 10:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

我使用的STM32F103VBT6这款芯片,K9F1G08U0B和 STM32F103VBT6连接接口有如下对应关系:
ALE——PA1
WE——PA2  
WP——PA3
R\B——PC0
RE——PC1
CE——PC2
CLE——PC3

8位IO口对应PE0——PE7
下面4个函数,对应的是读取设备的ID,我在main函数里调用函数Nand_Flash_ReadDeviceID();
则会从串口打印出DeviceID = ec f1 0 95 40,这个设备ID号是正确的。问题在下面。
/***************************
写指令函数
***************************/
void Nand_FlashCommandLatch(uint8_t CommandTypes)
{

        Data_PortOutputMode();
        
        Flash_CE_Low;
        Flash_CLE_Low;
        Flash_ALE_Low;
        Flash_WE_High;
        Flash_CLE_High;
        Flash_WE_Low;
        Data_Output(CommandTypes);
        Flash_WE_High;        
        Flash_CLE_Low;
        Flash_ALE_High;
        Flash_CE_High;        
}
/****************************
设置地址函数
****************************/
void Nand_Flash_Write_Address(uint32_t Address)
{
        Data_PortOutputMode();

        Flash_CE_Low;                        
        Flash_CLE_Low;               
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_ALE_High;
        Flash_WE_Low;
        Data_Output((Address));
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_ALE_High;        
        Flash_WE_Low;
        Data_Output((Address >> 8) & 0x0f);
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_ALE_High;
        Flash_WE_Low;
        Data_Output((Address >> 12) & 0xFF);
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_ALE_High;
        Flash_WE_Low;
        Data_Output((Address >> 20) & 0xFF);
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_CE_High;        
}
/*******************************
用来读设备的ID
*******************************/
void Nand_FlashReadData(uint8_t *pBuffer,uint32_t rd_Length)
{
        uint32_t i = 0;
        Data_PortInputMode();
        Flash_CE_Low;
        while(rd_Length--)
        {
               
                Flash_RE_Low;
                *(pBuffer + i) = Data_Input;
                Flash_RE_High;
                i++;
        }
        Flash_RE_High;
        Flash_CE_High;

}
/*读设备ID函数*/
void Nand_Flash_ReadDeviceID(void)
{

        uint8_t array[5];
        Nand_FlashCommandLatch(0x90);
        Nand_Flash_Write_Address(0x00);
        Nand_FlashReadData(array,5);
        printf("DeviceID = %x %x %x %x %x\r\n",array[0],array[1],array[2],array[3],array[4]);        
}

下面的两个函数分别是向一页中写数据的函数和从一页中读出数据,我是对照K9F1G08U0D数据手册中Page Program Operation的时序和Read Operation的时序写的, 虽然我用的是K9F1G08U0B,但我觉得这两个应该时序上差别,我在main函数里面执行红色标记的代码,从串口打印出的数据如下:
Nand_FlashPage_Program is Error
Page 0 data:0xff 0x1e 0xf0 0x0 0x7 0x0 0xe0 0x0 0x7 0x18

而我写入的数据为 uint8_t arr[]="0123456789";

哪位大侠遇到过这样的问题,帮小弟解决一下,到底我的写错在哪里还是我的操作顺序有问题呢?



/****************************
向某一页中写数据
****************************/

bool Nand_FlashPage_Program(uint32_t PageNumber,uint8_t *string)
{
        uint8_t regvalue = 0;
        uint32_t i=2048,j=0;
        uint32_t Address = PageNumber*2048;
        uint8_t *pBuffer=string;
        Data_PortOutputMode();
        Flash_CE_Low;
        Flash_ALE_Low;
        Flash_RE_High;
        Flash_CLE_High;
        Flash_WE_Low;
        Data_Output(0x80);
        Flash_WE_High;
        Flash_CLE_Low;
        Flash_ALE_High;
        Flash_WE_Low;
        Data_Output((Address));
        Flash_WE_High;        
        Flash_WE_Low;
        Data_Output((Address >> 8) & 0x0F);
        Flash_WE_High;
        Flash_WE_Low;
        Data_Output((Address >> 12) & 0xFF);
        Flash_WE_High;
        Flash_WE_Low;
        Data_Output((Address >> 20) & 0xFF);
        Flash_WE_High;
        Flash_ALE_Low;

        while(i--)
        {
                Flash_WE_Low;
                Data_Output(*(pBuffer + j));
                Flash_WE_High;
                j++;
        }
        Flash_WE_Low;
        Flash_CLE_High;
        Data_Output(0x10);
        Flash_WE_High;
        Flash_Wait();
        Flash_WE_Low;
        Data_Output(0x70);
        Flash_WE_High;
        Flash_CLE_Low;
        Data_PortInputMode();
        Flash_RE_Low;
        regvalue = Data_Input;
        Flash_RE_High;
        if(!( (1 << 0) & regvalue))
        {

                return TRUE;
        }
        else
        {
                return         FALSE;
        }        
}
/*********************
从一页中读出数据
*********************/

void Nand_Flash_ReadOnePage(uint32_t sc_address,uint8_t *string)
{
        uint32_t Address = 2048*sc_address;
        uint32_t i=2048,j=0;
        uint8_t dat;
        Data_PortOutputMode();
        //Flash_CLE_Low;
        //Flash_CE_High;
        //Flash_WE_High;
        Flash_CE_Low;
        Flash_ALE_Low;
        Flash_RE_High;
        Flash_CLE_High;
        Flash_WE_Low;
        Data_Output(0x00);
        Flash_WE_Low;
        Flash_WE_High;
        Flash_CLE_Low;
        Flash_ALE_High;
        Flash_WE_Low;        
        Data_Output(Address);
        Flash_WE_High;        
        Flash_WE_Low;        
        Data_Output((Address >> 8) & 0x0F);
        Flash_WE_High;
        Flash_WE_Low;        
        Data_Output((Address >> 12) & 0xFF);
        Flash_WE_High;
        Flash_WE_Low;        
        Data_Output((Address >> 20) & 0xFF);
        Flash_WE_High;
        Flash_ALE_Low;
        Flash_CLE_High;
        Flash_WE_Low;        
        Data_Output(0x30);
        Flash_WE_High;
        Flash_CLE_Low;
        Flash_Wait();
        Data_PortInputMode();
        while(i--)
        {
                Flash_RE_Low;               
                *(string+j) = Data_Input;
                Flash_Delay(c_FlashDelayCnt);
                Flash_RE_High;
                Flash_Delay(c_FlashDelayCnt);
        }               
}


int main(void)
{
        uint8_t array[2112],i;
        bool Is_ok;
        Init_RCC();
        delay_init(64);                     //延时函数初始化         
        NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(115200);
        Nandflash_Init();

       Is_ok = Nand_FlashPage_Program(0x00,arr);
        if(Is_ok==TRUE)
                printf("Nand_FlashPage_Program is Successful\r\n");
        else
                printf("Nand_FlashPage_Program is Error\r\n");


        while(1)
        {
                        Nand_Flash_ReadOnePage(0x00,array);
                        printf("Page 0 data:");
                        for(i=0;i<10;i++)
                        {
                                printf("0x%x ",array);
                        }
                        printf("\r\n");
                        delay_ms(1000);
                           
        }
}

这是我的nandflash初始化函数
void Nandflash_Init()
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE, ENABLE);
        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;           
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);         
        GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;           
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);         
        GPIO_SetBits(GPIOC,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                                                                                                                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

        GPIOE->CRL = 0x33333333;
        Flash_WP_High;        
}

相关帖子

沙发
Hu.Te| | 2014-2-18 15:04 | 只看该作者
Mark一下

使用特权

评论回复
板凳
嵌入式云终端| | 2014-2-18 17:08 | 只看该作者
你这样贴程序,估计没有几个能耐心看的,百度搜索吧,帮顶

使用特权

评论回复
地板
Hu.Te| | 2014-2-26 10:20 | 只看该作者
本帖最后由 Hu.Te 于 2014-2-26 16:14 编辑

楼主没有回来了,希望楼主已经解决了相关的问题。
我不是软件开发人员,但感觉楼主可以再细化一下代码的...看起来是让人觉得有些头晕

........................

手册中有关Data Output中,指令集中强调了nRE指令是从上升沿到下降沿才有效的...
楼主的指令前是否需要模拟一下拉高的动作.

还有一个问题:
楼主能不能试试通过block erase的指令,试试看看,检查一下前几个block是否有坏点的。
按手册上所说的,第一0x00h地址应该是不需要的,但是楼主可以试试看看如何!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

21

帖子

0

粉丝