我对struct有一点问题,并从atmega328p定义。
我有以下代码:
typedef struct {
char port;
unsigned char pin;
unsigned long timestamp;
} BUTTONS;
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
BUTTONS* button[BUTTONS_ID_COUNT] = {&button_1,&button_2,&button_3};
void Button_init(void){
button[BUTTONS_ID_1]->port = PINB;
button[BUTTONS_ID_1]->pin = PINB4;
button[BUTTONS_ID_1]->timestamp = 0;
}
unsigned char Button_instantRead(int id){
//return PINB & (1 << PINB4);
return button[id]->port & (1 << button[id]->pin);
}
我想使用我的Button_instantRead()
只能给它一个ID号来读取任何端口。我使用我的init函数来设置哪个引脚与哪个端口相关联。但由于某种原因,当我调用Button_instantRead()
功能时,即使按下开关,我也不会得到1。
我使用注释行在我的主文件中尝试了我的配置,一切都运行得很好。
我在return
行中做错了什么?
经过一些谷歌搜索后,我发现char
可能不是引用端口的正确类型。我想我会更好地使用指向端口地址的第一个元素的指针,但我又不知道怎么做,也找不到答案。
答案 0 :(得分:2)
我建议先查看PINB
的定义。我发现了this link到功能点演示文稿,它似乎引用了正确的头文件。
值得注意的文件是:
您需要定义自己指向PINB的指针所需的所有信息。
以下内容应该按照您的要求运行:
typedef struct {
volatile uint8_t * port;
uint8_t pin;
unsigned long timestamp;
} BUTTONS;
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
BUTTONS* button[BUTTONS_ID_COUNT] = {&button_1,&button_2,&button_3};
void Button_init(void){
button[BUTTONS_ID_1]->port = &PINB;
button[BUTTONS_ID_1]->pin = PINB4;
button[BUTTONS_ID_1]->timestamp = 0;
}
unsigned char Button_instantRead(int id){
//return PINB & (1 << PINB4);
return *(button[id]->port) & (1 << button[id]->pin);
}
请注意,端口是一个指针。
修改强>
我必须检查自己volatile
结构成员的使用情况,发现this SO question和this other SO question非常有趣。
编辑2:
如果您正在使用 gcc (我认为您不是因为它是AVR但我可能错了)您可以跳过找出PINB
的确切类型的步骤是,并按如下方式声明您的结构:
typedef struct {
typeof(PINB)* port;
uint8_t pin;
unsigned long timestamp;
};
typeof
operator是C语言的 gcc 扩展程序,因此您可能无法使用它,但了解它是很好的。
答案 1 :(得分:1)
PINB
是否有波动?那不是实际读取的端口吗?如果是,则在Button_init
中读取端口的值,而不是Button_instantRead
。
换句话说,button[id]->port
包含在Button_init中读取时的端口值,而不是稍后可以使用的对PINB的引用。
小心:自从我做完atmega之后已经有好几年了。
你可以这样重新编码:
unsigned char Button_instantRead(int id){
switch(id) {
case ID_A: return PINA & (1 << button[id]->pin);
case ID_B: return PINB & (1 << button[id]->pin);
// etc
}
}