我试图在使用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__));
提前谢谢!
答案 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”一次,你要确保端口中存在位名并且该位存在。