用STM32写AT45DB161时有部分空间写不进去。

nihongsheng 2017-09-04 10:55:10
我一个项目上需要写AT45DB161。驱动采用的是红牛板上的驱动,发现有的空间写进去,读出来正确,有的空间写过后读出来是00,具体情况如下:
驱动部分:
/* Private typedef -----------------------------------------------------------*/
#define SPI_FLASH_PageSize 0x210

/* Private define ------------------------------------------------------------*/
#define READ 0xD2 /* Read from Memory instruction */
#define WRITE 0x82 /* Write to Memory instruction */

#define RDID 0x9F /* Read identification */
#define RDSR 0xD7 /* Read Status Register instruction */

#define SE 0x7C /* Sector Erase instruction */
#define PE 0x81 /* Page Erase instruction */

#define RDY_Flag 0x80 /* Ready/busy(1/0) status flag */

#define Dummy_Byte 0xA5

void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* Enable SPI1 and GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIO_CS, ENABLE);

/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure I/O for Flash Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_CS, &GPIO_InitStructure);

/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();

/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}

void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();
/* Send "Write to Memory " instruction */
SPI_FLASH_SendByte(WRITE);
/* Send WriteAddr high nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
/* Send WriteAddr medium nibble address byte to write to */
SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
/* Send WriteAddr low nibble address byte to write to */
SPI_FLASH_SendByte(WriteAddr & 0xFF);

/* while there is data to be written on the FLASH */
while (NumByteToWrite--)
{
/* Send the current byte */
SPI_FLASH_SendByte(*pBuffer);
/* Point on the next byte to be written */
pBuffer++;
}

/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();

/* Wait the end of Flash writing */
SPI_FLASH_WaitForEnd();
}

void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteStartAddressOnOnePage, uint16_t NumByteToWrite)
{
//uint8_t ByteWritePages = 0, ByteWriteleftOnOnepage = 0, StartAddressOnOnePage = 0, StartLeftBytesOnOnePage = 0, temp = 0; 原程序如此,估计有错,溢出
uint16_t ByteWritePages = 0, ByteWriteleftOnOnepage = 0, StartAddressOnOnePage = 0, StartLeftBytesOnOnePage = 0, temp = 0;

StartAddressOnOnePage= WriteStartAddressOnOnePage % SPI_FLASH_PageSize;
StartLeftBytesOnOnePage = SPI_FLASH_PageSize - StartAddressOnOnePage;
ByteWritePages = NumByteToWrite / SPI_FLASH_PageSize;
ByteWriteleftOnOnepage = NumByteToWrite % SPI_FLASH_PageSize;

if (StartAddressOnOnePage == 0) /* WriteStartAddressOnOnePage is SPI_FLASH_PageSize aligned */
{
if (ByteWritePages == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
{
SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, NumByteToWrite);
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
while (ByteWritePages--)
{
SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, SPI_FLASH_PageSize);
WriteStartAddressOnOnePage += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}

SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, ByteWriteleftOnOnepage);
}
}
else /* WriteStartAddressOnOnePage is not SPI_FLASH_PageSize aligned */
{
if (ByteWritePages == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
{
if (ByteWriteleftOnOnepage > StartLeftBytesOnOnePage) /* (NumByteToWrite + WriteStartAddressOnOnePage) > SPI_FLASH_PageSize */
{
temp = ByteWriteleftOnOnepage - StartLeftBytesOnOnePage;

SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, StartLeftBytesOnOnePage);
WriteStartAddressOnOnePage += StartLeftBytesOnOnePage;
pBuffer += StartLeftBytesOnOnePage;

SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, temp);
}
else
{
SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, NumByteToWrite); /////
}
}
else /* NumByteToWrite > SPI_FLASH_PageSize */
{
NumByteToWrite -= StartLeftBytesOnOnePage;
ByteWritePages = NumByteToWrite / SPI_FLASH_PageSize;
ByteWriteleftOnOnepage = NumByteToWrite % SPI_FLASH_PageSize;

SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, StartLeftBytesOnOnePage);
WriteStartAddressOnOnePage += StartLeftBytesOnOnePage;
pBuffer += StartLeftBytesOnOnePage;

while (ByteWritePages--)
{
SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, SPI_FLASH_PageSize);
WriteStartAddressOnOnePage += SPI_FLASH_PageSize;
pBuffer += SPI_FLASH_PageSize;
}

if (ByteWriteleftOnOnepage != 0)
{
SPI_FLASH_PageWrite(pBuffer, WriteStartAddressOnOnePage, ByteWriteleftOnOnepage);
}
}
}
}

void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
/* Select the FLASH: Chip Select low */
SPI_FLASH_CS_LOW();

/* Send "Read from Memory " instruction */
SPI_FLASH_SendByte(READ);

/* Send ReadAddr high nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
/* Send ReadAddr medium nibble address byte to read from */
SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
/* Send ReadAddr low nibble address byte to read from */
SPI_FLASH_SendByte(ReadAddr & 0xFF);

/* Read a byte from the FLASH */
SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
SPI_FLASH_SendByte(Dummy_Byte);
/* Read a byte from the FLASH */
SPI_FLASH_SendByte(Dummy_Byte);

while (NumByteToRead--) /* while there is data to be read */
{
/* Read a byte from the FLASH */
*pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
/* Point to the next location where the byte read will be saved */
pBuffer++;
}

/* Deselect the FLASH: Chip Select high */
SPI_FLASH_CS_HIGH();
}

注:在SPI_FLASH_BufferWrite函数里,变量声明原为uint8_t 我改为uint16_t
因为页为0-4096,不应该声明为unsigned char.估计有错溢出。故改为int16_t

在主函数里,是这样写的
U16 addr;
U8 save_data8bit[8]={0x99,0x44,0x33,0x44,0x55,0x66,0x77,0x88};

addr = 200 + Store_Pointer*31*2;
SPI_FLASH_BufferWrite(save_data8bit,addr,2);
OSTimeDly(500);
memset(save_data8bit,0x00,100);
SPI_FLASH_BufferRead(save_data8bit,addr,2);

试验中发现
当store_pointer有些空间写入后读出是正确的,有些空间写入后读出是0(不能肯定一定是写入错)
如下:
store_pointer=0->5,正确
store_pointer=6->13,错误
store_pointer=14->21,正确
store_pointer=22->28,错误
store_pointer=29->38,正确
store_pointer=39->45,错误

因为读写仅二个字节,不存在跨页问题。
芯片也换了几个,故障依旧。
感觉到是偶数页面写得进去,奇数页面写不进去。

怎么也查不出是什么问题,切望各位大神指点。谢谢谢
...全文
330 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_28665111 2019-07-30
  • 打赏
  • 举报
回复
可以讲讲具体是哪里问题吗 我也遇到奇数页读写错误的问题
nihongsheng 2018-05-15
  • 打赏
  • 举报
回复
问题已解决,这个驱动程序有错误。改正后就正常了

27,373

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