打印

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

[复制链接]
6691|40
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
古道热肠|  楼主 | 2009-3-28 10:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用ARM开发产品,没有了位指令,机器架构又是流水线结构,分枝指令严重影响效率,对ARM汇编又不熟悉.到底始何写C语言程序才能高效运行.先写两个函数,大家提提优化建议.

static uchar SD_SPI_ReadByte(void)
{
    uchar ucReadData;
    uchar ucCount;

    ucReadData = 0;
    Macro_Set_SI_High();
    
    for(ucCount=8; ucCount; --ucCount)
    {
        ucReadData <<= 1;

        Macro_Set_CLK_Low();
        Macro_Set_CLK_High();
    
//        if(GetSDCard_SO_Value())
        if(AT91F_PIO_GetInput( AT91C_BASE_PIOA) & SD_SO)  //内联函数,无调用开销
        {
//            ucReadData |= 0x01;
            ucReadData++;
        }
    }
    return(ucReadData);
}

void  VS1003B_SPIPutChar(unsigned char ucSendData)
{      
//    S0SPDR = c;
//    while((S0SPSR & 0x80) == 0);     //等待SPI将数据发送完毕
    uchar ucCount;
    uchar ucMaskCode;

    ucMaskCode = 0x80;
    for(ucCount=8; ucCount; --ucCount)
    {
        Macro_Set_CLK_Low();

        if(ucMaskCode & ucSendData)
        {
            Macro_Set_SI_High();
        }
        else
        {
            Macro_Set_SI_Low();
        }

        Macro_Set_CLK_High();
        ucMaskCode >>= 1;

    }
}

相关帖子

来自 2楼
alex74| | 2009-3-30 14:00 | 只看该作者

....

芯片不是这样玩的.
以下原则千万遵守

1. 能用硬件解决就用硬件.别用软件模拟.才几十M就觉得很宽裕?用1G的DSP都不敢这么用.

2. 资源足够,能上操作系统千万别裸奔.裸奔不代表高手,恰恰是落后的象征.

3. 能用C千万别写汇编.我敢担保你基本写不出能比ARM编译器更快的汇编.32位芯片有流水线的,和单片机不一样,很容易产生寄存器竞争的.比如上条指令写R0,下一条指令读R0的话就会有2-3个clk的延时.MDK使用ADS3的编译器,虽然比不上最新的ADS4编译器,但是已经很厉害了.

4. 写代码一定要系统无关性.无论在arm7,arm9,还是pc上都是能跑的.平时调程序多用VC,调好后直接上板,争取一次成功.

5. 用操作系统千万记得线程安全性. 要保护多个线程操作一个硬件.

使用特权

评论回复
板凳
古道热肠|  楼主 | 2009-3-28 10:40 | 只看该作者

补充一下,上面带Macro开头的语句都是宏调用,无开销

#define Macro_Set_SI_High()      AT91F_PIO_SetOutput( AT91C_BASE_PIOA, SD_SDIN )
#define Macro_Set_SI_Low()      AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, SD_SDIN)

#define Macro_Set_CLK_High()      AT91F_PIO_SetOutput( AT91C_BASE_PIOA, SD_SCLK) 
#define Macro_Set_CLK_Low()      AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, SD_SCLK) 
后面的函数是内联库函数,编译直接插入功能函数中.

使用特权

评论回复
地板
古道热肠|  楼主 | 2009-3-28 10:44 | 只看该作者

最近试了一把用AT91SAM7S64+VS1003B播放MP3音乐,320kbps有些杂音

256KbPS时,MCU还有空闲,上升到320kbPS时,MCU满负载,耳机中有杂音,系数据断流所致.哈哈,此贴为抛砖引玉贴,最后底层读写肯定要用硬件SPI实现,但其优化的思路和方法可用到程序的其它地方,会带来更多性能的提升.

使用特权

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

开硬件SPI吧,再加上DMA。

使用特权

评论回复
6
xwj| | 2009-3-28 11:09 | 只看该作者

晕,不要拿着ARM当单片机用啊~~~

尽量启用硬件SPI、DMA

使用特权

评论回复
7
古道热肠|  楼主 | 2009-3-28 11:36 | 只看该作者

当然最后肯定要用硬件SPI的,但俺深信优化还是大有益处的

贴上仿真时的汇编源程序,简单的移位变换处理,为什么要用到NOP指令,没整明白,哈哈,会ARM汇编的不妨指点指点.
    36:  
