WeatherStation/GDM1602K.c

142 lines
2.7 KiB
C
Raw Normal View History

2023-12-03 13:37:53 +01:00
#include "config.h"
#include <avr/io.h>
#include <util/delay.h>
#include <stdbool.h>
#define LCD_DATA_PORT PORTB
#define LCD_DATA_DDR DDRB
#define LCD_RS_PIN PB1
#define LCD_EN_PIN PB2
#define LCD_DB4 PB3
#define LCD_DB5 PB4
#define LCD_DB6 PB5
#define LCD_DB7 PB6
// Delay constants from the datasheet. These are mostly in nanoseconds
#define LAG 10
#define TW 300
#define TSU1 100
void lcd_4bit_init() {
LCD_DATA_DDR = 0xFF;
LCD_DATA_PORT = (1 << LCD_DB5);
LCD_DATA_PORT &= ~(1 << LCD_RS_PIN);
_delay_us(1);
LCD_DATA_PORT |= (1 << LCD_EN_PIN);
_delay_us(1);
LCD_DATA_PORT &= ~(1 << LCD_EN_PIN);
_delay_us(1);
LCD_DATA_PORT &= ~(1 << LCD_DB5);
_delay_us(1);
}
void lcd_send(bool rs, uint8_t data) {
LCD_DATA_DDR = 0xFF;
LCD_DATA_PORT = 0x00;
LCD_DATA_PORT |= (data >> 4) << 3;
_delay_us(1);
// If rs (actual text data), set RS pin high
if(rs == true) LCD_DATA_PORT |= (1 << LCD_RS_PIN);
// Pulse enable
_delay_ms(2);
LCD_DATA_PORT |= (1 << LCD_EN_PIN);
_delay_us(1);
LCD_DATA_PORT &= ~(1 << LCD_EN_PIN);
//_delay_us(1);
// Clear data pins
LCD_DATA_PORT &= ~(0x0F << 3);
// Mask the lower bits and shift accordingly
LCD_DATA_PORT |= (data & 0x0F) << 3;
_delay_us(1);
// Pulse enable
LCD_DATA_PORT |= (1 << LCD_EN_PIN);
_delay_us(1);
LCD_DATA_PORT &= ~(1 << LCD_EN_PIN);
_delay_us(1);
LCD_DATA_PORT &= ~(0x0F << 3);
LCD_DATA_PORT &= ~(1 << LCD_RS_PIN); // RS Low
}
void lcd_init() {
_delay_ms(100);
lcd_4bit_init();
//lcd_send(1, 0b01111000);
lcd_send(0, 0x01); // Clear screen
lcd_send(0, 0x02); // Return home
lcd_send(0, 0b00001100); // Display on, no cursor
lcd_send(0, 0b00101000);
}
void lcd_clear() {
lcd_send(0, 0x01);
}
void test_leds() {
DDRB |= 0xFF;
PORTB = (1 << LCD_DB4);
_delay_us(1);
PORTB = (1 << LCD_DB5);
_delay_us(1);
PORTB = (1 << LCD_DB6);
_delay_us(1);
PORTB = (1 << LCD_DB7);
_delay_us(1);
PORTB = (1 << LCD_EN_PIN);
_delay_us(1);
PORTB = (1 << LCD_RS_PIN);
_delay_us(1);
PORTB = 0x00;
}
void lcd_set_cursor(uint8_t row, uint8_t col) {
uint8_t position = 0x80;
if (row == 1) position += 0x40;
position += col;
lcd_send(0, position);
}
// Takes a string and splits it over two lines if needed. Max length is 32 characters.
void lcd_write_string(const char* string) {
uint8_t i = 0;
while(string[i]) {
if(i == 16) {
lcd_set_cursor(1, 0);
while(string[i] == ' ') i++; // Skip leading spaces on the new line
}
lcd_send(1, string[i]);
i++;
}
}
// Takes two separate strings and prints them on their corresponding row
void lcd_write_strings(const char* top, const char* bottom) {
uint8_t i = 0;
while (top[i]) {
lcd_send(1, top[i]);
i++;
}
i = 0;
lcd_set_cursor(1, 0);
while(bottom[i]) {
lcd_send(1, bottom[i]);
i++;
}
}