初级会员

- 积分
- 72
- 金钱
- 72
- 注册时间
- 2013-4-22
- 在线时间
- 10 小时
|
1金钱
在STM32F4上移植了原子哥的读写spi flash的程序,仅仅是把SPI1换到了SPI2 ,ID都能读正确,但是发现写数据的时候,总是会一次正常,一次不正常。初使化应该是没有什么问题的,时钟总线在其他初使化的时候已经打开了的,就没有在SPI2的初使化打开了。
buff2[0]=0x01;
buff2[1]=0x02;
buff2[2]=0x03;
buff2[3]=0x04;
buff2[4]=0x11;
buff2[5]=0x98;
buff2[6]=0x99;
buff2[7]=0xa0;
sSPI_Write_IncludeEra(buff2, 0x00,10);
sFLASH_ReadBuffer(buff1, 0x00,10);
for(i=0;i<10;i++)
{
printf("buff1[%d]=%x \n",i,buff1[i]);
}
在主程序里面调用了读和写打印出来,发现开机一次读出来都是0xff
ad:0x0,nb:0xA
buff1[0]=ff
buff1[1]=ff
buff1[2]=ff
buff1[3]=ff
buff1[4]=ff
buff1[5]=ff
buff1[6]=ff
buff1[7]=ff
buff1[8]=ff
buff1[9]=ff
如果再开一次,就是正常的
ad:0x0,nb:0xA
buff1[0]=1
buff1[1]=2
buff1[2]=3
buff1[3]=4
buff1[4]=11
buff1[5]=98
buff1[6]=99
buff1[7]=a0
buff1[8]=0
buff1[9]=0
感觉有点奇怪,为啥一开一关,正常一次,非正常一次。 我验证了下,如果去掉写,直接读的时候,都能正确读出flash里面的数据,那间接证明flash肯定是写出错了。
和硬件关系不大,因为每次都能正确读到id.
初使化和写函数如下:
void SPI2_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);
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(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
sFLASH_SendByte(0xff);//启动传输
}
u8 W25QXX_BUFFER[4096];
void sSPI_Write_IncludeEra(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
u8 * W25QXX_BUF;
W25QXX_BUF=W25QXX_BUFFER;
secpos=WriteAddr/4096;//扇区地址
secoff=WriteAddr%4096;//在扇区内的偏移
secremain=4096-secoff;//扇区剩余空间大小
printf("ad:0x%X,nb:0x%X\r\n",WriteAddr,NumByteToWrite);//测试用
if(NumByteToWrite<=secremain)
{secremain=NumByteToWrite;}//不大于4096个字节
while(1)
{
sFLASH_ReadBuffer(W25QXX_BUF,secpos*4096,4096);//读出整个扇区的内容
for(i=0;i<secremain;i++)//校验数据
{
if(W25QXX_BUF[secoff+i]!=0XFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
sFLASH_Erase_Sector(secpos);//擦除这个扇区
for(i=0;i<secremain;i++) //复制
{
W25QXX_BUF[i+secoff]=pBuffer[i];
}
sFLASH_WritePage(W25QXX_BUF,secpos*4096,4096);//写入整个扇区
}else sFLASH_WritePage(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.
if(NumByteToWrite==secremain){break;}//写入结束了
else//写入未结束
{
secpos++;//扇区地址增1
secoff=0;//偏移位置为0
pBuffer+=secremain; //指针偏移
WriteAddr+=secremain;//写地址偏移
NumByteToWrite-=secremain; //字节数递减
if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完
else secremain=NumByteToWrite; //下一个扇区可以写完了
}
};
}
|
|