标题: C语言如何把一个超大数组赋值后存放到FLASH中? [打印本页]

作者: hxdby    时间: 2022-7-24 10:03
标题: C语言如何把一个超大数组赋值后存放到FLASH中?
我的FLASH空间比较大,有512K,RAM空间也比较大,接近200K,但是RAM由于还要做其他用途,所以现在需要把一个超大数组保存到FLASH中。
现在有一个超大数组:

uint16_t   databuffer[240][320],

这个数组有240x320=76800个元素,然后占用空间76800x16bit=153KB, 可谓是相当大了,我如何把这个大数组存放到FLASH中呢?

这么大的数组怎么给他赋初值?不可能用大括号的方式,databuffer[240][320]={0xFFFF, 0x32A3........},  7万多个数据,写到猴年马月也写不完啊。

如果我加关键字const uint16_t   databuffer[240][320] 的方式,可以让他保存在FLASH中,但是没法先赋初值,如果我用for循环赋值,倒是很快,可是就没法加const保存到FLASH中了。

谁能解决这个矛盾?

作者: xuyaqi    时间: 2022-7-24 14:02
编程时数组直接赋值放FLASH中。
作者: lkc8210    时间: 2022-7-24 15:22
你的7万多个数据是有来源的吧?Excel?SQL?CSV?
利用这些来源生成一个
uint16_t code databuffer[240][320] = {......};储存到DtatTable.h内就可以了
作者: hxdby    时间: 2022-7-24 17:13
lkc8210 发表于 2022-7-24 15:22
你的7万多个数据是有来源的吧?Excel?SQL?CSV?
利用这些来源生成一个
uint16_t code databuffer[240][ ...

没有来源,,这些数据是LCD的颜色数据,平时我是用for循环直接赋值,赋值后直接使用。因为颜色数据我要用的时候直接for循环赋值就可以了,所以没必要整成一个excel. 所以这算不算C语言的一个缺陷,大数组的初始化非常不方便,,,,,,只能直接大括号内写。。。
作者: hxdby    时间: 2022-7-24 17:15
xuyaqi 发表于 2022-7-24 14:02
编程时数组直接赋值放FLASH中。

我这个大数组是为了LCD初始化的时候,DMA直接从数据读数据刷屏幕,,,因为这些数据基本不涉及到改动,所以考虑放FLASH中,请问编程时直接赋值怎么能放FLASH中?7万多个数据要一个一个写吗?
作者: Y_G_G    时间: 2022-7-24 21:17
能用for循环直接赋值,这个数据是固定的吗?或者是有规律的?不知道这是什么意思,没有用过LCD不知道
在FLASH开辟某个地址,比如0000H存放一个标志位
程序启动先读取这个标志位,如果没有标志,就用for循环写入FLASH,写完之后置位标志位并保存,这样,这你所谓的7万多个数据就保存在FLASH了
如果已经标志了,就不用写入了,跳过写入这一步
下一步就是读取FLASH中的数据,初始化LCD
这样就达到了每次开机都能通过读取FLASH来完成初始化了
不知道这行不行得通
作者: Hephaestus    时间: 2022-7-24 22:26
7万个数据怎么可能没有来源?总不能是随手瞎写的吧?
作者: hxdby    时间: 2022-7-24 23:21
Hephaestus 发表于 2022-7-24 22:26
7万个数据怎么可能没有来源?总不能是随手瞎写的吧?

我说的没有来源指的是没有把这7万多个数据汇总成一个EXCEL表格随时调用,我是这么用的,我现在的LCD是320x240的分辨率,所以像素是320x240=76800个,用的是RGB565颜色,所以一个像素需要用16bit的数据刷颜色,这个数据量太大,只能用DMA去连续搬运同一个颜色,比如这个颜色是0xFFFF, 所以我的用法是,

for(i=0; i<240; i++)
{
    for(j=0; j<320; j++)
    {
        databuffer[ i][j]=0xFFFF;
  }
}

//然后用DMA搬运
DMA_Senddata16(&databuffer[0][0], 76800);


所以用法很简单,只是for循环把一个颜色数据赋值给大数组,然后DMA根据数组地址连续搬运。
所以没什么来源,只是赋值而已。
作者: hxdby    时间: 2022-7-24 23:23
Y_G_G 发表于 2022-7-24 21:17
能用for循环直接赋值,这个数据是固定的吗?或者是有规律的?不知道这是什么意思,没有用过LCD不知道
在FLASH ...

数据是固定的,就是LCD的颜色数据,也就是一个RGB565颜色,16bit,2个字节,比如OXFFFF,就是要把这个0XFFFF写入到这个大数组,简单说就是写76800次0XFFFF。
这样做主要是为了DMA从数组搬运颜色刷整个屏幕,这样的方法速度最快。

你这个方法我也想过,目前看来,好像也没别的方法了。
作者: hxdby    时间: 2022-7-24 23:33
Hephaestus 发表于 2022-7-24 22:26
7万个数据怎么可能没有来源?总不能是随手瞎写的吧?

换句话说,如果有来源,比如这7万多个数据都整理好了,那我也不来这里提问了,我直接copy到我的代码里就好了。现在是没有来源,而且我这个数据是固定的一个值,因为这是刷LCD的颜色值作为全屏画布用,不是你想的那种整理好的数据,颜色值就是一个固定值,我要刷什么颜色就赋什么值到大数组,所以用for循环就好了。

作者: 188610329    时间: 2022-7-25 00:03
hxdby 发表于 2022-7-24 23:23
数据是固定的,就是LCD的颜色数据,也就是一个RGB565颜色,16bit,2个字节,比如OXFFFF,就是要把这个0XF ...

所以,为什么一定要DMA搬运数组呢? 直接刷76800次不比从数组搬运更快么? 中断里做一个刷屏标志,做一个底色变量,以及计数,只要刷屏标志被置位,就不停的刷指定的底色,直到计数满76800次结束,然后清刷屏标志,感觉这样比搬运数组到DMA,然后DMA自动刷屏效率要高啊。
作者: Y_G_G    时间: 2022-7-25 00:58
188610329 发表于 2022-7-25 00:03
所以,为什么一定要DMA搬运数组呢? 直接刷76800次不比从数组搬运更快么? 中断里做一个刷屏标志,做一个 ...

DMA不需要做什么的呀,设定好初始化就可以了,SPI的DMA操作是不用占用主程序时间的
肯定要快一点了
直接写入76800次,不管是用中断还是等待,每次写入完成,你就得清除中断标志位,中断返回,大概要1uS吧
那76800次就要多花76800uS=76.8mS
DMA就不需要多花这76.8mS了,程序只要处理DMA传输完成之后的几个操作而已
作者: hxdby    时间: 2022-7-25 01:25
188610329 发表于 2022-7-25 00:03
所以,为什么一定要DMA搬运数组呢? 直接刷76800次不比从数组搬运更快么? 中断里做一个刷屏标志,做一个 ...

你这种方法在实际LCD刷屏中是行不通的,主要是没考虑SPI的速率,SPI的频率一般很低,如果用你这种方法,SPI每次只能传输一帧数据,每传输一帧需要拉低拉高片选一次,这中间拉低拉高片选的时间加上SPI的低速都够你受的了,而DMA的好处是只需拉低一次片选,中间可以靠DMA连续无停顿的搬运76800次,就像打%%%一样的,搬完了拉高片选结束。当然前提是SPI的速度不能太低,太低了,DMA也没用,但如果不用DMA,大概率直接刷屏的速度是不可能提上来的。我板子都做出来了,现在DMA刷屏速度杠杠的
作者: 260189914    时间: 2022-7-25 18:11
两个问题:
1、保存到flash
这位问题看起来你已经解决了,const定义就可以了
2、赋初始值
为啥非得要C去给初始值啊,你用脚本写一个初值不就行了么?很快,很简单,perl,python都可以啊
作者: 的花朵    时间: 2022-7-27 10:46
大兄弟不会是想用flash当显存叭,不可以哦
作者: 雪玉寐影    时间: 2022-7-27 12:54
我怎么感觉你是想要存一副图片呢
作者: yzwzfyz    时间: 2022-7-28 10:19
主导思想不合理。方针错了,方法就没有意义了。
作者: 名字不是重点    时间: 2022-7-28 11:28
关注一下!看看楼主是如何解决这个问题的。
作者: tuohang2012    时间: 2022-7-28 11:50
那就是 flash编程啊,需要单独的flash地址不要下载程序的地址和这个冲突,单独的函数,程序开始的时候运行,把数组里面的数据进行编程,再进行读取。
作者: 神话A小王子    时间: 2022-7-28 17:03
flash模拟eeprom的方法,先给扇区擦除在写入数据就可以实现数据修改,还可以实现掉电保存~
作者: lyonkon    时间: 2022-7-28 22:08
hxdby 发表于 2022-7-24 23:33
换句话说,如果有来源,比如这7万多个数据都整理好了,那我也不来这里提问了,我直接copy到我的代码里就 ...

按你这么说,就不需要写数据到falsh。程序直接现场给显示屏赋值就可以了,你想用什么颜色就附什么值,不是更方便吗
作者: hxdby    时间: 2022-7-29 00:12
lyonkon 发表于 2022-7-28 22:08
按你这么说,就不需要写数据到falsh。程序直接现场给显示屏赋值就可以了,你想用什么颜色就附什么值,不 ...

说的没错,但是你没看我前面的描述,我是想节省我的RAM,因为不写到flash的话,定义的大数组是占用RAM的,而且我的RAM还有其他用途,不能占用太多,所以考虑把他放到flash里
作者: hxdby    时间: 2022-7-29 00:14
yzwzfyz 发表于 2022-7-28 10:19
主导思想不合理。方针错了,方法就没有意义了。

不明白你在说什么?你可能没有真正理解我在做什么?给LCD刷屏的颜色数据我想问问,你是怎么处理的?要放在哪里?flash还是RAM?怎么刷?总归要有地方放吧?不明白你这莫名其妙的一句话什么意思,你有好的思想你提出来大家讨论呀
作者: hxdby    时间: 2022-7-29 00:18
祖国的花朵 发表于 2022-7-27 10:46
大兄弟不会是想用flash当显存叭,不可以哦

显存我一般用RAM来做,你用flash当显存?看来你还得努力啊
作者: Y_G_G    时间: 2022-7-29 07:00
lyonkon 发表于 2022-7-28 22:08
按你这么说,就不需要写数据到falsh。程序直接现场给显示屏赋值就可以了,你想用什么颜色就附什么值,不 ...

现场用SPI操作是不是还得拉高拉低CS线的?
是不是还来  SPI_Write(数据);那么一下呢?
这一来一去的,7万多次,那得多花多少时间出来呢?
用Flash通过DMA写入,基本就是什么事都不用干,主程序有很多时间去执行其它任务的




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1