Jednou jsem si řekl, že by nebylo marné si osvojit dovednost v programové obsluze LCD displeje.
Chvíli jsem uvažoval o zakoupení běžného displeje z SOS či GME, avšak cena mne odradila.
Vzpomněl jsem si však, že při svém websurfingu jsem narazil na bastl se zprovozněným displejem z mobilu.
A jelikož jsem měl k dispozici pouze vysloužilý mobil NOKIE 1100, tak nebylo co řešit.
Skoulel jsem to do kupy a tady to máte.
module.ro/circuite/lcdn8310.jpg
Toto schématko je určeno sice pro LCD z nokie8310, ale je použitelné i na nokii1100.
Displej obsahuje LCD driver PCF8814. mylcd.sourceforge.net/files/pcf8814.pdf
To pro případ, že si s tím budete chtít pohrát víc jak já…
Na adrese sunbizhosting.com/~spiral/ jsem nalezl knihovnu pro tento displej, ale byla dělaná pro procesor Microchipu.
Tak jsem se v něm pošťoural a zde máte výsledek.
[code]/*
| \ | | / _ \ | |/ / |_ | / \ / | / | / _ \ / _ \ | | / | | _
| | | | | | | | ’ / | | / _ \ | | | | | | | | | | | | | | | | | | | |
| |\ | | || | | . \ | | / ___ \ | | | | | || | | || | | |__ | |___ | || |
|| _| _/ ||_\ || // _\ || || _/ _/ |__| _| |___/
Tato knihovna převzata odsud: http://sunbizhosting.com/~spiral/
Následně upravena pro AVR od ATMELU Divousem.
File: lcd1100.h
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
// set output pins for lcd here
#define sclk PE1
#define sda PE3
#define cs PE2
#define rst PE0
#define SETPE(pin,value) {if (value == 0) PORTE &= ~(1<<pin); else PORTE |= (1<<pin);}
#define CMD 0
#define DATA 1
void init(void);
void Lcd_Init(void);
void Lcd_Write(char cd,unsigned char c);
void Lcd_Clear(void);
void SetX(char x);
void SetY(char y);
void Gotoxy(char x,char y);
void VLine(char x,char y,char on);
void Line(unsigned char x,unsigned char y,unsigned char y2,unsigned char on);
void print_message(const char* message);
void print_char(char c);
void print_string(char * message);[/code]
…
[code]/*
| \ | | / _ \ | |/ / |_ | / \ / | / | / _ \ / _ \ | | / | | _
| | | | | | | | ’ / | | / _ \ | | | | | | | | | | | | | | | | | | | |
| |\ | | || | | . \ | | / ___ \ | | | | | || | | || | | |__ | |___ | || |
|| _| _/ ||_\ || // _\ || || _/ _/ |__| _| |___/
Tato knihovna převzata odsud: http://sunbizhosting.com/~spiral/
Následně upravena pro AVR od ATMELU Divousem.
File: lcd1100.c
*/
#include “lcd1100.h”
#include <avr/pgmspace.h>
char bitaddr;
// lookup table, here you can modify the font
static const unsigned char FontLookup[96][5] PROGMEM = {
{0x00, 0x00, 0x00, 0x00, 0x00},// (space)
{0x00, 0x00, 0x5F, 0x00, 0x00},// !
{0x00, 0x07, 0x00, 0x07, 0x00},// "
{0x14, 0x7F, 0x14, 0x7F, 0x14},// #
{0x24, 0x2A, 0x7F, 0x2A, 0x12},// $
{0x23, 0x13, 0x08, 0x64, 0x62},// %
{0x36, 0x49, 0x55, 0x22, 0x50},// &
{0x00, 0x05, 0x03, 0x00, 0x00},// ’
{0x00, 0x1C, 0x22, 0x41, 0x00},// (
{0x00, 0x41, 0x22, 0x1C, 0x00},// )
{0x08, 0x2A, 0x1C, 0x2A, 0x08},// *
{0x08, 0x08, 0x3E, 0x08, 0x08},// +
{0x00, 0x50, 0x30, 0x00, 0x00},// ,
{0x08, 0x08, 0x08, 0x08, 0x08},// -
{0x00, 0x30, 0x30, 0x00, 0x00},// .
{0x20, 0x10, 0x08, 0x04, 0x02},// /
{0x3E, 0x51, 0x49, 0x45, 0x3E},// 0
{0x00, 0x42, 0x7F, 0x40, 0x00},// 1
{0x42, 0x61, 0x51, 0x49, 0x46},// 2
{0x21, 0x41, 0x45, 0x4B, 0x31},// 3
{0x18, 0x14, 0x12, 0x7F, 0x10},// 4
{0x27, 0x45, 0x45, 0x45, 0x39},// 5
{0x3C, 0x4A, 0x49, 0x49, 0x30},// 6
{0x01, 0x71, 0x09, 0x05, 0x03},// 7
{0x36, 0x49, 0x49, 0x49, 0x36},// 8
{0x06, 0x49, 0x49, 0x29, 0x1E},// 9
{0x00, 0x36, 0x36, 0x00, 0x00},// :
{0x00, 0x56, 0x36, 0x00, 0x00},// ;
{0x00, 0x08, 0x14, 0x22, 0x41},// <
{0x14, 0x14, 0x14, 0x14, 0x14},// =
{0x41, 0x22, 0x14, 0x08, 0x00},// >
{0x02, 0x01, 0x51, 0x09, 0x06},// ?
{0x32, 0x49, 0x79, 0x41, 0x3E},// @
{0x7E, 0x11, 0x11, 0x11, 0x7E},// A
{0x7F, 0x49, 0x49, 0x49, 0x36},// B
{0x3E, 0x41, 0x41, 0x41, 0x22},// C
{0x7F, 0x41, 0x41, 0x22, 0x1C},// D
{0x7F, 0x49, 0x49, 0x49, 0x41},// E
{0x7F, 0x09, 0x09, 0x01, 0x01},// F
{0x3E, 0x41, 0x41, 0x51, 0x32},// G
{0x7F, 0x08, 0x08, 0x08, 0x7F},// H
{0x00, 0x41, 0x7F, 0x41, 0x00},// I
{0x20, 0x40, 0x41, 0x3F, 0x01},// J
{0x7F, 0x08, 0x14, 0x22, 0x41},// K
{0x7F, 0x40, 0x40, 0x40, 0x40},// L
{0x7F, 0x02, 0x04, 0x02, 0x7F},// M
{0x7F, 0x04, 0x08, 0x10, 0x7F},// N
{0x3E, 0x41, 0x41, 0x41, 0x3E},// O
{0x7F, 0x09, 0x09, 0x09, 0x06},// P
{0x3E, 0x41, 0x51, 0x21, 0x5E},// Q
{0x7F, 0x09, 0x19, 0x29, 0x46},// R
{0x46, 0x49, 0x49, 0x49, 0x31},// S
{0x01, 0x01, 0x7F, 0x01, 0x01},// T
{0x3F, 0x40, 0x40, 0x40, 0x3F},// U
{0x1F, 0x20, 0x40, 0x20, 0x1F},// V
{0x7F, 0x20, 0x18, 0x20, 0x7F},// W
{0x63, 0x14, 0x08, 0x14, 0x63},// X
{0x03, 0x04, 0x78, 0x04, 0x03},// Y
{0x61, 0x51, 0x49, 0x45, 0x43},// Z
{0x00, 0x00, 0x7F, 0x41, 0x41},//
{0x02, 0x04, 0x08, 0x10, 0x20},// ""
{0x41, 0x41, 0x7F, 0x00, 0x00},// ]
{0x04, 0x02, 0x01, 0x02, 0x04},// ^
{0x40, 0x40, 0x40, 0x40, 0x40},// _
{0x00, 0x01, 0x02, 0x04, 0x00},// `
{0x20, 0x54, 0x54, 0x54, 0x78},// a
{0x7F, 0x48, 0x44, 0x44, 0x38},// b
{0x38, 0x44, 0x44, 0x44, 0x20},// c
{0x38, 0x44, 0x44, 0x48, 0x7F},// d
{0x38, 0x54, 0x54, 0x54, 0x18},// e
{0x08, 0x7E, 0x09, 0x01, 0x02},// f
{0x08, 0x14, 0x54, 0x54, 0x3C},// g
{0x7F, 0x08, 0x04, 0x04, 0x78},// h
{0x00, 0x44, 0x7D, 0x40, 0x00},// i
{0x20, 0x40, 0x44, 0x3D, 0x00},// j
{0x00, 0x7F, 0x10, 0x28, 0x44},// k
{0x00, 0x41, 0x7F, 0x40, 0x00},// l
{0x7C, 0x04, 0x18, 0x04, 0x78},// m
{0x7C, 0x08, 0x04, 0x04, 0x78},// n
{0x38, 0x44, 0x44, 0x44, 0x38},// o
{0x7C, 0x14, 0x14, 0x14, 0x08},// p
{0x08, 0x14, 0x14, 0x18, 0x7C},// q
{0x7C, 0x08, 0x04, 0x04, 0x08},// r
{0x48, 0x54, 0x54, 0x54, 0x20},// s
{0x04, 0x3F, 0x44, 0x40, 0x20},// t
{0x3C, 0x40, 0x40, 0x20, 0x7C},// u
{0x1C, 0x20, 0x40, 0x20, 0x1C},// v
{0x3C, 0x40, 0x30, 0x40, 0x3C},// w
{0x44, 0x28, 0x10, 0x28, 0x44},// x
{0x0C, 0x50, 0x50, 0x50, 0x3C},// y
{0x44, 0x64, 0x54, 0x4C, 0x44},// z
{0x00, 0x08, 0x36, 0x41, 0x00},// {
{0x00, 0x00, 0x7F, 0x00, 0x00},// |
{0x00, 0x41, 0x36, 0x08, 0x00},// }
{0x08, 0x08, 0x2A, 0x1C, 0x08},// →
{0x08, 0x1C, 0x2A, 0x08, 0x08} // ←
};
// clear LCD
void Lcd_Clear(void){
unsigned int i;
Lcd_Write(CMD,0x40); // Y = 0
Lcd_Write(CMD,0xb0);
Lcd_Write(CMD,0x10); // X = 0
Lcd_Write(CMD,0x0);
Lcd_Write(CMD,0xae); // disable display;
for(i=0;i<864;i++)
Lcd_Write(DATA,0x00);
Lcd_Write(CMD,0xaf); // enable display;
}
// init LCD
void Lcd_Init(void){
SETPE(cs,0);
SETPE(rst,0);
_delay_ms(5); // 5mS so says the stop watch(less than 5ms will not work)
SETPE(rst,1);
Lcd_Write(CMD,0x20); // write VOP register
Lcd_Write(CMD,0x9f);
/*** Zde jsem nastavil vysoké napětí pro displej, jelikož ten můj displej
*** měl již bídný kontrast.
*** Pokud nemáte ten samý problém, tak by měla stačit hodnota 0x90 ***/
Lcd_Write(CMD,0xA4); // all on/normal display
Lcd_Write(CMD,0x2F); // Power control set(charge pump on/off)
Lcd_Write(CMD,0x40); // set start row address = 0
Lcd_Write(CMD,0xb0); // set Y-address = 0
Lcd_Write(CMD,0x10); // set X-address, upper 3 bits
Lcd_Write(CMD,0x0); // set X-address, lower 4 bits
Lcd_Write(CMD,0xC8); // mirror Y axis (about X axis)
Lcd_Write(CMD,0xa1); // Invert screen in horizontal axis
Lcd_Write(CMD,0xac); // set initial row (R0) of the display
Lcd_Write(CMD,0x07);
Lcd_Write(CMD,0xaf); // display ON/OFF
Lcd_Clear(); // clear LCD
Lcd_Write(CMD,0xa7); // invert display
_delay_ms(500); // 1/2 Sec delay
Lcd_Write(CMD,0xa6); // normal display (non inverted)
_delay_ms(500); // 1 Sec delay
}
void Lcd_Write(char cd,unsigned char c){
char i;
SETPE(cs,0);
SETPE(sclk,0);
SETPE(sda,cd);
SETPE(sclk,1);
for(i=0;i<8;i++){
SETPE(sclk,0);
if(c & 0x80)
SETPE(sda,1)
else
SETPE(sda,0)
SETPE(sclk,1);
c <<= 1;
_delay_us(100);
}
SETPE(cs,1);
}
void SetX(char x){
Lcd_Write(CMD,0x10 | ((x>>4)&0x7));
Lcd_Write(CMD,x & 0x0f);
}
void SetY(char y){
char aux = 0;
while(y>7){
y -=8;
aux ++;
}
bitaddr = y-1;
Lcd_Write(CMD,0xB0 | (aux & 0x0f));
}
void Gotoxy(char x,char y){
Lcd_Write(CMD,(0xB0|(y&0x0F))); // Y axis initialisation: 0100 yyyy
Lcd_Write(CMD,(0x00|(x&0x0F))); // X axis initialisation: 0000 xxxx ( x3 x2 x1 x0)
Lcd_Write(CMD,(0x10|((x>>4)&0x07))); // X axis initialisation: 0010 0xxx ( x6 x5 x4)
}
//x dir > y dir from last line to ^
void VLine(char x,char y,char on){
char aux[8];
int i;
for(i=0;i<8;i++)
aux* = 0;
i = 7;
while(y > 9){
aux* = 0xff;
y -= 8;
i--;
}
while(y > 0){
aux* >>= 1;
aux* |= 0x80;
y --;
}
for(y=0;y<8;y++){
Lcd_Write(CMD,0xB0 | y);
SetX(x);
Lcd_Write(DATA,aux(unsigned int)y]);
}
}
// xdir is > y is always < than y2 can be used for graphs
void Line(unsigned char x,unsigned char y,unsigned char y2,unsigned char on){
char aux[8];
char o=0;
char c=1;
unsigned int index;
unsigned int i;
for(i=0;i<8;i++)
aux* = 0;
index = 0;
for(i=0;i<64;i++){
if(i >= y && i <= y2){
aux[index] |= c << o;
}
o ++;
if(o == 8){
o = 0;
index ++;
}
}
for(i=0;i<8;i++){
Lcd_Write(CMD,0xB0 | i);
SetX(x);
Lcd_Write(DATA,aux*);
}
}
void print_char(char c)
{
int i;
for ( i = 0; i < 5; i++ )
{
Lcd_Write(DATA, pgm_read_byte(&FontLookup[c - 32]*) << 1);
}
Lcd_Write(DATA,0x00);
}
void print_message(const char * message)// Write message to LCD (C string type)
{
Lcd_Write(CMD,0xae); // disable display;
while (*message){ // Look for end of string
print_char(*message++);
}
Lcd_Write(CMD,0xaf); // enable display;
}
void print_string(char * message){ // Write message to LCD (C string type)
Lcd_Write(CMD,0xae); // disable display;
while (*message){ // Look for end of string
print_char(*message++);
}
Lcd_Write(CMD,0xaf); // enable display;
}
[/code]
…
[code]/*
| \ | | / _ \ | |/ / |_ | / \ / | / | / _ \ / _ \ | | / | | _
| | | | | | | | ’ / | | / _ \ | | | | | | | | | | | | | | | | | | | |
| |\ | | || | | . \ | | / ___ \ | | | | | || | | || | | |__ | |___ | || |
|| _| _/ ||_\ || // _\ || || _/ _/ |__| _| |___/
Pro Atmel AVR zprovoznil Divous
File: main.c
*/
#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include “lcd1100.h”
//
/ Přednadstavení portů /
//
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
DDRB = 0xFF;
PORTB = 0x00;
PORTC = 0x00;
DDRC = 0xFF;
PORTD = 0x00;
DDRD = 0xFF;
PORTE = 0xFF;
DDRE = 0xFF;
PORTF = 0x00;
DDRF = 0xFF;
PORTG = 0x00;
DDRG = 0xFF;
}
int main(void)
{
port_init();
Lcd_Init();
Gotoxy(0,0);
print_message(“It works!!”);
Gotoxy(5,1);
print_message(“It works!!”);
Gotoxy(10,2);
print_message(“It works!!”);
Gotoxy(15,3);
print_message(“It works!!”);
Gotoxy(20,4);
print_message(“It works!!”);
Gotoxy(25,5);
print_message(“It works!!”);
Gotoxy(30,6);
print_message(“It works!!”);
Gotoxy(35,7);
print_message(“It works!!”);
while(1) {}
}
[/code]
Doufám, že vám tato menší inspirace pomůže k dalším úspěchům.
Edit:
Ještě dodávám menší foto, že mi to skutečně fungovalo…
administrator: přejmenováno z “Displej z Nokie 1100”******
administrator: příspěvek byl upraven
administrator: přiloženy externí soubory*
nokia-lcd-1100-by-divous.zip (4.15 KB)
pcf8814.pdf (390 KB)