216 lines
4.5 KiB
C
216 lines
4.5 KiB
C
|
#include <lcd.h>
|
||
|
#include <delay.h>
|
||
|
|
||
|
static void lcd_port_clear(void)
|
||
|
{
|
||
|
LCD_DPORT->ODR &= ~(LCD_E_MASK);
|
||
|
LCD_DPORT->ODR &= ~(LCD_DATA_MASK | LCD_RS_MASK | LCD_E_MASK);
|
||
|
}
|
||
|
|
||
|
static void lcd_enable(void)
|
||
|
{
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
LCD_DPORT->ODR |= LCD_E_MASK;
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
LCD_DPORT->ODR &= ~LCD_E_MASK;
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
__ASM("nop");
|
||
|
}
|
||
|
|
||
|
static void lcd_out(uint8_t data)
|
||
|
{
|
||
|
LCD_DPORT->ODR &= ~(LCD_DATA_MASK);
|
||
|
LCD_DPORT->ODR |= (data << LCD_DATA_BIT_OFFSET) & LCD_DATA_MASK;
|
||
|
}
|
||
|
|
||
|
static void lcd_data(uint8_t data)
|
||
|
{
|
||
|
lcd_port_clear();
|
||
|
LCD_DPORT->ODR |= LCD_RS_MASK;
|
||
|
lcd_out((data>>4) & 0xFU);
|
||
|
lcd_enable();
|
||
|
lcd_out(data & 0xFU);
|
||
|
lcd_enable();
|
||
|
delay_ms(1);
|
||
|
}
|
||
|
|
||
|
static void lcd_command(uint8_t data)
|
||
|
{
|
||
|
lcd_port_clear();
|
||
|
lcd_out((data>>4) & 0xFU);
|
||
|
lcd_enable();
|
||
|
lcd_out(data & 0xFU);
|
||
|
lcd_enable();
|
||
|
delay_ms(1);
|
||
|
}
|
||
|
|
||
|
#define LCD_DDADR_LINE1 0x00
|
||
|
#define LCD_DDADR_LINE2 0x40
|
||
|
#define LCD_DDADR_LINE3 0x10
|
||
|
#define LCD_DDADR_LINE4 0x50
|
||
|
|
||
|
// Clear Display -------------- 0b00000001
|
||
|
#define LCD_CLEAR_DISPLAY 0x01
|
||
|
|
||
|
// Cursor Home ---------------- 0b0000001x
|
||
|
#define LCD_CURSOR_HOME 0x02
|
||
|
|
||
|
// Set Entry Mode ------------- 0b000001xx
|
||
|
#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 ---------------- 0b00001xxx
|
||
|
#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
|
||
|
|
||
|
// Set Shift ------------------ 0b0001xxxx
|
||
|
#define LCD_SET_SHIFT 0x10
|
||
|
|
||
|
#define LCD_CURSOR_MOVE 0x00
|
||
|
#define LCD_DISPLAY_SHIFT 0x08
|
||
|
#define LCD_SHIFT_LEFT 0x00
|
||
|
#define LCD_SHIFT_RIGHT 0x04
|
||
|
|
||
|
// Set Function --------------- 0b001xxxxx
|
||
|
#define LCD_SET_FUNCTION 0x20
|
||
|
|
||
|
#define LCD_FUNCTION_4BIT 0x00
|
||
|
#define LCD_FUNCTION_8BIT 0x10
|
||
|
#define LCD_FUNCTION_1LINE 0x00
|
||
|
#define LCD_FUNCTION_2LINE 0x08
|
||
|
#define LCD_FUNCTION_5X7 0x00
|
||
|
#define LCD_FUNCTION_5X10 0x04
|
||
|
|
||
|
#define LCD_SOFT_RESET 0x30
|
||
|
|
||
|
// Set CG RAM Address --------- 0b01xxxxxx (Character Generator RAM)
|
||
|
#define LCD_SET_CGADR 0x40
|
||
|
|
||
|
#define LCD_GC_CHAR0 0
|
||
|
#define LCD_GC_CHAR1 1
|
||
|
#define LCD_GC_CHAR2 2
|
||
|
#define LCD_GC_CHAR3 3
|
||
|
#define LCD_GC_CHAR4 4
|
||
|
#define LCD_GC_CHAR5 5
|
||
|
#define LCD_GC_CHAR6 6
|
||
|
#define LCD_GC_CHAR7 7
|
||
|
|
||
|
// Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM)
|
||
|
#define LCD_SET_DDADR 0x80
|
||
|
|
||
|
void lcd_clear(void)
|
||
|
{
|
||
|
lcd_command(LCD_CLEAR_DISPLAY);
|
||
|
delay_ms(3);
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// Sendet den Befehl: Cursor Home
|
||
|
void lcd_home( void )
|
||
|
{
|
||
|
lcd_command(LCD_CURSOR_HOME);
|
||
|
delay_ms(3);
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4)
|
||
|
|
||
|
void lcd_setcursor( uint8_t x, uint8_t y )
|
||
|
{
|
||
|
uint8_t data;
|
||
|
|
||
|
switch (y)
|
||
|
{
|
||
|
case 1: // 1. Zeile
|
||
|
data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
|
||
|
break;
|
||
|
|
||
|
case 2: // 2. Zeile
|
||
|
data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
|
||
|
break;
|
||
|
|
||
|
case 3: // 3. Zeile
|
||
|
data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
|
||
|
break;
|
||
|
|
||
|
case 4: // 4. Zeile
|
||
|
data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return; // für den Fall einer falschen Zeile
|
||
|
}
|
||
|
|
||
|
lcd_command(data);
|
||
|
}
|
||
|
|
||
|
void lcd_string(const char *data)
|
||
|
{
|
||
|
while(*data != '\0') {
|
||
|
lcd_data((uint8_t)*data++);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void lcd_init(void)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
lcd_port_clear();
|
||
|
delay_ms(100);
|
||
|
LCD_DPORT->ODR |= (0x3 << LCD_DATA_BIT_OFFSET);
|
||
|
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
lcd_enable();
|
||
|
delay_ms(5);
|
||
|
}
|
||
|
|
||
|
// Set 4 Bit mode
|
||
|
lcd_port_clear();
|
||
|
LCD_DPORT->ODR |= (0x2<<LCD_DATA_BIT_OFFSET);
|
||
|
lcd_enable();
|
||
|
delay_ms(2);
|
||
|
|
||
|
// 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();
|
||
|
}
|
||
|
|
||
|
|