stly 发表于 2022-10-13 19:18

一条取结构体数组元素的指令要花费几十个系统指令周期

typedef void (*PFV1)(UINT8 *pBuf);

typedef struct
{
    UINT16 LongTime;         /* 长按键生效时间,0表示非长按键*/
    UINT8ReentryTime;      /* 长按键重复生效时间,0表示键值不重复生效*/
    UINT8FiltTime;         /* 去抖滤波时间      */
    PFV1   keyFuncDown;      /* 按键按下,所调用函数的指针*/
    PFV1   keyFuncUp;          /* 按键弹起,所调用函数的指针*/
    PFV1   keyFuncLong;      /* 按键长按,所调用函数的指针*/
   
}KeyElem_TypeDef;

// 按键元素表
KeyElem_TypeDef const sKeyElemTbl = {
{    600,    0,      4,   KEY_0_FUNC_DOWN,   KEY_0_FUNC_UP,    KEY_0_FUNC_LONG}, // KEY_0
{    150,    20,      4,   KEY_1_FUNC_DOWN,   KEY_1_FUNC_UP,    KEY_1_FUNC_LONG}, // KEY_1
{    0,      0,      4,   KEY_2_FUNC_DOWN,   KEY_2_FUNC_UP,    KEY_2_FUNC_LONG}, // KEY_2
{    150,    20,      4,   KEY_3_FUNC_DOWN,   KEY_3_FUNC_UP,    KEY_3_FUNC_LONG}, // KEY_3
{    0,      0,      4,   KEY_4_FUNC_DOWN,   KEY_4_FUNC_UP,    KEY_4_FUNC_LONG}, // KEY_4
{    0,      0,      4,   KEY_5_FUNC_DOWN,   KEY_5_FUNC_UP,    KEY_5_FUNC_LONG}, // KEY_5
{    150,    20,      4,    KEY_6_FUNC_DOWN,   KEY_6_FUNC_UP,    KEY_6_FUNC_LONG}, // KEY_6, KEY_0和KEY_1组合
{    150,    20,      4,    KEY_7_FUNC_DOWN,   KEY_7_FUNC_UP,    KEY_7_FUNC_LONG   }// KEY_7, KEY_0和KEY_3组合

};
if( pKeyElem->LongTime > 0 )

就这么一条指令,要开销33个系统指令周期,让人崩溃。

songqian17 发表于 2022-10-13 19:20

看看面向对象的方法,容易理解了就......

stly 发表于 2022-10-13 19:23

编译器是XC8,一条取结构体数组元素的指令居然要调用函数库乘法子程序,巨耗时间。

KeysState |= sKeyVar.KeyState;

这条指令要调用下面的乘法子程序

// 8 x 8 bit multiplication with 8 bit result

unsigned char
__bmul(unsigned char multiplier, unsigned char multiplicand)
{
    unsigned char product = 0;

#if defined(__OPTIMIZE_SPEED__)

    if(multiplier & 0x01)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x02)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x04)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x08)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x10)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x20)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x40)
      product = (product + multiplicand) & 0xff;
    multiplicand <<= 1;

    if(multiplier & 0x80)
      product = (product + multiplicand) & 0xff;

#else
    do {
      if(multiplier & 1)
            product += multiplicand;
      multiplicand <<= 1;
      multiplier >>= 1;
    } while(multiplier != 0);

#endif
    return product;
}

xxrs 发表于 2022-10-13 19:25

你那数据不适合8位机操作,能给你结果就不错了。如果这样的数据过多还有速度要求,说明你的芯片选错了。8位机的优势不在这里

zhanghqi 发表于 2022-10-13 19:27


指针不适合于普通的PIC单片机

stly 发表于 2022-10-13 19:29

8位机就是价格有优势,没其他了

stly 发表于 2022-10-13 19:31

用结构体是为了让程序清晰一些,即使不用函数指针数组,但参数这样的数组还是必须的,问题是一条取数组元素的指令也要十几个系统指令周期,PIC 8位中、低档伤不起。近些年出的高频版本如16F15xx,时钟到16M,一般的应用就不太要考虑如结构体引用开销大这样的问题,但早期的16F73这样的8位MCU真是没办法。

chuxh 发表于 2022-10-13 19:36


看指令就知道了,指针这种操作最适合ARM内核

renyaq 发表于 2022-10-13 19:38

pic的指令系统确实不太适合用指针,还是尽量用简单的语句吧。

zhuhuis 发表于 2022-10-13 19:42

另外编译器也不够智能,否则应该也可以少用几条指令。
页: [1]
查看完整版本: 一条取结构体数组元素的指令要花费几十个系统指令周期