2

我在使用 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);
}

我想使用 myButton_instantRead()来读取任何端口,只需给它一个 ID 号。我使用我的 init 函数来设置哪个引脚与哪个端口相关联。但是由于某种原因,当我调用我的Button_instantRead()函数时,即使按下开关,我也没有得到 1。

我使用注释行在我的主文件中尝试了我的配置,一切正常。

我在我的return行中做错了什么?

经过一番谷歌搜索后,我发现这char可能不是引用端口的正确类型。我想我会更适合指向端口地址的第一个元素的指针,但我也不知道该怎么做,也找不到答案。

4

2 回答 2

2

我建议查找PINBfirst 的定义。我发现这个链接到一个似乎引用了正确头文件的 power point 演示文稿。

值得注意的文件是:

  1. sfr_defs.h
  2. iom328p.h

定义自己的指向 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使用 struct member 并发现这个 SO questionthis other SO question很有趣。

编辑2:

如果您使用的是gcc(我认为您不是,因为它是 AVR,但我可能是错的)您可以跳过找出确切类型的步骤PINB并声明您的结构如下:

typedef struct {
    typeof(PINB)* port;
    uint8_t pin;
    unsigned long timestamp;
};

typeof运算符是 C 语言的gcc扩展,因此您可能无法使用它,但最好了解它。

于 2013-09-24T10:49:06.833 回答
1

PINB易挥发吗?这不是端口的实际读取吗?Button_init如果是这样,您在not in 中读取端口的值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
    }
}
于 2013-09-24T03:07:39.647 回答