1

首先,我为我的 PIC 使用 C18 编译器。当我在没有任何调用的情况下创建像 high_ISR 这样的函数时,我的编译器会向它添加代码,我只能在反汇编列表视图中看到代码。这使我的 high_ISR 函数的周期时间为 160 个周期(但看 C 代码似乎是空的)。

相反,如果我将它定义为一个宏,我将让它没有“秘密”代码。我会以某种方式对其他函数有问题,导致删除我的编译器偷偷放在那里的代码,它会以其他方式应对吗?

我的意思是,我希望 ISR 快速。在 ac 文件中编写函数时,有没有办法让 ISR 函数快速运行,我可以以某种方式抑制“秘密代码”。

请参阅下面的代码示例:

在 .c 文件中正确创建我的 high_ISR 函数,但循环时间很长

#pragma interrupt highISR
void highISR(void)
{
    SomeFunction();
}

例如在我的头文件中创建的宏函数(比如 16 个周期的周期时间)

#define FAST_INTERRUPT           \
    void highISR(void)           \
    {                            \
        SomeFunction();          \
    }

只是为了澄清,如果我使用宏,我将其实现为:

#pragma interrupt higISR
    FAST_INTERRUPT

第一个 highISR 声明产生了这个:

    #pragma interrupt highISR
323: void highISR(void)
 12B12    CFDA     MOVFF 0xfda, 0xfe4
 12B14    FFE4     NOP
 12B16    CFE2     MOVFF 0xfe2, 0xfda
 12B18    FFDA     NOP
 12B1A    CFE9     MOVFF 0xfe9, 0xfe4
 12B1C    FFE4     NOP
 12B1E    CFEA     MOVFF 0xfea, 0xfe4
 12B20    FFE4     NOP
 12B22    CFD9     MOVFF 0xfd9, 0xfe4
 12B24    FFE4     NOP
 12B26    CFDA     MOVFF 0xfda, 0xfe4
 12B28    FFE4     NOP
 12B2A    C1FB     MOVFF 0x1fb, 0xfe4
 12B2C    FFE4     NOP
 12B2E    C1FC     MOVFF 0x1fc, 0xfe4
 12B30    FFE4     NOP
 12B32    C1FD     MOVFF 0x1fd, 0xfe4
 12B34    FFE4     NOP
 12B36    C1FE     MOVFF 0x1fe, 0xfe4
 12B38    FFE4     NOP
 12B3A    CFF6     MOVFF 0xff6, 0xfe4
 12B3C    FFE4     NOP
 12B3E    CFF7     MOVFF 0xff7, 0xfe4
 12B40    FFE4     NOP
 12B42    CFF8     MOVFF 0xff8, 0xfe4
 12B44    FFE4     NOP
 12B46    CFF5     MOVFF 0xff5, 0xfe4
 12B48    FFE4     NOP
 12B4A    CFF3     MOVFF 0xff3, 0xfe4
 12B4C    FFE4     NOP
 12B4E    CFF4     MOVFF 0xff4, 0xfe4
 12B50    FFE4     NOP
 12B52    CFFA     MOVFF 0xffa, 0xfe4
 12B54    FFE4     NOP
 12B56    CFFB     MOVFF 0xffb, 0xfe4
 12B58    FFE4     NOP
 12B5A    EE05     LFSR 0, 0x500
 12B5C    F000     NOP
 12B5E    0E12     MOVLW 0x12
 12B60    04E8     DECF 0xfe8, W, ACCESS
 12B62    E303     BNC 0x12b6a
 12B64    CFEE     MOVFF 0xfee, 0xfe4
 12B66    FFE4     NOP
 12B68    D7FB     BRA 0x12b60
 12B6A    52E6     MOVF 0xfe6, F, ACCESS