0x0010020C  E1A00C84  MOV       R0,R4,LSL #25
0x00100210  E1A04C20  MOV       R4,R0,LSR #24
    37:         Macro_Set_CLK_Low(); 
0x00100214  E1A00000  NOP       
   620:         pPio->PIO_CODR = flag; 
0x00100218  E3A00901  MOV       R0,#0x00004000
0x0010021C  E2401B13  SUB       R1,R0,#0x00004C00
0x00100220  E5810034  STR       R0,[R1,#0x0034]
   621: } 
0x00100224  E1A00000  NOP       
    38:         Macro_Set_CLK_High(); 
    39:      
    40: //        if(GetSDCard_SO_Value()) 
0x00100228  E3A01901  MOV       R1,#0x00004000
0x0010022C  E2400B13  SUB       R0,R0,#0x00004C00
0x00100230  EB0000D5  BL        AT91F_PIO_SetOutput(0x0010058C)
    41:         if(AT91F_PIO_GetInput( AT91C_BASE_PIOA) & SD_SO)  //内联函数,无调用开销 
    42:         { 
    43: //            ucReadData |= 0x01; 
0x00100234  E1A00000  NOP       
   586:         return pPio->PIO_PDSR; 
0x00100238  E59F00C8  LDR       R0,[PC,#0x00C8]
0x0010023C  E590003C  LDR       R0,[R0,#0x003C]
0x00100240  E3100A01  TST       R0,#0x00001000
0x00100244  0A000001  BEQ       0x00100250
    44:             ucReadData++; 
    45:         } 
    46:     } 
0x00100248  E2840001  ADD       R0,R4,#0x00000001
0x0010024C  E20040FF  AND       R4,R0,#0x000000FF
    33:     for(ucCount=8; ucCount; --ucCount) 
    34:     { 
    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; 
    44:             ucReadData++; 
    45:         } 
    46:     } 
0x00100250  E2450001  SUB       R0,R5,#0x00000001
0x00100254  E20050FF  AND       R5,R0,#0x000000FF
0x00100258  E3550000  CMP       R5,#0x00000000
0x0010025C  1AFFFFEA  BNE       0x0010020C
    47:     return(ucReadData); 
0x00100260  E1A00004  MOV       R0,R4
0x00100264  E8BD4070  LDMIA     R13!,{R4-R6,R14}
    48: } 
    49:  
    50: void  VS1003B_SPIPutChar(unsigned char ucSendData) 
