未注释的代码工作得很好,但正如你所看到的,我已经注释了所有与端口相关的行,我认为这些行应该与未注释的行等效,但是当我取消注释这些代码并注释其他代码时,代码只是不执行任何操作。
我正在为大学作业使用 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() 方法完美配合,但不执行任何操作端口的操作。
要初始化引脚 0-10,代码应为:
DDRD = 0b10011111;
DDRC = 0b01000000;
DDRE = 0b01000000;
DDRB = 0b01110000;