راه اندازی ال سی دی نوکیا 6125

ر این آموزش قصد دارم نحوه راه اندازی ال سی دی نوکیا ۶۱۲۵ (Nokia6125 Back RGB LCD) رو با استفاده از میکروکنترلر AVR توضیح بدم.
این ال سی دی همچنین در گوشی های: Nokia6100، Nokia N70، Nokia1600، Nokia1208، Nokia2126 و Nokia2310 استفاده شده است.
درایور بکار رفته در ال سی دی نوکیا ۶۱۲۵ از نوع PCF8833 STN RGB – 132*132*3 LCD driver می باشد که بطور کلی برای کنترل ۱۳۲*۱۳۲ پیکسل بکار می رود.
اما از آنجایی که ال سی دی ما در این آموزش ۷۰*۹۸ پیکسل است، مابقی پیکسل ها نادیده گرفته می شود.
این ال سی دی کانکتور ۱۰ پین از نوع “برد به برد” نیاز دارد که من از همان گوشی این کانکتور را جدا کردم.
پایه های ال سی دی به شرح زیر است:
۱. CLK
۲. Data
۳. GND
۴. CS#
۵. RESET#
۶. Back light LED+, 7.5V
۷. Back light LED-, GND
۸. NC
۹. VddAN, 2.8V… 3.3V
۱۰. VddIO, 1.8V… 3.3V
برای درایو ال سی دی از ولتاژ ۳.۳ استفاده کردم.
میکروکنترلری که برای درایو LCD درنظر گرفتم، AVR ATMega8A هست و شماتیک اتصال آن به پین های ال سی دی آن به صورت زیر میباشد:

میکروکنترلر و ال سی دی سوار شده روی بِردبُرد به صورت تصویر زیر می باشد:

برای انتقال اطلاعات و دستورات به ال سی دی از پروتکل SPI 9bit استفاده شده است که به صورت زیر می باشد:
Here’s command protocol in 9-bit SPI:
__ __ __ __ __ __ __ __ __
CLK ___|C1|_|C2|_|C3|_|C4|_|C5|_|C6|_|C7|_|C8|_|C9|____...
Data_______<b7 ><b6 ><b5 ><b4 ><b3 ><b2 ><b1 ><b0 > ...
_ __
CS# |______________________________________________| ...
Here’s data protocol in 9-bit SPI:
__ __ __ __ __ __ __ __ __
CLK ___|C1|_|C2|_|C3|_|C4|_|C5|_|C6|_|C7|_|C8|_|C9|____...
___
Data_| |_<b7 ><b6 ><b5 ><b4 ><b3 ><b2 ><b1 ><b0 > ...
_ __
CS# |______________________________________________| ...
برای تنظیمات اولیه ال سی دی، باید دستورات و داده های زیر به ال سی دی داده شود:
command: 0x11
command: 0x20
command: 0x3A
Data: 0x05
command: 0x36
Data: 0xC8
command: 0x25
Data: 0x30
command: 0x29
command: 0x2A
Data: 0x00
Data: 97 (Number of pixel column – 1)
command: 0x2B;
Data: 0x00
Data: 69 (Number of pixel lines or rows – 1)
برنامه به صورت زیر است که با نرم افزار CodeVision AVR قابل کامپایل است:
/*******************************************************
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();
// ۱mS Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
rucJ++;
TCNT0 = ۱۲۵;//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 = ۰;
TCCR0 = 0x03;
TIFR = 0x01;
TIMSK = 0x01;
#asm("sei");
//PORTB.PORTB0 //RST#
//PORTB.PORTB1 //CS#
//PORTB.PORTB2 //SI
//PORTB.PORTB3 //SCK
PORTB.PORTB0 = ۰; //RST#
rucK = ۲۵۰;
//۱ second delay
vDelay();
vDelay();
vDelay();
vDelay();
PORTB.PORTB4 = ۱; //Status LED 1 On
vDelay();
//LCD Reset
rucK = ۱;
PORTB.PORTB0 = ۱; //RST#
vDelay();
PORTB.PORTB0 = ۰; //RST#
vDelay();
PORTB.PORTB0 = ۱; //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 = ۱;
rucK = ۲۵۰;
vDelay();
//۹۸*۷۰
ucI = 0x2A;
vCMD();
ucI = ۰;
vData();
ucI = ۹۷;
vData();
ucI = 0x2B;
vCMD();
ucI = ۰;
vData();
ucI = ۶۹;
vData();
//0xFFFF White
//0x0000 Black
while(۱)
{
ucI = 0x2c; // Screen data command
vCMD();
//First line
//Border white
for(j = ۰; j < ۹۸; j++)
{
//۱st byte: BBBBB GGG
//۲nd byte: GGG RRRRR
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
}
//Second line
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//Border Black
for(j = ۰; j < ۹۶; j++)
{
//۱st byte: BBBBB GGG
//۲nd byte: GGG RRRRR
ucI = 0x00;
vData();
ucI = 0x00;
vData();
}
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//Blue screen
for(i = ۰; i < ۶۶; i++)
{
//Border
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
ucI = 0x00;
vData();
ucI = 0x00;
vData();
for(j = ۰; j < ۹۴; j++)
{
//۱st byte: BBBBB GGG
//۲nd 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 = ۰; j < ۹۶; j++)
{
//۱st byte: BBBBB GGG
//۲nd byte: GGG RRRRR
ucI = 0x00;
vData();
ucI = 0x00;
vData();
}
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
//White border
for(j = ۰; j < ۹۸; j++)
{
//۱st byte: BBBBB GGG
//۲nd byte: GGG RRRRR
ucI = 0xFF;
vData();
ucI = 0xFF;
vData();
}
vDelay(); //۲۵۰ mS Delay
//Green screen
ucI = 0x2c; // Screen data command
vCMD();
for(i = ۰; i < ۷۰; i++)
{
for(j = ۰; j < ۹۸; j++)
{
ucI = 0x07;
vData();
ucI = 0xE0;
vData();
}
}
vDelay(); // ۲۵۰mS Delay
//Red Screen
ucI = 0x2c; // Screen data command
vCMD();
for(i = ۰; i < ۷۰; i++)
{
for(j = ۰; j < ۹۸; j++)
{
ucI = 0x00;
vData();
ucI = 0x1F;
vData();
}
}
vDelay(); //۲۵۰mS
};
}
void vCMD()
{
PORTB.PORTB1 = ۰; //CS#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB2 = ۰; //SI#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
vSend();
}
void vData()
{
PORTB.PORTB1 = ۰; //CS#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB2 = ۱; //SI#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
vSend();
}
void vSend()
{
vClk();
if(ucI & 0x80)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x40)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x20)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x10)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x08)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x04)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x02)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
if(ucI & 0x01)
PORTB.PORTB2 = ۱; //SI#
else
PORTB.PORTB2 = ۰; //SI#
vClk();
PORTB.PORTB1 = ۱; //CS#
}
void vClk()
{
PORTB.PORTB3 = ۰; //SCK#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
PORTB.PORTB3 = ۱; //SCK#
#asm("NOP");
#asm("NOP");
#asm("NOP");
#asm("NOP");
}
void vDelay()
{
rucJ = ۰;
while(rucJ < rucK) //۱۰۰ mS delay
{
#asm("sleep");
};
}
مطالعه بیشتر: How to Drive Nokia Tiny LCDs
برای آموزش های بیشتر به بلاگ مراجعه کنید.

نوشته شده توسط: محمد مهدی کفش کنان – مهندس الکترونیک و برنامه نویسی فول استک و بنیانگذار WiCardTech