در این آموزش قصد دارم نحوه راه اندازی ال سی دی نوکیا ۶۱۲۵ (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
برای آموزش های بیشتر به دسته آموزش مراجعه کنید.