OpenEdv-开源电子网

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

串口接收数据,如何实时动态写入SPI接口的flash,而不是需要满4096个字节才能写入,或者说需要满固定的字节数才能写入

[复制链接]

4

主题

7

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2021-1-2
在线时间
6 小时
发表于 2021-1-11 21:05:51 | 显示全部楼层 |阅读模式
5金钱
运用新战舰 V3开发板,SPI flash为W25Q128xx,Flash每4KB为一个Sector,共计4096个Sector

方法一:串口中断接收数据,保存在开辟的存储区(数组),数组长度4096,写满这个数组刚好4KB,然后W25QXX_Write((u8*)TEXT_Buffer,t*4096,4096);将整个数组的数据依次写入并保存在Flash里面

方法一可以正确的写入数据,但是有一个问题就是只有写满数组4096个字节,数据才会写入FLASH,如果数组没有写满是无法写入到FLASH的;
例如:串口1正常接收数据,每满4096个字节就写入到Flash,但是最后一个段数据不满4096个字节,那么最后这一段就会出现没有写入flash的情况;
为了解决数据没有写满4096个字节也能写入Flash的问题,修改为下面的方法二,但是有问题,希望高手来指点一下。
方法一:
void USART1_IRQHandler(void)
{

        if(t<4096)                   //判断地址是否超出范围
        {
                if(USART_GetITStatus(USART1,USART_IT_RXNE))
                {
                        res=USART_ReceiveData (USART1);
                        TEXT_Buffer[i]=res;                                    //串口1接收数据并保存在数组中
                        if(i<4095)                                 
                                {
                                        i++;                                          //数组还未写满
                                }
                        else
                                {       
                                        W25QXX_Write((u8*)TEXT_Buffer,t*4096,4096);             //数组写满,写入Flash中           
                                        i=0;
                                        t++;
                                }
                }
        }
}

===========================================================================================================================
方法二:
void USART1_IRQHandler(void)
{
                if(USART_GetITStatus(USART1,USART_IT_RXNE))
                {
                        res=USART_ReceiveData (USART1);                               //串口1接收数据,并放入数组的第一位
                        TEXT_Buffer[0]=res;
                        if(i<4096)
                        {
                                W25QXX_Write((u8*)TEXT_Buffer,num*4096+i,1);      //数据还没满4096,Sector的地址不变,偏移地址加1,每来一个数据就写一次
                                i++;
                        }
                        else
                        {       
                                num++;                                                            //数据满4096个,进入下一个Sector地址,偏移地址从0开始
                                i=0;
                        }
                }
}



目前采用方法二进行验证,有一个问题就是数据写入不全,串口1接收好多数据,但是写入到Flash的字符数量很少;

个人分析可能是串口1接收数据太快,在串口中断程序里面写入太平凡,导致串口1丢数据太严重;

针对这个问题,大家有没有什么好的编程思路。要求就是串口1接收任意长度的(不超过4096个字节)的数据能够准确写入FLASH里面。



最佳答案

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

按照方法一,在两个情况下写flash,1:满了4096;2:你这收到的字节不是会计数吗,当这个字节不动了,不是就收完了数据吗,然后把这一包数据写到flash就好了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

41

主题

278

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2357
金钱
2357
注册时间
2019-10-29
在线时间
380 小时
发表于 2021-1-11 21:05:52 | 显示全部楼层
按照方法一,在两个情况下写flash,1:满了4096;2:你这收到的字节不是会计数吗,当这个字节不动了,不是就收完了数据吗,然后把这一包数据写到flash就好了
回复

使用道具 举报

34

主题

252

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
473
金钱
473
注册时间
2020-5-11
在线时间
217 小时
发表于 2021-1-12 10:23:28 | 显示全部楼层
将接收的数据放到数组,然后在另外写入,不要边收边存呗
回复

使用道具 举报

12

主题

3402

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8689
金钱
8689
注册时间
2020-5-11
在线时间
4177 小时
发表于 2021-1-12 10:49:25 | 显示全部楼层
建议用数组模拟FIFO(环形队列),串口中断只管接收数据存入FIFO,主循环读取FIFO写入FLASH。
http://www.openedv.com/forum.php ... hlight=%B6%D3%C1%D0
专治疑难杂症
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2021-1-12 12:31:54 | 显示全部楼层
FLASH存储器写入寿命是由次数的,加缓存少次多量写入数据可以延长寿命。同时结合DMA可以减少CPU资源占用,以完成更多的任务
回复

使用道具 举报

233

主题

961

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1815
金钱
1815
注册时间
2011-10-9
在线时间
230 小时
发表于 2021-1-12 16:36:54 | 显示全部楼层
本帖最后由 simms01 于 2021-1-12 16:42 编辑

数组 A[4096*2]

串口中断
{
收到了数 如果是第一个数 那么打开定时器1
  收到存数组  数组地址+++ 重置定时器

如果数组地址=4096 置标志1
如果数组地址=8192 数组地址=0 置标志2

}

大循环
{
  如果标志1  写入数组0-4096到flash
如果标志2  写入4096-8192到flash
如果定时器中断了 说明数据没了 写入数据到flash
}
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-25 15:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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