我使用的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;
} |