打印

回Computer00,您提到的那篇**在博客的哪一页,没找到.

[复制链接]
楼主: 古道热肠
手机看帖
扫描二维码
随时随地手机跟帖
21
wangkj| | 2009-3-30 14:48 | 只看该作者 回帖奖励 |倒序浏览

热肠的脑袋还在单片机转呢

过两年就转过来了。
原来,只有1两银子,现在有一屋子的金子,不知道咋用。

使用特权

评论回复
22
古道热肠|  楼主 | 2009-3-30 16:50 | 只看该作者

22楼的说得很好,很在理,鼓掌

也很有指导性.

使用特权

评论回复
23
wangkj| | 2009-3-30 18:21 | 只看该作者

俺的群共享有硬件spi的例子,香肠自己找找吧。

使用特权

评论回复
24
avocationA| | 2009-3-30 22:33 | 只看该作者

平时调程序多用VC,???????

VC 是啥东西啊?

使用特权

评论回复
25
alex74| | 2009-3-31 08:40 | 只看该作者

Visual C++, 呵呵

使用特权

评论回复
26
goosen| | 2009-4-2 12:56 | 只看该作者

re

1)uchar ucCount -> uint ucCount
2) for循环适当展开。

使用特权

评论回复
27
古道热肠|  楼主 | 2009-4-2 17:29 | 只看该作者

哈哈,难道32位变量体做的循环控制直比8位的快?

楼上网友的这建议,俺再来仿真验证验证,如的确可行,在ARM平台上那就改变习惯,尽量用32位数做循环变量了.

使用特权

评论回复
28
computer00| | 2009-4-2 17:35 | 只看该作者

临时变量尽量用32位的,这个你可以参考俺blog有篇**分析

使用特权

评论回复
29
古道热肠|  楼主 | 2009-4-3 12:02 | 只看该作者

用软件仿真调试了一下,没有改进速度.

对单字节无符号数与字的操作完全用的一样的指令.变量长度够用的原则对低档单片机较为适用.

使用特权

评论回复
30
古道热肠|  楼主 | 2009-4-3 12:12 | 只看该作者

回Computer00,您提到的那篇**在博客的哪一页,没找到.

使用特权

评论回复
31
computer00| | 2009-4-3 12:16 | 只看该作者

这里:

http://blog.**/computer00/20132/message.aspx


看看编译后的汇编代码就清楚了。

使用特权

评论回复
32
三块石头| | 2009-4-3 15:06 | 只看该作者

古道

如果32位机循环还用8位变量来计数的话,反而慢
因为编译器会在自增后,把多余的高24位mask掉,“与”出一个8位结果来给你;而32位变量自增一条指令就完成了

使用特权

评论回复
33
古道热肠|  楼主 | 2009-4-3 17:16 | 只看该作者

俺用的那MDK3.2版,经过三级优化,测试的结果速度是一样的.

经过优化,MDK把8位无符号变量直接用一32位寄存器来装载,并初始化成无符号字节的初始值,代码如下.