0x00100268  E12FFF1E  BX        R14
    51: {       
    52: //    S0SPDR = c; 
    53: //    while((S0SPSR & 0x80) == 0);     //等待SPI将数据发送完毕 
    54:     uchar ucCount; 
    55:     uchar ucMaskCode; 
    56:  
0x0010026C  E92D4070  STMDB     R13!,{R4-R6,R14}
0x00100270  E1A04000  MOV       R4,R0
    57:     ucMaskCode = 0x80; 
0x00100274  E3A05080  MOV       R5,#0x00000080
    58:     for(ucCount=8; ucCount; --ucCount) 
    59:     { 
0x00100278  E3A06008  MOV       R6,#0x00000008
0x0010027C  EA000016  B         0x001002DC
    60:         Macro_Set_CLK_Low(); 
    61:  
0x00100280  E1A00000  NOP       
   620:         pPio->PIO_CODR = flag; 
0x00100284  E3A00901  MOV       R0,#0x00004000
0x00100288  E2401B13  SUB       R1,R0,#0x00004C00
0x0010028C  E5810034  STR       R0,[R1,#0x0034]
   621: } 
0x00100290  E1A00000  NOP       
    62:         if(ucMaskCode & ucSendData) 
    63:         { 
0x00100294  E1150004  TST       R5,R4
0x00100298  0A000003  BEQ       0x001002AC
    64:             Macro_Set_SI_High(); 
    65:         } 
    66:         else 
    67:         { 
0x0010029C  E3A01A02  MOV       R1,#0x00002000
0x001002A0  E2410B0B  SUB       R0,R1,#0x00002C00
0x001002A4  EB0000B8  BL        AT91F_PIO_SetOutput(0x0010058C)
0x001002A8  EA000005  B         0x001002C4
    68:             Macro_Set_SI_Low(); 
    69:         } 
    70:  
0x001002AC  E1A00000  NOP       
0x001002B0  E3A00A02  MOV       R0,#0x00002000
0x001002B4  E2401B0B  SUB       R1,R0,#0x00002C00
0x001002B8  E5810034  STR       R0,[R1,#0x0034]
0x001002BC  E1A00000  NOP       
0x001002C0  E1A00000  NOP       
    71:         Macro_Set_CLK_High(); 
0x001002C4  E3A01901  MOV       R1,#0x00004000
0x001002C8  E2410B13  SUB       R0,R1,#0x00004C00
0x001002CC  EB0000AE  BL        AT91F_PIO_SetOutput(0x0010058C)
    72:         ucMaskCode >>= 1; 
    73:  
    74:     } 
0x001002D0  E1A050C5  MOV       R5,R5,ASR #1
    58:     for(ucCount=8; ucCount; --ucCount) 
    59:     { 
    60:         Macro_Set_CLK_Low(); 
    61:  
    62:         if(ucMaskCode & ucSendData) 
    63:         { 
    64:             Macro_Set_SI_High(); 
    65:         } 
    66:         else 
    67:         { 
    68:             Macro_Set_SI_Low(); 
    69:         } 
    70:  
    71:         Macro_Set_CLK_High(); 
    72:         ucMaskCode >>= 1; 
    73:  
    74:     } 
0x001002D4  E2460001  SUB       R0,R6,#0x00000001
0x001002D8  E20060FF  AND       R6,R0,#0x000000FF
0x001002DC  E3560000  CMP       R6,#0x00000000
0x001002E0  1AFFFFE6  BNE       0x00100280
    75: } 

使用特权

评论回复
8
computer00| | 2009-3-28 13:09 | 只看该作者

我晕...你慢慢优化吧...俺直接上SPI和DMA...

使用特权

评论回复
9
hotpower| | 2009-3-28 13:16 | 只看该作者

俺也晕个~~~有SPI和DMA不用就是犯罪~~~

使用特权

评论回复
10
computer00| | 2009-3-28 13:20 | 只看该作者

哈哈……顶大叔,不但犯罪,还犯X~~~~

使用特权

评论回复
11
hotpower| | 2009-3-28 13:22 | 只看该作者

哈哈~~~ARM时代不浪费都是犯罪~~~

使用特权

评论回复
12
HWM| | 2009-3-28 14:56 | 只看该作者

哈哈~~~ARM时代乱归类都是犯罪~~~

都把SPI,DMA,...集成在芯片内了,为何不用呢?

哦,因为把那玩意儿当“单片机”用了。

相当精彩的逻辑!

使用特权

评论回复
13
古道热肠|  楼主 | 2009-3-28 15:24 | 只看该作者

我的乖乖,不能跟您们急了.说得是抛砖引玉,引来一堆口

即使用到ARM.需要优化的地方也很多.比如显示部分,比如流戏快速查找位表,比如快速贴BMP图.不要以为跨到ARM就可以高枕无忧了,曾看过老外用AT91SAM7S64在TFT的LCD上做的仿真钟,就用全汇编写的,为啥?追求速度.但俺不提倡全盘用汇编,我的理解是会用汇编比一无所知好.知道如何优化比不知道好.

使用特权

评论回复
14
古道热肠|  楼主 | 2009-3-29 09:46 | 只看该作者

哈哈,终于搞定了,原来是优化等级设定不当

把优化等级设成level -3 播放320Kbps的MP3,MCU还有很多空闲时间向串口喊叫"I am Free"

使用特权

评论回复
15
alex74| | 2009-3-29 09:49 | 只看该作者

...

ARM编译器出名的好,你基本不可能写出汇编比编译器编出来的还快

使用特权

评论回复
16
古道热肠|  楼主 | 2009-3-29 09:49 | 只看该作者

谢谢NetJob等,贴上一个用于测试的完整MDK项目,专测串并转换用

使用特权

评论回复
17
古道热肠|  楼主 | 2009-3-29 09:54 | 只看该作者

MDK的优化页面内容如下,熟悉的朋友讲讲具体功能

找MDK自带的帮助,也没发现详细的介绍.

使用特权

评论回复
18
渤海三叠浪| | 2009-3-29 10:14 | 只看该作者

楼上画面看起来不错啊

用的电脑是宽屏么??

使用特权

评论回复
19
wangkj| | 2009-3-30 08:38 | 只看该作者

鼓捣热肠,最终将成为at91sam7s的砖家

佩服,俺太偷懒了,能省事就省事。

使用特权

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

呵呵,是打算把它当砖头用.还蛮结实的

有次焊接时调了1个180度,通电后发现不对劲,再转回来焊,还能用.

使用特权

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

本版积分规则

284

主题

6411

帖子

16

粉丝