драйвер ЖК-дисплея Nokia (6125 LCD) программирование
Вот простая схема и код, совместимый с драйвером PCF8833 (драйвер ЖК-дисплея Nokia — mini LCD), например 1208, 1600, 2126, 2310, 6100, 6125, N71 (миниатюрные ЖК-дисплеи).
Схема и код в этом проекте совместимы с драйвером ЖК-дисплея PCF8833 STN RGB — 1321323.
Этот драйвер ЖК-дисплея использовался для некоторых крошечных ЖК-дисплеев Nokia, таких как 1208, 1209, 1600, 2126, 2310, 6100 и 6125, 6136, задний ЖК-дисплей N71.
***»»Проекты по электронике, программированию и Arduino, включая исходные коды, схемы и планы печатных плат для инженеров, студентов и любителей»»***
ЖК-дисплей, над которым я работал, представляет собой ЖК-дисплей размером 98*70 пикселей, который я снял с разбитого Nokia 6125.
Для этого ЖК-дисплея требуется межплатный разъем, который я удалил из печатной платы Nokia. Линия транзакции для моего ЖК-дисплея представляет собой 9-битный SPI, который не имеет линии передачи и принимает только данные или команды от хоста.
Хост (контроллер, драйвер и т. д.), который я использовал, — это микроконтроллер ATMega8A.
ATMega8A имеет 8-битный SPI, а не 9-битный, поэтому я использовал входы/выходы напрямую, а не внутренний модуль SPI.
Схема драйвер ЖК-дисплея Nokia
Вот моя схема на макетной плате:
Схема
Here’s the pinout of my LCD:
1. CLK
2. Data
3. GND
4. CS#
5. RESET#
6. Подсветка LED+, 7,5 В.
7. Подсветка LED-, GND
8. NC
9. VddAN, 2.8V… 3.3V
10. VddIO, 1.8V… 3.3V
Вот схема:
Протокол транзакции
Когда на выводе Reset# низкий уровень, это означает, что ЖК-дисплей находится в состоянии сброса и не принимает команды и данные.
Когда CS# имеет низкий уровень, ЖК-дисплей будет принимать команды/данные.
Вот командный протокол в 9-битном SPI:
__ __ __ __ __ __ __ __ __
CLK ___|C1|_|C2|_|C3|_|C4|_|C5|_|C6|_|C7|_|C8|_|C9|____...
Data_______<b7 ><b6 ><b5 ><b4 ><b3 ><b2 ><b1 ><b0 > ...
_ __
CS# |______________________________________________| ...
Вот протокол данных в 9-битном SPI:
__ __ __ __ __ __ __ __ __
CLK ___|C1|_|C2|_|C3|_|C4|_|C5|_|C6|_|C7|_|C8|_|C9|____...
___
Data_| |_<b7 ><b6 ><b5 ><b4 ><b3 ><b2 ><b1 ><b0 > ...
_ __
CS# |______________________________________________| ...
Инициализация ЖК-дисплея Nokia
Для инициализации я сначала отправил эти команды и данные:
command: 0x11
command: 0x20
command: 0x3A
Data: 0x05
command: 0x36
Data: 0xC8
command: 0x25
Data: 0x30
command: 0x29
command: 0x2A
Data: 0x00
Data: 97 (Кол-во столбцов пикселей — 1)
command: 0x2B;
Data: 0x00
Data: 69 (Количество строк или строк пикселей — 1)
Пример исходного кода
Вот пример исходного кода для изменения цвета фона ЖК-дисплея:
/*******************************************************
This program was created by the
CodeWizardAVR V3.12 Advanced
Chip type : ATmega8A
AVR Core Clock frequency: 8.000000 MHz (Internal)
*******************************************************/
#include <mega8.h>
register unsigned char ucI,rucJ,rucK,i,j;
void vCMD();
void vData();
void vSend();
void vClk();
void vDelay();
// 1mS Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
rucJ++;
TCNT0 = 125;//about 1mS
TIFR = 0x01;
}
void main(void)
{
//Microcontroller init
PORTB = 0x0A;
DDRB = 0x3F;
OSCCAL = 0x99;
//Low level external interrupts - sleep enable
MCUCR = 0x8A;
//Timer 0
TCNT0 = 0;
TCCR0 = 0x03;
TIFR = 0x01;
TIMSK = 0x01;
#asm("sei");
//PORTB.PORTB0 //RST#
//PORTB.PORTB1 //CS#
//PORTB.PORTB2 //SI
//PORTB.PORTB3 //SCK
PORTB.PORTB0 = 0; //RST#
rucK = 250;
//1 second delay
vDelay();
vDelay();
vDelay();
vDelay();
PORTB.PORTB4 = 1; //Status LED 1 On
vDelay();
//LCD Reset
rucK = 1;
PORTB.PORTB0 = 1; //RST#
vDelay();
PORTB.PORTB0 = 0; //RST#
vDelay();
PORTB.PORTB0 = 1; //RST#
//LCD Init
ucI = 0x11;
vCMD();
ucI = 0x20;
vCMD();
ucI = 0x3A;
vCMD();
ucI = 0x05;
vData();
ucI = 0x36;
vCMD();
ucI = 0xC8;
vData();
ucI = 0x25;
vCMD();
ucI = 0x30;
vData();
ucI = 0x29;
vCMD();
PORTB.PORTB5 = 1;
rucK = 250;
vDelay();
//98*70
ucI = 0x2A;
vCMD();
ucI = 0;
vData();
ucI = 97;
vData();
ucI = 0x2B;
vCMD();
ucI = 0;
vData();
ucI = 69;
vData();
//0xFFFF White
//0x0000 Black
while(1)
{
ucI = 0x2c; // Screen data command
vCMD();
//First line
//Border white
for(j = 0; j < 98; j++)
{
//1st byte: BBBBB GGG
//2nd byte: GGG RRRRR
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
}
//Second line
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//Border Black
for(j = 0; j < 96; j++)
{
//1st byte: BBBBB GGG
//2nd byte: GGG RRRRR
ucI = 0x00;
vData();
ucI = 0x00;
vData();
}
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//Blue screen
for(i = 0; i < 66; i++)
{
//Border
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
ucI = 0x00;
vData();
ucI = 0x00;
vData();
for(j = 0; j < 94; j++)
{
//1st byte: BBBBB GGG
//2nd byte: GGG RRRRR
ucI = 0xF8;
vData();
ucI = 0x00;
vData();
}
ucI = 0x00;
vData();
ucI = 0x00;
vData();
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
}
//Border
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
for(j = 0; j < 96; j++)
{
//1st byte: BBBBB GGG
//2nd byte: GGG RRRRR
ucI = 0x00;
vData();
ucI = 0x00;
vData();
}
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//White border
for(j = 0; j < 98; j++)
{
//1st byte: BBBBB GGG
//2nd byte: GGG RRRRR
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
}
vDelay(); //250 mS Delay
//Green screen
ucI = 0x2c; // Screen data command
vCMD();
for(i = 0; i < 70; i++)
{
for(j = 0; j < 98; j++)
{
ucI = 0x07;
vData();
ucI = 0xE0;
vData();
}
}
vDelay(); // 250mS Delay
//Red Screen
ucI = 0x2c; // Screen data command
vCMD();
for(i = 0; i < 70; i++)
{
for(j = 0; j < 98; j++)
{
ucI = 0x00;
vData();
ucI = 0x1F;
vData();
}
}
vDelay(); //250mS
};
}
void vCMD()
{
PORTB.PORTB1 = 0; //CS#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB2 = 0; //SI#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
vSend();
}
void vData()
{
PORTB.PORTB1 = 0; //CS#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB2 = 1; //SI#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
vSend();
}
void vSend()
{
vClk();
if(ucI & 0x80)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x40)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x20)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x10)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x08)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x04)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x02)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
if(ucI & 0x01)
PORTB.PORTB2 = 1; //SI#
else
PORTB.PORTB2 = 0; //SI#
vClk();
PORTB.PORTB1 = 1; //CS#
}
void vClk()
{
PORTB.PORTB3 = 0; //SCK#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB3 = 1; //SCK#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
}
void vDelay()
{
rucJ = 0;
while(rucJ < rucK) //100 mS delay
{
#asm("sleep");
};
}
Автор: М. Мahdi К. Кanan — инженер по электронике и программированию полного цикла, основатель WiCardTech