当我尝试操作端口而不是使用 pinMode() 和 digitalWrite() 时,我的 Arduino 代码停止工作

问题描述 投票:0回答:1

未注释的代码工作得很好,但正如你所看到的,我已经注释了所有与端口相关的行,我认为这些行应该与未注释的行等效,但是当我取消注释这些代码并注释其他代码时,代码只是不执行任何操作。

我正在为大学作业使用 LCD,我的 arduino 是 Arduino Leonardo。 LCD控制器是HITACHI的hd44780u。函数 set_byte 会反转字节,因为我的连接也反转了(Arduino 引脚 0 连接到 LCD 的引脚 7)。

#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))

// Sets up all pin modes
void setup() {
  // TODO: cambiar esto y ponerlo con sbi por eficiencia
  //DDRD |= B11111111;  // Configura todos los pines de PORTD como salida
  //DDRB |= B00000111;  // Configura pines 8, 9, 10 como salida
  
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

// Defines all commands
#define DISPLAY_ON 0x0C
#define DISPLAY_OFF 0x08
#define CURSOR 0x0E
#define NO_CURSOR 0x0C
#define BLINK 0x0D
#define NO_BLINK 0x0C
#define SCROLL_R 0x18
#define SCROLL_L 0x1C
#define HOME 0x02
#define AUTOSCROLL 0x07
#define NO_AUTOSCROLL 0x06
#define CLEAR 0x01

// Writes the values in the pins
void set_byte(uint8_t in_byte){
  in_byte = (in_byte & 0xF0) >> 4 | (in_byte & 0x0F) << 4;
  in_byte = (in_byte & 0xCC) >> 2 | (in_byte & 0x33) << 2;
  in_byte = (in_byte & 0xAA) >> 1 | (in_byte & 0x55) << 1;
  for(int i = 7; i >= 0; i--){
    digitalWrite(i, 0b00000001 & (in_byte >> i));
  }

  /*in_byte = (in_byte & 0xF0) >> 4 | (in_byte & 0x0F) << 4;
    in_byte = (in_byte & 0xCC) >> 2 | (in_byte & 0x33) << 2;
    in_byte = (in_byte & 0xAA) >> 1 | (in_byte & 0x55) << 1;
    PORTD = in_byte;*/
}

// Sends a command to the display
void send_command(uint8_t command){
  // Set RS and R/W
  //cbi(PORTB, 2);
  digitalWrite(10, 0);
  //cbi(PORTB, 1);
  digitalWrite(9, 0);

  // Set bit values
  set_byte(command);

  // Signal Enable
  //sbi(PORTB, 0);
  //cbi(PORTB, 0);
  digitalWrite(8, 1);
  digitalWrite(8, 0);

  //Uses a different delay based on the commands
  if(command == CLEAR || command == HOME)
    delay(2);
  else
    delayMicroseconds(50);
}

// Writes the introduced byte in the LCD 
void write(uint8_t in_char){
  // Set RS and R/W
  //sbi(PORTB, 2);
  //cbi(PORTB, 1);
  digitalWrite(10, 1);
  digitalWrite(9, 0);

  // Set bit values
  set_byte(in_char);

  // Signal Enable
  //sbi(PORTB, 0);
  //cbi(PORTB, 0);
  digitalWrite(8, 1);
  digitalWrite(8, 0);

  delayMicroseconds(50);
}

// Writes the introduced String into the LCD
void write_str(char* char_str){
  while(*char_str != 0){
    write(*char_str);
    char_str++;
  }
}

// Sets the cursor to a position between 0-60
void move_cursor(uint8_t position){
  // Puts cursor in starting position
  send_command(0x80);
  
  // Ignores non valid positions
  if(position < 0 || position > 80) return;

  // Writes the instruction position time
  for(uint8_t i = 0; i < position; i++){
    set_byte(0b00010100);

    // Signal Enable
    //sbi(PORTB, 0);
    //cbi(PORTB, 0);
    digitalWrite(8, 1);
    digitalWrite(8, 0);
  
    delayMicroseconds(50);
  }
}

// Sends all initialization commands
void lcd_begin() {
  // Enviar "Function Set" tres veces para establecer modo 8 bits
  send_command(0x30);
  delay(10);
  send_command(0x30);
  delayMicroseconds(200);
  send_command(0x30);

  send_command(0x3C);
  send_command(DISPLAY_OFF);
  send_command(CLEAR);
  send_command(NO_AUTOSCROLL);
}     

我期待它能起作用,因为如果我是对的,它是等价的。

void loop() {
  lcd_begin();
  send_command(DISPLAY_ON);

  for(uint8_t i = 65; i < 91; i++){
    write(i);
    delay(50);
  }

  delay(1000);
}

例如,这段代码打印字母表中的字母,与 pinMode()/digitalWrite() 方法完美配合,但不执行任何操作端口的操作。

arduino port atmega lcd
1个回答
0
投票

要初始化引脚 0-10,代码应为:

DDRD = 0b10011111;
DDRC = 0b01000000;
DDRE = 0b01000000;
DDRB = 0b01110000;

Arduino Leonardo 引脚分配

© www.soinside.com 2019 - 2024. All rights reserved.