Created
April 26, 2014 11:20
-
-
Save ZhukV/11317545 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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