【问题标题】:Arduino class initialization executionArduino类初始化执行
【发布时间】:2018-03-10 18:19:26
【问题描述】:

我正在尝试为 UNO 板编写一个简单的固件,该板能够在按下按钮时切换 LCD (16x2) 显示屏的内容。我尝试使用类和标题来编写它,以便可以更轻松地向代码中添加更多按钮。问题是我的类初始化方法在while(1) 循环之外不起作用,如下所示。

这根本不起作用:

ma​​in.ino

#include "button.h"

#include <avr/io.h>
#include <util/delay.h>
#include <LiquidCrystal.h>

//Buttons PORTX register
#define buttonPortx PORTD
//Buttons DDRx register
#define buttonDdrx DDRD
//Buttons PINx register
#define buttonPinx PIND
//Buttons pins definition
#define B0 PD2
#define B1 PD3
#define B2 PD4
#define B3 PD5

//LCD pins definition
#define RS A5
#define EN A4
#define D4 A3
#define D5 A2
#define D6 A1
#define D7 A0

LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
Button button1 = Button();

int main()
{
  buttonDdrx = (0 << B0) | (0 << B1) | (0 << B2) | (0 << B3);
  buttonPortx = (1 << B0) | (1 << B1) | (1 << B2) | (1 << B3);

  //My initialization method:
  button1.Initialize(buttonPinx, B0);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(5,0);
  lcd.print("Hello!");

  while (1)
  {
    if (button1.IsReleased())
    {
      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("Pressed!");
      while (1);
    }
    _delay_ms(50);
  }
}

但是这个效果很好:

ma​​in.ino

#include "button.h"

#include <avr/io.h>
#include <util/delay.h>
#include <LiquidCrystal.h>

//Buttons PORTX register
#define buttonPortx PORTD
//Buttons DDRx register
#define buttonDdrx DDRD
//Buttons PINx register
#define buttonPinx PIND
//Buttons pins definition
#define B0 PD2
#define B1 PD3
#define B2 PD4
#define B3 PD5

//LCD pins definition
#define RS A5
#define EN A4
#define D4 A3
#define D5 A2
#define D6 A1
#define D7 A0

LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
Button button1 = Button();

int main()
{
  buttonDdrx = (0 << B0) | (0 << B1) | (0 << B2) | (0 << B3);
  buttonPortx = (1 << B0) | (1 << B1) | (1 << B2) | (1 << B3);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(5,0);
  lcd.print("Hello!");

  while (1)
  {
    //My initialization method:
    button1.Initialize(buttonPinx, B0);
    if (button1.IsReleased())
    {
      lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("Pressed!");
      while (1);
    }
    _delay_ms(50);
  }
}

还有我的头文件/cpp 文件:

button.h

#ifndef Button_h
#define Button_h

class Button
{
  public:
    Button();
    void Initialize(int port, int pin);
    bool IsReleased();
  private:
    bool pressed = false;
    int _port;
    int _pin;
};

#endif

button.cpp

#include "button.h"

Button::Button()
{

}

void Button::Initialize(int port, int pin)
{
  _port = port;
  _pin = pin;
}

bool Button::IsReleased()
{
  if (!(_port & (1 << _pin)) && (pressed == false))
  {
    pressed = true;
  }
  if ((_port & (1 << _pin)) && (pressed == true))
  {
    pressed = false;
    return true;
  }
  return false;
}

我使用带有参数的 C++ 类构造函数来设置 _port_pin 值,但在查看 this 论坛帖子后,我创建了 Initialize(int port, int pin) 方法,但仍然无法解决问题。

任何帮助将不胜感激!

【问题讨论】:

    标签: c++ class oop arduino lcd


    【解决方案1】:

    您的 _port 变量是简单的 int。它不会从真正的PINx 寄存器中得到任何东西。它至少应该是指向字节的 volatile 指针(并且被取消引用)。

    【讨论】:

    • 感谢您的回答 :) !我将修改我的代码。但是我仍然不明白为什么当Initialize 方法处于循环中时它会起作用。你能帮我解决这个问题吗?根据PINx 寄存器状态,我尝试打印int 变量_port 的值,这似乎是合法的。是什么让我对一切变得更加陌生。
    • @KawaungaXDG 当你调用 Initialize 时,你会读取相应的 PINx 寄存器的内容并将其存储为 _port。但这只是一个副本。这不是实际的 PINx 状态,而是调用 Initialize 时的 PINx 状态。
    • 哦,现在说得通了!感谢您的解释!真的很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    相关资源
    最近更新 更多