324:                    {
325:                        SomeFunction();
 12B6C    EC48     CALL 0x14090, 0
 12B6E    F0A0     NOP
327:                    }
 12B70    52E5     MOVF 0xfe5, F, ACCESS
 12B72    EE05     LFSR 0, 0x511
 12B74    F011     NOP
 12B76    0E12     MOVLW 0x12
 12B78    04E8     DECF 0xfe8, W, ACCESS
 12B7A    E303     BNC 0x12b82
 12B7C    CFE5     MOVFF 0xfe5, 0xfed
 12B7E    FFED     NOP
 12B80    D7FB     BRA 0x12b78
 12B82    CFE5     MOVFF 0xfe5, 0xffb
 12B84    FFFB     NOP
 12B86    CFE5     MOVFF 0xfe5, 0xffa
 12B88    FFFA     NOP
 12B8A    CFE5     MOVFF 0xfe5, 0xff4
 12B8C    FFF4     NOP
 12B8E    CFE5     MOVFF 0xfe5, 0xff3
 12B90    FFF3     NOP
 12B92    CFE5     MOVFF 0xfe5, 0xff5
 12B94    FFF5     NOP
 12B96    CFE5     MOVFF 0xfe5, 0xff8
 12B98    FFF8     NOP
 12B9A    CFE5     MOVFF 0xfe5, 0xff7
 12B9C    FFF7     NOP
 12B9E    CFE5     MOVFF 0xfe5, 0xff6
 12BA0    FFF6     NOP
 12BA2    CFE5     MOVFF 0xfe5, 0x1fe
 12BA4    F1FE     NOP
 12BA6    CFE5     MOVFF 0xfe5, 0x1fd
 12BA8    F1FD     NOP
 12BAA    CFE5     MOVFF 0xfe5, 0x1fc
 12BAC    F1FC     NOP
 12BAE    CFE5     MOVFF 0xfe5, 0x1fb
 12BB0    F1FB     NOP
 12BB2    CFE5     MOVFF 0xfe5, 0xfda
 12BB4    FFDA     NOP
 12BB6    CFE5     MOVFF 0xfe5, 0xfd9
 12BB8    FFD9     NOP
 12BBA    CFE5     MOVFF 0xfe5, 0xfea
 12BBC    FFEA     NOP
 12BBE    CFE5     MOVFF 0xfe5, 0xfe9
 12BC0    FFE9     NOP
 12BC2    CFE5     MOVFF 0xfe5, 0xfda
 12BC4    FFDA     NOP
 12BC6    0011     RETFIE 0x1

第二个函数只产生这个 ->

322:      #pragma interrupt highISR
323:          FAST_INTERRUPT
 13742    CFDA     MOVFF 0xfda, 0xfe4
 13744    FFE4     NOP
 13746    CFE2     MOVFF 0xfe2, 0xfda
 13748    FFDA     NOP
 1374A    52E6     MOVF 0xfe6, F, ACCESS
 1374C    0105     MOVLB 0x5
 1374E    5140     MOVF 0x40, W, BANKED
 13750    1A77     XORWF 0xf77, F, ACCESS
 13752    96A4     BCF 0xfa4, 0x3, ACCESS
 13754    2877     INCF 0xf77, W, ACCESS
 13756    6078     CPFSLT 0xf78, ACCESS
 13758    86A4     BSF 0xfa4, 0x3, ACCESS
 1375A    7E8B     BTG 0xf8b, 0x7, ACCESS
 1375C    0011     RETFIE 0x1
 1375E    52E5     MOVF 0xfe5, F, ACCESS
 13760    CFE5     MOVFF 0xfe5, 0xfda
 13762    FFDA     NOP
 13764    0011     RETFIE 0x1

进一步澄清只是为了表明它们自己的功能是相同的:对于第一个 rutine ->

void SomeFunction(void)
{
    if(PIR3bits.TMR4IF)
    {
        PIR3bits.TMR4IF = 0; 

        PR4 ^= _SoftPWM_Toggle;

        _asm
            INCF PR4,0,ACCESS 
            CPFSLT TMR4,ACCESS 
        _endasm

            PIR3bits.TMR4IF = 1; 

        SOFT_PWM_PIN ^= 1;
    }
}

标题中的第二个作为宏->

#define FAST_INTERRUPT \
    void highISR(void) \
    { \
        PR4 ^= _SoftPWM_Toggle; \
        \
        PIR3bits.TMR4IF = 0; \
        \
        _asm \
            INCF PR4,0,ACCESS \
            CPFSLT TMR4,ACCESS \
        _endasm \
        \
            PIR3bits.TMR4IF = 1; \
        \
        SOFT_PWM_PIN ^= 1; \
        \
        _asm \
            RETFIE 1 \
        _endasm \
    }
4

1 回答 1

2

我不认为它在你的运行时是垃圾。请记住,主行代码中的任何地方都可能发生中断。当您从中断中返回时,您会期望您的代码以与中断相同的状态继续运行。编译器添加的是在 ISR 开始时保存该状态的代码,然后在中断结束时恢复该状态。如果它不这样做,并且您在 ISR 中修改了主线代码正在使用的寄存器或内存位置,那么当 ISR 返回时代码不会按预期执行的可能性很大。通过消除编译器生成的代码,您已将责任移交给 ISR,以保存并恢复主线代码的状态。如果你能保证你会没事的(一个空的 ISR 就是一个例子,它永远不会改变状态)。如果你不能,当您从 ISR 返回主行代码时,将会发生奇怪的代码执行。如果您使用的是高级编译语言,则很难知道它在幕后使用了什么,因此让编译器为您生成状态保存代码 ISR 比尝试自己做更安全。

我建议您查看 MPLAB® C18 C 编译器用户指南文档。#pragma interupt 指令还有其他参数,允许您在一定程度上自定义保存的状态信息。

于 2012-01-20T22:54:26.737 回答