PIC将SFR地址传递给C中的功能

时间:2014-10-12 02:31:46

标签: c types io embedded arguments

我试图在使用C的PIC24F MCU上将I / O引脚的引用作为函数参数传递。对于PIC,器件头文件通过以下方式访问I / O缓冲寄存器:

LATAbits.LATA2 = 0;    // sets the pin (RA2 in this case) low.
if (PORTAbits.RA3) {   // reads the state of the pin. (RA3)

我想做这样的事情:

int main() {
    Configure();                        // Sets up peripherals, etc. 
    WaitForHigh(PORTAbits.RA3);         // waits for pin RA3 to go hi. 
    ...

    return 0;
}

void WaitForHigh( ?datatype? pin_reference ) { 

    while( !pin_reference );            // Stays here until the pin goes hi.
}

那么我想在这里传递什么数据类型?当我查看那个引脚时,实际上发生了什么?下面,我从我正在使用的PIC24F器件头中复制相关部分,以防它有用。

#define PORTA PORTA
extern volatile unsigned int  PORTA __attribute__((__sfr__));
typedef struct tagPORTABITS {
  unsigned RA0:1;
  unsigned RA1:1;
  unsigned RA2:1;
  unsigned RA3:1;
  unsigned RA4:1;
  unsigned RA5:1;
} PORTABITS;
extern volatile PORTABITS PORTAbits __attribute__((__sfr__));

提前谢谢!

3 个答案:

答案 0 :(得分:4)

作为使用宏的替代方法,函数既可以接受PORT寄存器地址(或锁存寄存器地址,例如,在配置为输出的引脚的情况下为LATA),也可以接受寄存器中的位掩码。需要。例如:

#include<p24FV32KA301.h>   // defines both PORTA and _PORTA_RA3_MASK 

void WaitForHigh( volatile unsigned int * port, pin_mask ) { 

    while( !(*port & pin_mask) );           // Stays here until the pin goes hi.
}


int main() 
{
    ...
    WaitForHigh( &PORTA, _PORTA_RA3_MASK );         // waits for pin RA3 to go hi. 
    ...

    return 0;
}

答案 1 :(得分:1)

请注意,PORT位值是通过位字段获得的,因此,回答您的问题,您不能。位字段没有地址,因此您无法将其作为指向函数的指针传递。

相反,您可以使用宏:

#define WaitForHigh(p) do{while(!(p));}while(0)

宏确实有它在代码可读性上的缺点,但是,如果采取适当的谨慎,有些情况下它们是最好的解决方案。如果宏 是此Q&amp; A中的最佳解决方案,那是有争议的,但重要的是要提及。


感谢评论者提出改善宏观安全性的建议。

答案 2 :(得分:0)

您可以将预处理器处理与函数结合起来,以便通过编译时检查符号来获得您想要的内容。例如:

#define PORT_FUNC(f, p, b) f(p, b)
#define WaitForHigh(p, b) PORT_FUNC(WaitForHighImp, &p, _ ##p## _ ##b## _MASK)

void WaitForHighImp(volatile unsigned* p, unsigned char mask)
{
    while (!(*p & m))
        ;
}

int main()
{
    WaitForHigh(PORTA, RA3);
}

这种方法的优点是你在网上说“PORTA”一次,在调用时说“RA3”一次,你要确保端口中存在位名并且该位存在。