0x00100244  E3A00000  MOV       R0,#0x00000000
0x00100248  E583C030  STR       R12,[R3,#0x0030]
    33:     for(ucCount=8; ucCount; --ucCount) 
    34:     { 
0x0010024C  E3A01008  MOV       R1,#0x00000008
    35:         ucReadData <<= 1; 
    36:  
    37:         Macro_Set_CLK_Low(); 
    38:         Macro_Set_CLK_High(); 
    39:      
    40: //        if(GetSDCard_SO_Value()) 
    41:         if(AT91F_PIO_GetInput( AT91C_BASE_PIOA) & SD_SO)  //内联函数,无调用开销 
    42:         { 
    43: //            ucReadData |= 0x01; 
0x00100250  E1A00C80  MOV       R0,R0,LSL #25
0x00100254  E1A00C20  MOV       R0,R0,LSR #24
0x00100258  E5834034  STR       R4,[R3,#0x0034]
0x0010025C  E5834030  STR       R4,[R3,#0x0030]
   586:         return pPio->PIO_PDSR; 
0x00100260  E593203C  LDR       R2,[R3,#0x003C]
    44:             ucReadData++; 
    45:         } 
    46:     } 
    47:     return(ucReadData); 
    48: } 
    49:  
    50: void  VS1003B_SPIPutChar(unsigned char ucSendData) 
    51: {       
    52: //    S0SPDR = c; 
    53: //    while((S0SPSR & 0x80) == 0);     //等待SPI将数据发送完毕 
    54:     uchar register ucCount; 
    55:     uchar register ucMaskCode; 
    56:  
0x00100264  E2411001  SUB       R1,R1,#0x00000001
    41:         if(AT91F_PIO_GetInput( AT91C_BASE_PIOA) & SD_SO)  //内联函数,无调用开销 
    42:         { 
    43: //            ucReadData |= 0x01; 
    44:             ucReadData++; 
    45:         } 
    46:     } 
    47:     return(ucReadData); 
    48: } 
    49:  
    50: void  VS1003B_SPIPutChar(unsigned char ucSendData) 
    51: {       
    52: //    S0SPDR = c; 
    53: //    while((S0SPSR & 0x80) == 0);     //等待SPI将数据发送完毕 
    54:     uchar register ucCount; 
    55:     uchar register ucMaskCode; 
    56:  
0x00100268  E3120A01  TST       R2,#0x00001000
0x0010026C  12800001  ADDNE     R0,R0,#0x00000001
0x00100270  120000FF  ANDNE     R0,R0,#0x000000FF
0x00100274  E21110FF  ANDS      R1,R1,#0x000000FF
0x00100278  1AFFFFF4  BNE       0x00100250
    57:     ucMaskCode = 0x80; 

说明: R1为uCount;
执行ucCount--的汇编语句为:
SUB       R1,R1,#0x00000001
执行检查循环终止条件是否为0并退出的语句为
ANDS      R1,R1,#0x000000FF
BNE       0x00100250


使用特权

评论回复
34
guet| | 2009-4-4 15:52 | 只看该作者

re

我在UCOS里几个任务,放320KPB/S的MP3,播放任务还可以挂起30ms不卡

使用特权

评论回复
35
古道热肠|  楼主 | 2009-4-5 10:19 | 只看该作者

楼上的说说详细点听听,用的什么平台.挂起30mS,有些不可信.

320Kbps,要求数据流是40K字节/s,每毫秒40个字节.30ms是1200个字节,VS1003B总共只有32字节缓冲,怎么来得及缓冲.

使用特权

评论回复
36
computer00| | 2009-4-5 10:28 | 只看该作者

估计人家用的硬件SPI和硬件DMA啊,这个可差得N远了。

使用特权

评论回复
37
goosen| | 2009-4-5 11:53 | 只看该作者

re

可以试下把for循环展开

至于具体细节,可以参考《ARM嵌入式系统开发—软件设计与优化》(沈建华译,北航出版社)的第五章:高效的C编程。那介绍比较详细。

使用特权

评论回复
38
古道热肠|  楼主 | 2009-4-5 12:06 | 只看该作者

哈哈,除非DMA,硬件SPI理论上是不可能的

俺在37楼计算时,已经把送数据的时间按0计算了.DMA+SPI那是无敌的,等于请了个不吃饭光干活的工人,发现VS1003B没数据了,自己去SRAM中找数据,把VS1003B喂饱.只有SRAM中的数据用完了,才通知MCU,运一车过来.慢慢用.

使用特权

评论回复
39
古道热肠|  楼主 | 2009-4-5 12:10 | 只看该作者

哈哈,俺有空时去看看北航译的那本书,不会For循环展开

只会使用不带循环的写法,循环多少次,俺就把循环代码体Ctrl+V多少次,估计效率是高,但代码长度也高.

使用特权

评论回复
40
guet| | 2009-4-5 16:54 | 只看该作者

楼上的说说详细点听听,用的什么平台.挂起30mS,有些不可信

用NXP的LPC2148,都是用硬件SPI模式,没有DMA,VS1003B并不止32字节缓冲,你没有好好看英文手册,实际上1003内部的5K RAM都可以做缓冲,这才是关键。
我的播放任务确实挂起30ms才去给VS1003送数,320K的MP3播放流畅。

使用特权

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

本版积分规则