HD44780 的初始化不起作用。我完成了数据表上的每一步,但无法取得任何进展。我在 4 位接口上运行。 我故意不使用库,因为我想在使用库之前先了解代码。这是包含所有功能和初始化的代码。 主要是尝试使用初始化函数,最后让光标闪烁。
我尝试完成官方数据表中的每一步。 我一次又一次地重写代码,并确保初始化会成功。 我期待光标出现在显示屏上并开始闪烁。
这里是数据表:https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
第 46 页是初始化说明。
这是我的代码:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
//#define LCD_Port PortB
// Pinbelegung für das LCD
#define LCD_DDR DDRB
#define LCD_D4 PB4
#define LCD_D5 PB5
#define LCD_D6 PB6
#define LCD_D7 PB7
// LCD Steuersignale RS und EN
#define LCD_RS PB0
#define LCD_EN PB2
//LCD Ausführungszeiten
#define LCD_BOOTUP_MS 15
#define LCD_ENABLE_US 1
#define LCD_WRITEDATA_US 46
#define LCD_COMMAND_US 42
#define LCD_SOFT_RESET_MS1 5
#define LCD_SOFT_RESET_MS2 1
#define LCD_SOFT_RESET_MS3 1
#define LCD_SET_4BITMODE_MS 5
#define LCD_CLEAR_DISPLAY_MS 2
#define LCD_CURSOR_HOME_MS 2
#define LCD_SOFT_RESET 0x30
#define LCD_SET_FUNCTION 0x20
#define LCD_FUNCTION_4BIT 0x00
#define LCD_FUNCTION_2LINE 0x08
#define LCD_FUNCTION_5X7 0x00
// Set Entry Mode
#define LCD_SET_ENTRY 0x04
#define LCD_ENTRY_DECREASE 0x00
#define LCD_ENTRY_INCREASE 0x02
#define LCD_ENTRY_NOSHIFT 0x00
#define LCD_ENTRY_SHIFT 0x01
// Set Display
#define LCD_SET_DISPLAY 0x08
#define LCD_DISPLAY_OFF 0x00
#define LCD_DISPLAY_ON 0x04
#define LCD_CURSOR_OFF 0x00
#define LCD_CURSOR_ON 0x02
#define LCD_BLINKING_OFF 0x00
#define LCD_BLINKING_ON 0x01
#define LCD_CURSOR_HOME 0x02
// Clear Display
#define LCD_CLEAR_DISPLAY 0x01
static void lcd_enable (void){
PORTB |= (1<<LCD_EN); // Enable auf 1 setzen
_delay_us(LCD_ENABLE_US); // Pause
PORTB &= ~(1<<LCD_EN); // Enable auf 0 setzen
}
void lcd_out (uint8_t data) {
//wandelt 8-Bit System in ein 4-Bit System um
// Sende die oberen 4 Bits
//high nippel
PORTB |= (data & 0xF0);
lcd_enable();
//low nippel
PORTB |= ((data << 4) & 0xF0);
lcd_enable();
}
void lcd_command( uint8_t data ) {
PORTB &= ~(1<<LCD_RS); // RS auf 0 setzen
lcd_out( data ); // zuerst die oberen,
lcd_out( data<<4); // dann die unteren 4 Bit senden
_delay_us(LCD_COMMAND_US );
}
void lcd_home( void )
{
lcd_command( LCD_CURSOR_HOME );
_delay_ms( LCD_CURSOR_HOME_MS );
}
void lcd_clear( void ) {
lcd_command( LCD_CLEAR_DISPLAY );
_delay_ms( LCD_CLEAR_DISPLAY_MS );
}
void lcd_init (void){
// verwendete Pins auf Ausgang schalten
uint8_t pins = (0x0F << LCD_D4) | // 4 Datenleitungen
(0x0F << LCD_D5) |
(0x0F << LCD_D6) |
(0x0F << LCD_D7) |
(1<<LCD_RS) | // R/S Leitung
(1<<LCD_EN); // Enable Leitung
LCD_DDR |= pins;
// initial alle Ausgänge auf Null
PORTB &= ~pins;
// warten auf die Bereitschaft des LCD
_delay_ms(LCD_BOOTUP_MS);
// Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
lcd_out(LCD_SOFT_RESET);
_delay_ms(LCD_SOFT_RESET_MS1);
lcd_enable();
_delay_ms(LCD_SOFT_RESET_MS2);
lcd_enable();
_delay_ms(LCD_SOFT_RESET_MS3);
// 4-bit Modus aktivieren
lcd_out (LCD_SET_FUNCTION | LCD_FUNCTION_4BIT );
_delay_ms (LCD_SET_4BITMODE_MS );
// 4-bit Modus / 2 Zeilen / 5x7
lcd_command( LCD_SET_FUNCTION |
LCD_FUNCTION_4BIT |
LCD_FUNCTION_2LINE |
LCD_FUNCTION_5X7 );
// Display ein / Cursor aus / Blinken aus
lcd_command(LCD_SET_DISPLAY |
LCD_DISPLAY_ON |
LCD_CURSOR_OFF |
LCD_BLINKING_OFF);
// Cursor inkrement / kein Scrollen
lcd_command( LCD_SET_ENTRY |
LCD_ENTRY_INCREASE |
LCD_ENTRY_NOSHIFT );
lcd_clear();
}
int main (void){
/* Replace with your application code */
lcd_init();
lcd_command(LCD_DISPLAY_ON);
lcd_command(LCD_CURSOR_ON);
lcd_command(LCD_BLINKING_ON);
lcd_home();
while (1)
{
}
return 0;
}
好的,你可以尝试像这样调整你的
lcd_enable
吗:
static void lcd_enable (void){
PORTB |= (1<<LCD_EN); // Enable auf 1 setzen
_delay_us(LCD_ENABLE_US); // Pause
PORTB &= ~(1<<LCD_EN); // Enable auf 0 setzen
_delay_us(LCD_ENABLE_US); // Pause
}
其他一切似乎都很好。我已将其与下面的链接进行了比较。那个图书馆对我有用。