本帖最后由 wankle 于 2010-9-9 13:49 编辑
STM32F103VCT6用复用地址方式接nor flashsst39vf1601,片选用的是io,读id正确,但是写数据再返读就有对有错。写0x3210读出来有的是FFFF 有的是7EFF,有的是3210。设置如下clock的时间怎么调整都差不多。望高手指点一下!
void NOR_Init(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
GPIO_InitTypeDef GPIO_InitStructure;
/*!< Configure PD6 for NOR memory Ready/Busy signal */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/*!< Configure PD2 for NOR memory CS signal */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/*-- FSMC Configuration ----------------------------------------------------*/
p.FSMC_AddressSetupTime = 0x02;
p.FSMC_AddressHoldTime = 0x05;
p.FSMC_DataSetupTime = 0x0b;
p.FSMC_BusTurnAroundDuration = 0x00;
p.FSMC_CLKDivision = 0x02;
p.FSMC_DataLatency = 0x05;
p.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/*!< Enable FSMC Bank1_NOR Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
}
/**
* @brief Reads NOR memory's Manufacturer and Device Code.
* @param NOR_ID: pointer to a NOR_IDTypeDef structure which will hold the
* Manufacturer and Device Code.
* @retval None
*/
void NOR_ReadID(NOR_IDTypeDef* NOR_ID)
{
NORCS_EN();
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x0090);
NOR_ID->Manufacturer_Code = *(__IO uint16_t *) ADDR_SHIFT(0x0000);
NOR_ID->Device_Code1 = *(__IO uint16_t *) ADDR_SHIFT(0x0001);
NOR_ID->Device_Code2 = *(__IO uint16_t *) ADDR_SHIFT(0x000E);
NOR_ID->Device_Code3 = *(__IO uint16_t *) ADDR_SHIFT(0x000F);
NORCS_DIS();
}
/**
* @brief Erases the specified Nor memory sector 2K.
* @param SectorAddr: address of the sector to erase.
* @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
* or NOR_TIMEOUT
*/
NOR_Status NOR_EraseSector(uint32_t SectorAddr)
{
NOR_Status status;
NORCS_EN();
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x0080);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE((Bank1_NOR2_ADDR + SectorAddr), 0x30);
DelayMs(30);
status=NOR_GetStatus(SectorErase_Timeout);
NORCS_DIS();
return status;
}
/**
* @brief Erases the entire chip.
* @param None
* @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
* or NOR_TIMEOUT
*/
NOR_Status NOR_EraseChip(void)
{
NOR_Status status;
NORCS_EN();
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x0080);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x0010);
DelayMs(50);
status=NOR_GetStatus(SectorErase_Timeout);
NORCS_DIS();
return status;
}
/**
* @brief Writes a half-word to the NOR memory.
* @param WriteAddr: NOR memory internal address to write to.
* @param Data: Data to write.
* @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
* or NOR_TIMEOUT
*/
NOR_Status NOR_WriteHalfWord(uint32_t WriteAddr, uint16_t Data)
{
NOR_Status status;
NORCS_EN();
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00AA);
NOR_WRITE(ADDR_SHIFT(EVENADDR), 0x0055);
NOR_WRITE(ADDR_SHIFT(ODDADDR), 0x00A0);
NOR_WRITE((Bank1_NOR2_ADDR + WriteAddr), Data);
status=NOR_GetStatus(SectorErase_Timeout);
NORCS_DIS();
return status;
}
/**
* @brief Writes a half-word buffer to the FSMC NOR memory.
* @param pBuffer: pointer to buffer.
* @param WriteAddr: NOR memory internal address from which the data will be
* written.
* @param NumHalfwordToWrite: number of Half words to write.
* @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
* or NOR_TIMEOUT
*/
NOR_Status NOR_WriteBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)
{
NOR_Status status = NOR_ONGOING;
do
{
/*!< Transfer data to the memory */
status = NOR_WriteHalfWord(WriteAddr, *pBuffer++);
WriteAddr = WriteAddr + 2;
NumHalfwordToWrite--;
}
while((status == NOR_SUCCESS) && (NumHalfwordToWrite != 0));
return (status);
}
下面在主程序中
NOR_Init();
/* Read NOR memory ID */
NOR_ReadID(&NOR_ID);
NOR_ReturnToReadMode();
/* Erase the NOR memory Sector to write on */
NOR_EraseSector(WRITE_READ_ADDR);
for(Count=0;Count<0x400;Count++)
{
TxBuffer[Count]=0x3210;
}
/* Write data to FSMC NOR memory */
NOR_WriteBuffer(TxBuffer, WRITE_READ_ADDR, BUFFER_SIZE);
/* Read data from FSMC NOR memory */
NOR_ReadBuffer(RxBuffer, WRITE_READ_ADDR, BUFFER_SIZE); |