打印

如何高效的把一个数组左移一bit?

[复制链接]
楼主: fjhcpu
手机看帖
扫描二维码
随时随地手机跟帖
21
D触发器

使用特权

评论回复
22
xch| | 2019-12-23 15:17 | 只看该作者
会不会软硬结合位移时最后多发一个位移脉冲

使用特权

评论回复
23
coody| | 2019-12-23 15:40 | 只看该作者
fjhcpu 发表于 2019-12-23 07:19
左移动速度快,亮度也不降低?

移动是显示给人看的,你能移多快? 帧频一般超过50Hz,刷新一帧移一个点,就是一秒移动3个汉字以上了,移太快会看不清的。刷新一帧移一个点,不会对亮度有任何影响的。我一般是0.8ms扫一行,扫16行是12.8ms,接着是2行处理数据不显示的(1.6ms),所以不会影响亮度。

使用特权

评论回复
24
tianxj01| | 2019-12-23 15:57 | 只看该作者
本帖最后由 tianxj01 于 2019-12-23 16:03 编辑

你既然用的1维数组,最佳方法是一个16bit数据代表纵向16个点的亮、灭。
然后采用修改指针的窗口显示方法,一个1维数组,比如你这里16*64,只是修改指针,每扫描帧修改一下指针位置,速度肯定跟得上。其实哪怕需要纵向滚动也是一样的,只是多了一个16bit数据内部的指针,指针指到几,则从第几bit开始输出。其实用1bit的亮、灭控制,还是多彩的16bit-24bit的画面移动控制,都是一个原理,内存开辟出一个对应的二维矩阵,点对点映射到LED。而实际显示,是可以从任何行任何列开始读取输出。修改读取的起始位置,就可以实现画面横滚、上下滚对角线滚等各种动作。

使用特权

评论回复
25
z_no1| | 2019-12-23 17:53 | 只看该作者
xch 发表于 2019-12-22 18:37
bitband 操作可能是最快的。

不是快的问题,是不占用CPU时间的问题.

使用特权

评论回复
26
fjhcpu|  楼主 | 2019-12-23 19:27 | 只看该作者
coody 发表于 2019-12-23 15:40
移动是显示给人看的,你能移多快? 帧频一般超过50Hz,刷新一帧移一个点,就是一秒移动3个汉字以上了,移 ...

我的单色 32*320点阵显示屏,向左移动速度和亮度不能兼顾。市面上相同stm32方案的商业控制卡,向左移动的相当快速流畅,亮度也很好。不知道他们用了一些什么样的特殊技巧。我的始终达不到他们那个水平。

使用特权

评论回复
27
fjhcpu|  楼主 | 2019-12-23 22:26 | 只看该作者
做好不容易呀

使用特权

评论回复
28
linnjing| | 2019-12-23 22:36 | 只看该作者
变化快了亮度下降,感觉是刷新时序有问题。
检查一下刷新时序吧,再不行,改成双缓冲。
------
怀疑算法效率影响显示效果,那么具体要多快才够?这个可以定量算一下嘛。算法运行是us级的,显示要求是ms级的,说实话,算法效率不太可能影响显示效果的。
------
DMA移位带,使用内存到内存复制模式,类似a[0]=a[1]。
位带处理并不快,要讲快,还得是32位一起处理。位带处理的好处是逻辑比较清晰。
个人觉着,位带这个东西挺**肋的。不能说没用,特别是涉及读修改写的位操作,还是挺好用的,但真要说有多大用?相比硬件增加的复杂性,个人认为挺得不偿失的。

使用特权

评论回复
29
xch| | 2019-12-23 23:42 | 只看该作者
fjhcpu 发表于 2019-12-23 19:27
我的单色 32*320点阵显示屏,向左移动速度和亮度不能兼顾。市面上相同stm32方案的商业控制卡,向左移动的 ...

亮度与你处理位移没有半毛钱关系。速度才有关系

使用特权

评论回复
30
elife| | 2019-12-24 09:42 | 只看该作者
估计楼主是每移动完成就刷新一次,这样亮度和移动速度有关系了,没有按照显示屏那样定时刷新,还是程序运行机理的问题。

