附图的说明详见附件
环境CPU:STM32F429ZGT6SPI FLASH:W25N01GVZEIG (1G bit)
初始化/************************************管脚初始化*****************************/GPIO_InitTypeDef GPIO_InitStructure;
/*使能GPIO 时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
/*配置 SCK, MISO 、 MOSI 为复用功能 */ GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource6, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType= GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA,&GPIO_InitStructure);
/*配置片选 */// GPIO_PinAFConfig(GPIOA,GPIO_PinSource4, GPIO_AF_SPI1); SF_CS_HIGH(); /* 片选置高,不选中 */ GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType= GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin= GPIO_Pin_4; GPIO_Init(GPIOA,&GPIO_InitStructure);
/**********************************SPI初始化***********************************/SPI_InitTypeDef SPI_InitStructure;/* 打开SPI时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
/*配置SPI硬件参数 */ SPI_InitStructure.SPI_Direction= SPI_Direction_2Lines_FullDuplex; /* 数据方向:2线全双工 */ SPI_InitStructure.SPI_Mode= SPI_Mode_Master; /*STM32的SPI工作模式:主机模式 */ SPI_InitStructure.SPI_DataSize= SPI_DataSize_8b; /* 数据位长度 : 8位 */ /*SPI_CPOL和SPI_CPHA结合使用决定时钟和数据采样点的相位关系、 本例配置: 总线空闲是高电平,第2个边沿(上升沿采样数据) */ SPI_InitStructure.SPI_CPOL= SPI_CPOL_High; /*时钟上升沿采样数据 */ SPI_InitStructure.SPI_CPHA= SPI_CPHA_2Edge; /* 时钟的第2个边沿采样数据 */ SPI_InitStructure.SPI_NSS= SPI_NSS_Soft; /* 片选控制方式:软件控制*/
/*设置波特率预分频系数 */ /* 【SPI时钟最快是2分频,不支持不分频】 如果是SPI1,2分频时SCK时钟 = 42M,4分频时SCK时钟 = 21M 如果是SPI3, 2分频时SCK时钟 = 21M */ SPI_InitStructure.SPI_BaudRatePrescaler= SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit= SPI_FirstBit_MSB; /* 数据位传输次序:高位先传*/ SPI_InitStructure.SPI_CRCPolynomial= 7; /* CRC多项式寄存器,复位后为7。本例程不用 */ SPI_Init(SPI1,&SPI_InitStructure);
SPI_Cmd(SPI1,DISABLE); /* 先禁止SPI */ SPI_Cmd(SPI1,ENABLE); /* 使能SPI */
sf_Reset();
sf_ReadInfo(); /* 自动识别芯片型号 */
测试过程1, 从SPI地址0x100000开始写。2, 先将对应的存储擦掉。读出来全FF,没有问题3, 每次写8个字节,全0xaa。按地址顺序往下写。4, 每隔200ms写一次。
起初写的约512字节,读写都没有问题(一次读1024字节)。
继续往后写,发现问题,原来读出来正确的地方,现在已经变了,主要问题是部分本应为1的bit变成了0(注:也发生过0变1的情况)。
不仅是已写的部分不正确,还没写的部分也有问题了。甚至后面的相邻page也受到了影响。
针对某一个字节,用示波器看,黄 {MOD}为时钟,蓝 {MOD}为MISO,FLASH的输出,确实输出来的就是0x2A:ARM端是时钟上升沿采样。FLASH端是时钟下降沿拍数据。ARM端采数据几乎在电平的中间,时序是比较好的。file:///C:/Users/tc-lt/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg
MISO保持时间,约为2ns:
file:///C:/Users/tc-lt/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg
另外,甚至偶现某个字节的值每次读出来的值都不一样。有时是0xaa有时是0x2a。
在其他的block中,也出现过同样的问题,只是出现的几率会有不同。在其他的板子上,也有过同样的问题。
应该不是坏块或者芯片个体的问题。
尝试1, ARM端的问题应该不大,做了各种尝试,寄存器的各种配置几乎都试过。2, FLASH端的配置,只有两个寄存器。其中一个是做保护的,全都置为0。另一个是配置的,只有5个bit可以配置,基本上也试过。3, Winbon的另一个64M的芯片上,同样的初始化配置(软件读写序列与1G的有较大不同)。没有问题。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>