void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void) // 5 Hz
__attribute__
指令或宏来自GCC,但__interrupt__
和no_auto_psv
不是,它是特定于硬件的。那么,GCC编译器如何理解__interrupt__
和no_auoto_psv
,我搜索过,并没有在其他任何地方找到任何声明。
所以基本上_T1Interrupt
函数不带参数,只返回属性吗?
答案 0 :(得分:2)
答案 1 :(得分:2)
特别是,这些属性是Microchip XC16编译器中用于16位PIC24和dsPIC的特定于平台的扩展。
属性本质上是添加到编译器的解析树的额外信息。它们存在于C语言语义之外,可以提供编译器用来与您的期望保持一致的其他信息。在这种情况下,__interrupt__
告诉它将函数视为ISR(函数prolog和epilog与正常函数略有不同:dsPIC ISR使用RETFIE
返回指令,而RETURN
表示no_auto_psv
正常函数),PSVPAG
控制编译器是否设置{{1}}寄存器:
使用no_auto_psv属性省略了将PSVPAG值重新初始化为auto psv变量(const或放置在空间auto_psv中的变量)的默认值的代码。如果您的代码没有明确地或使用编译器管理的 psv 或 prog 限定符修改PSVPAG寄存器,那么使用no_auto_psv是安全的。此外,如果您的中断服务程序(或中断服务程序调用的函数)不使用任何const或空格auto_psv变量,那么使用no_auto_psv是安全的。
答案 2 :(得分:1)
unwind说的是真的,而attritbute是由gcc的MPLAB扩展定义的。自从我使用微控制器以来已经有一段时间了,所以我无法在这方面提供更多细节。但是对于您的特定应用(嵌入式c pic微控制器)。以上是声明一个函数的正确方法,该函数用于实现定时器1的中断子程序。中断子程序很少返回任何内容,如果需要捕获寄存器中的值,我建议您使用以下结构作为全局变量:
typedef struct T1OUT
{
int timer_register_value;
int flag;
} T1InteruptCapture;
timer_register_value是您想要从子例程中取出的值。而标志值是内存锁定,可防止子例程覆盖以前的值。有不同的方法可以从子例程中获取值。我发现这是最简单,最有效的时间。您还可以考虑实现一个迷你缓冲区。我建议你避免使用嵌入式C的指针。在过去的几年里,我不知道事情是否发生了变化。
编辑1:MPLAB有一些我见过的最好的文档。我建议您查看特定微控制器的那个。他们提供了很好的解释示例代码。
编辑2:我不确定你为什么要使用gcc。我建议你从MPLAB获得pic编译器。我相信它被称为C30。和相关的.h文件。