使用特权

评论回复
31
chongdongchen| | 2019-12-24 09:55 | 只看该作者
支持28楼,你的刷新时序很可能有问题。

使用特权

评论回复
32
kingkits| | 2019-12-24 09:58 | 只看该作者
如果你的显示内存不大,比如每一个点只有黑白两色(即1bit) 整个数据大概是 320x4bytes,即1280字节的数组,
如果想快,就不要去移位,
最笨的方法直接定义 32 * 1280 的数组,每一组存放移位好的数据,然后你就简单DMA或者拷贝就行了,当然你可能没有这么大的内存,
稍微复杂一点,定义16 * 1280 的数组,很明显,移位16位后,仅仅是错过2个字节
或者定义 8 * 1280的数组,每移动8bits,都会错过一个字节,循环使用就好
如果你还没有内存,那就只好做汇编了

使用特权

评论回复
33
xch| | 2019-12-24 10:12 | 只看该作者
嵌入汇编也很快。平均每32位位移差不多3条汇编指令。

使用特权

评论回复
34
jiekou001| | 2019-12-24 10:17 | 只看该作者
<<1
这种不行吗,

使用特权

评论回复
35
shizaigaole| | 2019-12-24 13:19 | 只看该作者
在当前单片机资源如此丰富,速度如此快的情况下,
还研究这些奇技淫巧,
完全是在浪费时间,浪费生命。

使用特权

评论回复
36
yjmwxwx| | 2019-12-24 15:18 | 只看该作者
本帖最后由 yjmwxwx 于 2019-12-24 15:21 编辑



胡乱写个程序做个试验,数太长,没仔细看,你自己对比下看看行不行。


        ldr r0, = 0x20000500
        movs r1, # 10
        bl __yi_wei
        bkpt # 2
__yi_wei:
        [url=home.php?mod=space&uid=72445]@[/url] r0=地址 r1=长度
        push {r4-r7,lr}
        mov r12, sp
        lsls r1, r1, # 5
        adds r1, r1, r0
        mov r11, r1
__xun_huan:
        mov sp, r0
        pop {r0-r7}
        adcs r0, r0, r0
        adcs r1, r1, r1
        adcs r2, r2, r2
        adcs r3, r3, r3
        adcs r4, r4, r4
        adcs r5, r5, r5
        adcs r6, r6, r6
        adcs r7, r7, r7
        push {r0-r7}
        mov r0, sp
        adds r0, r0, # 0x20
        cmp r0, r11
        bne __xun_huan
        mov sp, r12
        pop {r4-r7,pc}


运行前


运行后



使用特权

评论回复
37
linnjing| | 2019-12-25 09:03 | 只看该作者
循环中间使用 LDM STM 进行数据存取。
push pop 指令就是用R13做基址的块存取指令。

使用特权

评论回复
38
yjmwxwx| | 2019-12-25 10:34 | 只看该作者
本帖最后由 yjmwxwx 于 2019-12-25 10:35 编辑
linnjing 发表于 2019-12-25 09:03
循环中间使用 LDM STM 进行数据存取。
push pop 指令就是用R13做基址的块存取指令。 ...

我用的是M0的,这样改行不行?


使用特权

评论回复
评论
fjhcpu 2019-12-28 23:50 回复TA
你测试的的怎样?效率比C语言高不? 
39
amwrdfe| | 2019-12-25 11:22 | 只看该作者
shizaigaole 发表于 2019-12-24 13:19
在当前单片机资源如此丰富,速度如此快的情况下,
还研究这些奇技淫巧,
完全是在浪费时间,浪费生命。 ...

赞同,32*320=10240B 1.25k的数据,在内存直接开个vram就好了。

使用特权

评论回复
40
coody| | 2019-12-25 22:35 | 只看该作者
移动速度相对于扫描速度很慢,所以原则上,移动不会影响亮度。
亮度取决于驱动LED的电流和占空比,我的卡不会因为移动而有亮度变化,因为我的每一行扫描占空比总是固定不变的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则