用指针AVR端口屏蔽寄存器

Masking a Register Using Its Pointer - AVR Ports

本文关键字:屏蔽寄存器 AVR 指针      更新时间:2023-10-16

我正在使用一些led和按钮使用微处理器(atmega32)编程西蒙说游戏。我试图将指针存储到一个数组中的PORT寄存器,该函数将用于掩盖寄存器(打开引脚以点亮LED),具体取决于按下哪个按钮。

类似

的内容
*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;
}

多年来我编写了许多设备驱动程序。所以,我想我至少看到了你的一个问题。

我必须做一些样式清理来消除长侧边栏注释。大多数风格指南建议宽度不要超过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;
}