OpenEdv-开源电子网

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

SPI实验,把u8 SPI_FLASH_BUF[4096];放在SPI_Flash_Write函数里面为什么就有问题了,求解释

[复制链接]

30

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-8-29
在线时间
17 小时
发表于 2016-2-23 09:21:47 | 显示全部楼层 |阅读模式
1金钱
        u8 SPI_FLASH_BUF[4096];
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{
//        u8 SPI_FLASH_BUF[4096];
        u32 secpos;
        u16 secoff;
        u16 secremain;          
        u16 i;   

        secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16
        secoff=WriteAddr%4096;//在扇区内的偏移
        secremain=4096-secoff;//扇区剩余空间大小   

        if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
        while(1)
        {       
                SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容
                for(i=0;i<secremain;i++)//校验数据
                {
                        if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除            
                }
                if(i<secremain)//需要擦除
                {
                        SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
                        for(i=0;i<secremain;i++)           //复制
                        {
                                SPI_FLASH_BUF[i+secoff]=pBuffer[i];          
                        }
                        SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区  

                }else SPI_Flash_Write_NoCheck(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;                        //下一个扇区可以写完了
                }         
        };                  
}


        把u8 SPI_FLASH_BUF[4096];放在函数里面为什么就出错了

最佳答案

查看完整内容[请看2#楼]

局部变量占用的是栈空间(stack),你把一个4K的数组放在局部,估计是栈空间不足导致的问题。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
434
金钱
434
注册时间
2013-3-18
在线时间
82 小时
发表于 2016-2-23 09:21:48 | 显示全部楼层
局部变量占用的是栈空间(stack),你把一个4K的数组放在局部,估计是栈空间不足导致的问题。
回复

使用道具 举报

30

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-8-29
在线时间
17 小时
 楼主| 发表于 2016-2-23 09:47:24 | 显示全部楼层
if(key==WKUP_PRES)        //WK_UP 按下,写入W25Q64
                {
                        LCD_Fill(0,170,239,319,WHITE);//清除半屏   
                        LCD_ShowString(60,170,200,16,16,"Start Write W25Q64....");
                        printf("AA");
                        SPI_Flash_Write((u8*)TEXT_Buffer,10*4096,SIZE);                //从倒数第100个地址处开始,写入SIZE长度的数据
                        printf("zz");
                        LCD_ShowString(60,170,200,16,16,"W25Q64 Write Finished!");        //提示传送完成
                }


void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)   
{

        u32 secpos;
        u16 secoff;
        u16 secremain;          
        u16 i;   
        u8 SPI_FLASH_BUF[4096];
                printf("DSS");
        secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16
        secoff=WriteAddr%4096;//在扇区内的偏移
        secremain=4096-secoff;//扇区剩余空间大小   
       
        printf("DSS");
        if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
        while(1)
        {       
                SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容
                for(i=0;i<secremain;i++)//校验数据
                {
                        printf("1");
                        if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除            
                }
                if(i<secremain)//需要擦除
                {
                        SPI_Flash_Erase_Sector(secpos);//擦除这个扇区
                        for(i=0;i<secremain;i++)           //复制
                        {
                                printf("2");
                                SPI_FLASH_BUF[i+secoff]=pBuffer[i];          
                        }
                        printf("3");
                        SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区  

                }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
                if(NumByteToWrite==secremain)break;//写入结束了
                else//写入未结束
                {
                        printf("4");
                        secpos++;//扇区地址增1
                        secoff=0;//偏移位置为0          

                           pBuffer+=secremain;  //指针偏移
                        WriteAddr+=secremain;//写地址偏移          
                           NumByteToWrite-=secremain;                                //字节数递减
                        if(NumByteToWrite>4096)secremain=4096;        //下一个扇区还是写不完
                        else secremain=NumByteToWrite;                        //下一个扇区可以写完了
                }         
        };                  
}
串口只发送AA,后面的DSS什么的就不发送了,是因为这个数组太大了吗?感觉这已经超过我的理解范围了,求大神解释
回复

使用道具 举报

3

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
434
金钱
434
注册时间
2013-3-18
在线时间
82 小时
发表于 2016-2-23 10:54:09 | 显示全部楼层
后面不发送的原因是进Hardfault吗?
回复

使用道具 举报

6

主题

41

帖子

0

精华

高级会员

Rank: 4

积分
821
金钱
821
注册时间
2012-3-31
在线时间
177 小时
发表于 2016-2-23 11:27:51 | 显示全部楼层
holy404290384 发表于 2016-2-23 09:33
局部变量占用的是栈空间(stack),你把一个4K的数组放在局部,估计是栈空间不足导致的问题。

说的有道理。
饭量有限,技术无线。
电子开发,时间充裕。
QQ:58692647
回复

使用道具 举报

30

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-8-29
在线时间
17 小时
 楼主| 发表于 2016-2-23 12:37:43 | 显示全部楼层
holy404290384 发表于 2016-2-23 09:33
局部变量占用的是栈空间(stack),你把一个4K的数组放在局部,估计是栈空间不足导致的问题。

好吧,感觉好底层的感觉
回复

使用道具 举报

30

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-8-29
在线时间
17 小时
 楼主| 发表于 2016-2-24 09:34:29 | 显示全部楼层
holy404290384 发表于 2016-2-23 10:54
后面不发送的原因是进Hardfault吗?

不清楚啊,这怎么看
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2016-1-1
在线时间
1 小时
发表于 2016-8-30 22:54:20 | 显示全部楼层
为什么写入大于4096个字节时,读取出来的数据就会出错??
回复

使用道具 举报

30

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2015-8-29
在线时间
17 小时
 楼主| 发表于 2016-11-2 13:38:32 | 显示全部楼层
王雪承 发表于 2016-8-30 22:54
为什么写入大于4096个字节时,读取出来的数据就会出错??

好像是存放函数的内存有个最大量,当大于最大量时,会和后面的数据相互覆盖。只是个人理解。
回复

使用道具 举报

3

主题

55

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
318
金钱
318
注册时间
2017-1-27
在线时间
34 小时
发表于 2017-3-10 22:04:14 | 显示全部楼层
天魂 发表于 2016-11-2 13:38
好像是存放函数的内存有个最大量,当大于最大量时,会和后面的数据相互覆盖。只是个人理解。

会不会是因为一个扇区存放的的数据是4K 一次写大于4096个字节就会跨扇区  写的时候如果某个位置没被擦除 写数据就会失败。 而擦除的时候最小单位是扇区 也许只清除了一个扇区
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-12 20:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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