Маскировка регистра с помощью указателя — порты AVR

Я программирую игру Simon Says с микропроцессором (atmega32), используя несколько светодиодов и кнопок. Я пытаюсь сохранить указатели на регистр PORT в массиве, который функция будет использовать для маскирования регистра (для включения выводов, чтобы зажечь светодиод) в зависимости от того, какая кнопка нажата.

Нечто подобное

*arrayOfPointers[1] |= 1 << mask;

Но я не думаю, что это работает, и я думаю, что это потому, что я не совсем понимаю, как работают маскировка или указатели.

Как замаскировать регистр, если указатель на этот регистр хранится в массиве указателей? Пожалуйста, обратите внимание, что я новичок / новичок, поэтому, пожалуйста, объясните, что я тупой.

Вот упрощенный пример соответствующего кода:

volatile uint8_t *portActivate[numberOfButtons]; //stores pointers to the PORT register
unsigned char pinActivate[numberOfButtons];  //stores the pin I want to turn on

//activateOnPress populates 2 arrays that stores the PORT and PIN corresponding to each button. (index 0 is for button 0, index 1 is for button 1, etc.)
//this will be used to tell the program which PORT and PIN to activate (output a voltage) when that button is pressed.
void activateOnPress(unsigned int buttonNumber, volatile uint8_t *activatePort, unsigned char activatePin){
*portActivate[buttonNumber] = *activatePort;    //store the pointer to PORT register in an array
pinActivate[buttonNumber] = activatePin;    //store the pin to be turned on at that port
}

//buttonListen will see if the specified button has been pressed (voltage on pin is 0)
//if it has, it will output a voltage to the associated pin given by my 2 arrays by masking the register pointed to by the *portActivate array.
void buttonListen(unsigned int buttonNumber,unsigned char buttonPort, unsigned char buttonPin){
if(bit_is_clear(buttonPort, buttonPin)){    //bit_is_clear means the pin is showing 0V
*portActivate[buttonNumber] |= 1 << pinActivate[buttonIndex];  //this is the part thats not working!!!!
}
}

int main(void){
activateOnPress(1, &PORTB, PIN0);  //associate button 1 to PORT B, PIN 0, which I want to activate (output 5V) when this button is pressed

while(1){
buttonListen(1, PORTA, PIN1); //listen to PORT A, PIN 1. If it's pressed, then output a voltage to the port and pin associated with button 1.
}
return 0;
}

Буду признателен за любую помощь.

0

Решение

Я написал много драйверов устройств за эти годы. Итак, я думаю, что вижу [по крайней мере одну из] ваших проблем.

Я должен был сделать некоторую очистку стиля, чтобы устранить длинные комментарии боковой панели. Большинство руководств по стилю рекомендуют не шире, чем 80. Это затрудняет чтение кода. Я должен был сделать это, чтобы я мог понять вашу логику.

Также у вас было два параллельных массива, проиндексированных по номеру кнопки. Я объединил их в структуру, которая лучше связывает данные.

В любом случае, вот исправленный код с исправлением ошибки (подсказка: #if):

struct portpin {
// stores pointers to the PORT register
volatile uint8_t *portActivate;

// stores the pin I want to turn on
unsigned char pinActivate;
};
typedef struct portpin portpin_t;

portpin_t portlist[numberOfButtons];

// activateOnPress populates 2 arrays that stores the PORT and PIN corresponding
// to each button. (index 0 is for button 0, index 1 is for button 1, etc.)
// this will be used to tell the program which PORT and PIN to activate (output
// a voltage) when that button is pressed.
void
activateOnPress(unsigned int butno,volatile uint8_t *activatePort,
unsigned char activatePin)
{
portpin_t *port;

port = &portlist[butno];

// store the pointer to PORT register in an array
#if 0
*port->portActivate = *activatePort;  // your code
#else
port->portActivate = activatePort;  // fixed code
#endif

// store the pin to be turned on at that port
port->pinActivate = activatePin;
}

// buttonListen will see if the specified button has been pressed (voltage on
// pin is 0) if it has, it will output a voltage to the associated pin given by
// my 2 arrays by masking the register pointed to by the *portActivate array.
void
buttonListen(unsigned int butno,unsigned char buttonPort,
unsigned char buttonPin)
{
portpin_t *port;

port = &portlist[butno];

// bit_is_clear means the pin is showing 0V
if (bit_is_clear(buttonPort, buttonPin)) {
// this is the part thats not working!!!!
*port->portActivate |= 1 << port->pinActivate;
}
}

int
main(void)
{

// associate button 1 to PORT B, PIN 0, which I want to activate (output 5V)
// when this button is pressed
activateOnPress(1, &PORTB, PIN0);

// listen to PORT A, PIN 1. If it's pressed, then output a voltage to the
// port and pin associated with button 1.
while (1)
buttonListen(1, PORTA, PIN1);

return 0;
}
1

Другие решения

Других решений пока нет …