87 lines
2.1 KiB
C
87 lines
2.1 KiB
C
#include "lcd.h"
|
||
#include "i2c.h" /* Ihr I²C-Master-Treiber */
|
||
#include <msp430fr2355.h> /* für __delay_cycles() */
|
||
#include <stdint.h>
|
||
|
||
/* --- Interne Helfer: sendet eine 4-Bit-Halbnibble plus Control-Bits --- */
|
||
static void lcd_write_nibble(uint8_t nibble, uint8_t control)
|
||
{
|
||
char buf[1];
|
||
|
||
/* High-Nibble in die oberen 4 Bits */
|
||
buf[0] = (nibble << 4) | control | LCD_BACKLIGHT;
|
||
/* EN=1 */
|
||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
||
buf[0] |= LCD_ENABLE;
|
||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
||
__delay_cycles(500); /* ca. 50 µs @ 1 MHz */
|
||
/* EN=0 */
|
||
buf[0] &= ~LCD_ENABLE;
|
||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
||
__delay_cycles(500);
|
||
}
|
||
|
||
/* Sendet ein volles Byte (2×4-Bit) als Befehl (RS=0) */
|
||
static void lcd_send_cmd(uint8_t cmd)
|
||
{
|
||
lcd_write_nibble(cmd >> 4, 0x00);
|
||
lcd_write_nibble(cmd & 0x0F, 0x00);
|
||
}
|
||
|
||
/* Sendet ein volles Byte als Daten (RS=1) */
|
||
static void lcd_send_data(uint8_t data)
|
||
{
|
||
lcd_write_nibble(data >> 4, LCD_RS);
|
||
lcd_write_nibble(data & 0x0F, LCD_RS);
|
||
}
|
||
|
||
void lcd_init(void)
|
||
{
|
||
/* Wartezeit nach Power-Up */
|
||
__delay_cycles(50000); /* ca. 50 ms */
|
||
|
||
/* Initialsequenz 8-Bit-Befehle (3×) */
|
||
lcd_write_nibble(0x03, 0x00);
|
||
__delay_cycles(20000);
|
||
lcd_write_nibble(0x03, 0x00);
|
||
__delay_cycles(5000);
|
||
lcd_write_nibble(0x03, 0x00);
|
||
__delay_cycles(2000);
|
||
|
||
/* In 4-Bit-Modus schalten */
|
||
lcd_write_nibble(0x02, 0x00);
|
||
__delay_cycles(2000);
|
||
|
||
/* Funktion: 4-Bit, 2 Zeilen, 5×8 Punkte */
|
||
lcd_send_cmd(0x28);
|
||
/* Display off */
|
||
lcd_send_cmd(0x08);
|
||
/* Clear */
|
||
lcd_send_cmd(0x01);
|
||
__delay_cycles(2000);
|
||
/* Entry mode: Cursor++ */
|
||
lcd_send_cmd(0x06);
|
||
/* Display on, Cursor off, Blink off */
|
||
lcd_send_cmd(0x0C);
|
||
}
|
||
|
||
void lcd_clear(void)
|
||
{
|
||
lcd_send_cmd(0x01);
|
||
__delay_cycles(2000);
|
||
}
|
||
|
||
void lcd_set_cursor(uint8_t row, uint8_t col)
|
||
{
|
||
uint8_t addr = (row == 0 ? 0x00 : 0x40) + (col & 0x0F);
|
||
lcd_send_cmd(0x80 | addr);
|
||
}
|
||
|
||
void lcd_print(const char *str)
|
||
{
|
||
while (*str)
|
||
{
|
||
lcd_send_data((uint8_t)*str++);
|
||
}
|
||
}
|