OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3297|回复: 1

STM32F4 写GD25Q32不稳定问题

[复制链接]

3

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2013-4-22
在线时间
10 小时
发表于 2019-8-23 01:27:05 | 显示全部楼层 |阅读模式
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;                        //下一个扇区可以写完了
                }         
        };         
}





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

231

帖子

0

精华

高级会员

Rank: 4

积分
755
金钱
755
注册时间
2018-12-7
在线时间
131 小时
发表于 2019-8-23 13:49:44 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-16 06:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表