راه اندازی ال سی دی نوکیا 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
