Skip to content

Instantly share code, notes, and snippets.

@ZhukV
Created April 26, 2014 11:20
Show Gist options
  • Save ZhukV/11317545 to your computer and use it in GitHub Desktop.
Save ZhukV/11317545 to your computer and use it in GitHub Desktop.
/**
ks0066.c - Working with LCD displays on based controllers KS0066
Author: Vitaliy Zhuk
*/
#include <util/delay.h>
#include "ks0066.h"
void lcdInit()
{
#ifdef KS0066_4BIT
uint8_t command = (1 << 5) | (0 << 4) | (KS0066_COUNT_LINES << 3) | (KS0066_CHAR_SIZE << 2);
#else
uint8_t command = (1 << 5) | (1 << 4) | (KS0066_COUNT_LINES << 3) | (KS0066_CHAR_SIZE << 2);
#endif
lcdWriteByte(command, 1);
}
void lcdWriteByte(uint8_t byte, uint8_t command)
{
// Configure ports for writing data
#ifndef KS0066_4BIT
KS0066_DATA_DDR = 0xFF;
KS0066_DATA_PORT = 0x00;
#else
#if KS0066_4BIT_HIGH_BYTE == 1
KS0066_DATA_DDR |= 0b11110000;
KS0066_DATA_PORT &= ~(0b11110000);
#else
KS0066_DATA_DDR |= 0b00001111;
KS0066_DATA_PORT &= ~(0b00001111);
#endif
#endif
KS0066_CTRL_DDR |= (1 << KS0066_CTRL_STROBE_PIN) | (1 << KS0066_CTRL_RW_PIN) | (1 << KS0066_CTRL_RS_PIN);
// Set the flag for writing (Command/Data)
if (command) {
KS0066_WRITE_COMMAND();
} else {
KS0066_WRITE_DATA();
}
// Write data, not reading
KS0066_WRITE();
#ifdef KS0066_4BIT
// 4 BIT mode
#if KS0066_4BIT_HIGH_BYTE == 1
uint8_t clearByte = 0b11110000;
uint8_t highByte = byte & 0b11110000;
uint8_t lowByte = byte << 4;
#else
uint8_t clearByte = 0b00001111;
uint8_t highByte = byte >> 4;
uint8_t lowByte = byte & 0b00001111;
#endif
KS0066_DATA_PORT &= ~clearByte;
KS0066_DATA_PORT |= highByte;
KS0066_STROBE_SET();
_delay_us(2);
KS0066_STROBE_RESET();
KS0066_DATA_PORT &= ~clearByte;
KS0066_DATA_PORT |= lowByte;
KS0066_STROBE_SET();
_delay_us(2);
KS0066_STROBE_RESET();
#else
// 8 BIT mode
KS0066_DATA_PORT = byte;
KS0066_STROBE_SET();
_delay_us(2);
KS0066_STROBE_RESET();
#endif
// Secondary delay for process command/data
// For command with DRAM, timeout must be a large than 1.52 ms (1520 us),
// and for another command, timeout must be a large than 37 us (0.000037 s).
if (command) {
// This is a command register. Check command
if (byte == KS0066_CMD_CLEAR || byte == KS0066_CMD_GOTO_HOME) {
// This is clear display or goto home command. Timeout >= 1.52ms
_delay_us(1520);
} else {
_delay_us(37);
}
} else {
_delay_us(37);
}
}
void lcdWriteCommand(uint8_t command)
{
lcdWriteByte(command, 1);
}
void lcdWriteData(uint8_t data)
{
lcdWriteByte(data, 0);
}
void lcdPuts(const char *buffer)
{
while (*buffer) {
lcdWriteByte(*buffer, 0);
buffer++;
}
}
void lcdGoto(uint8_t byte, uint8_t line)
{
uint8_t command = (1 << 7);
if (line == 1) {
// First list
byte += 40;
}
command += byte;
lcdWriteByte(command, 1);
}
void lcdShift(uint8_t mode, uint8_t to)
{
uint8_t command = (1 << 4) | (mode << 3) | (to << 2);
lcdWriteByte(command, 1);
}
/**
ks0066.h - Working with LCD displays on based controllers KS0066
Author: Vitaliy Zhuk
*/
#ifndef __KS0066_H_
#define __KS0066_H_ 1
// Data PORT/DDR must be defined
#ifndef KS0066_DATA_DDR
# error "KS0066_DATA_DDR not defined for lcd/ks0066.h"
#endif
#ifndef KS0066_DATA_PORT
# error "KS0066_DATA_PORT not defined for lcd/ks0066.h"
#endif
// Controls PORT/DDR must be defined
#ifndef KS0066_CTRL_DDR
# error "KS0066_CTRL_DDR not defined for lcd/ks0066.h"
#endif
#ifndef KS0066_CTRL_PORT
# error "KS0066_CTRL_PORT not defined for lcd/ks0066.h"
#endif
#ifndef KS0066_CTRL_STROBE_PIN
# error "KS0066_CTRL_STROBE_PIN not defined for lcd/ks0066.h"
#endif
#ifndef KS0066_CTRL_RS_PIN
# error "KS0066_CTRL_RS_PIN not defined for lcd/ks0066.h"
#endif
#ifndef KS0066_CTRL_RW_PIN
# error "KS0066_CTRL_RS_PIN not defined for lcd/ks0066.h"
#endif
// Mode constants
#ifdef KS0066_4BIT
#ifndef KS0066_4BIT_HIGH_BYTE
#define KS0066_4BIT_HIGH_BYTE 1
#endif
#endif
#ifndef KS0066_COUNT_LINES
#define KS0066_COUNT_LINES 1
#endif
#ifndef KS0066_CHAR_SIZE
#define KS0066_CHAR_SIZE 0
#endif
// Define commands
#define KS0066_CMD_CLEAR 0x01
#define KS0066_CMD_GOTO_HOME 0x02
#define KS0066_CMD_CURSOR_SHIFT_LEFT 0x04
#define KS0066_CMD_CURSOR_SHIFT_RIGHT 0x06
#define KS0066_CMD_DISPLAY_OFF 0x08
#define KS0066_CMD_CURSOR_OFF 0x0C
#define KS0066_CMD_CURSOR_RECTANGLE 0x0D
#define KS0066_CMD_CURSOR_LINE 0x0E
// Define macros
#define KS0066_STROBE_SET() KS0066_CTRL_PORT |= (1 << KS0066_CTRL_STROBE_PIN)
#define KS0066_STROBE_RESET() KS0066_CTRL_PORT &= ~(1 << KS0066_CTRL_STROBE_PIN)
#define KS0066_WRITE() KS0066_CTRL_PORT &= ~(1 << KS0066_CTRL_RW_PIN)
#define KS0066_READ() KS0066_CTRL_PORT |= (1 << KS0066_CTRL_RW_PIN)
#define KS0066_WRITE_COMMAND() KS0066_CTRL_PORT &= ~(1 << KS0066_CTRL_RS_PIN)
#define KS0066_WRITE_DATA() KS0066_CTRL_PORT |= (1 << KS0066_CTRL_RS_PIN)
/**
Initialize of LCD. Send first command for configure
mode, count lines and char size
*/
void lcdInit();
/**
Write the byte \a byte to LCD as command, if \a command is 1
or as data, if \a command is 0
*/
void lcdWriteByte(uint8_t byte, uint8_t command);
/**
Write command \a command to LCD
*/
void lcdWriteCommand(uint8_t command);
/**
Write data \a data to LCD
*/
void lcdWriteData(uint8_t data);
/**
Write bytes \a *buffer as command, if \a command is 1
or as data, if \a command is 0
*/
void lcdPuts(const char *buffer);
/**
Goto position if LCD, to char \a byte, and line \a line.
\note The indicate byte and line start from 0 (zero).
*/
void lcdGoto(uint8_t byte, uint8_t line);
/**
LCD shift. Shift cursor or display
If \a mode is 1, then shift display, else shift cursor
If \a to is 1, then shift to right, else shift to left
*/
void lcdShift(uint8_t mode, uint8_t to);
#endif /* __KS0066_H_ */
/**
* Used on Atmega 8535
*
* Use one port: PORTA 0-6
*/
#define F_CPU 1000000 // 1 Mhz
#define KS0066_DATA_DDR DDRA
#define KS0066_DATA_PORT PORTA
#define KS0066_CTRL_DDR DDRA
#define KS0066_CTRL_PORT PORTA
#define KS0066_CTRL_STROBE_PIN PINA6
#define KS0066_CTRL_RW_PIN PINA5
#define KS0066_CTRL_RS_PIN PINA4
#define KS0066_4BIT 1
#define KS0066_4BIT_HIGH_BYTE 0
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include "lcd/ks0066.c"
int main(void)
{
_delay_ms(100);
// Initialize LCD
lcdInit();
lcdWriteCommand(KS0066_CMD_CLEAR);
lcdWriteCommand(KS0066_CMD_CURSOR_OFF);
// Write data
lcdGoto(0, 0);
lcdPuts("Hi... LCD");
lcdGoto(0, 1);
lcdPuts("This work :D");
while(1)
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment