使用其指针屏蔽寄存器 - AVR 端口
Masking a Register Using Its Pointer - AVR Ports
我正在使用一些 LED 和按钮使用微处理器 (atmega32) 编写 Simon Says 游戏。我正在尝试将指向 PORT 寄存器的指针存储在一个数组中,该函数将根据按下的按钮使用该函数来屏蔽寄存器(打开引脚以点亮 LED)。
类似于
*arrayOfPointers[1] |= 1 << mask;
但我认为这行不通,我认为这是因为我不完全理解屏蔽或指针的工作原理。
当我将指向该寄存器的指针存储在指针数组中时,如何屏蔽该寄存器?请注意我是beginner/novice,所以请像我很笨一样解释。
这里是相关代码的简化示例:
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;
}
我正在使用一些 LED 和按钮使用微处理器 (atmega32) 编写 Simon Says 游戏。我正在尝试将指向 PORT 寄存器的指针存储在一个数组中,该函数将根据按下的按钮使用该函数来屏蔽寄存器(打开引脚以点亮 LED)。
类似于
*arrayOfPointers[1] |= 1 << mask;
但我认为这行不通,我认为这是因为我不完全理解屏蔽或指针的工作原理。
当我将指向该寄存器的指针存储在指针数组中时,如何屏蔽该寄存器?请注意我是beginner/novice,所以请像我很笨一样解释。
这里是相关代码的简化示例:
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;
}