裸機シリーズ--s 3 c 2400のLCD


プラットフォームmini 2440
コンパイルツールads 1.2
lcd型ソニー3.5インチTFT液晶パネル
 
lcdの駆動を開始するのは前学期末で、その時もうすぐ期末になって、試験の準備をしなければなりません.たぶん見ていませんが、勉強の効率が低いと感じています.試験が終わったら、家の中で農作業を手伝って、家に帰って半月もいました.学校に帰ってきたのは8月分で、帰ってから間もなくlcdを駆動して、総括するつもりでした.しかし、后ろのlinux计画は、何が私の神経を刺激したのか分からないので、进度を速めて勉强しなければならないと感じて、それから引きずって今日になって、突然この勉强が着実にしなければならないと感じて、総括は勉强にとってとても重要で、自分で知识を分类して、重点を分けて、それから分析の総括能力を高めます.同時にまとめると、いくつかの問題や不足も見られます.以上の理由から、裸機シリーズの最後のlcdとタッチスクリーンの2つの駆動を振り返り続け、シリーズのまとめをしましょう.
1.0 LCD LCD LCDとタッチパネル
まずこの2つを区別して、多くの買った液晶パネルはすべてタッチスクリーンを持っていますが、1つのスクリーンしかありません.私は最初からこの2つのスクリーンをはっきり分けていませんでした.実はここには2つのスクリーンがあります.別々で、独立しています.私がタッチスクリーンの実験をしたとき、私は最初からこのスクリーンが明るくなくて(lcdが駆動していない)タッチスクリーンを駆動することができますか?実際には可能であり、彼らのインタフェースは分離されており、タッチスクリーンはADと一緒に置かれており、主にタッチスクリーンの実現が主にAD計算位置を運用しているためである.
1.1 lcdの単色階調16 bpp 24 bppパレット
lcdは表示装置が1画素点ずつ表示されるために用いられ、RTCテレビも1点ずつ表示されることを思い出す.だから1つの画素点を表示して単色あるいはカラーで表示することができて、白黒テレビとカラーテレビと同じように、単色はカラーがなくて白黒だけで、1つの画素点は1人で表示して、黒あるいは白で、美術に対して私達はよく知らないで、しかし私達はすべて美術のスケッチを知っていて、鉛筆で絵を描きます.これは私达が1枚の絵をスケッチする时ある地方は少し浓くてある地方は薄くて、このようにいくつかの立体感を见ることができて、同様に、表示に対して私达も黒と白の间をいくつかの阶に分けることができて、例えば4级の階調、このように1つの画素の点は2位で表す必要があって、白黒の间の4种类を表します同時に,各画素点をbppで何ビットで表し,4階調でも2 bppである.もちろん階調がいくら多くても白黒で、色が鮮やかに見えるので、ここでまず理解する必要があります.自然界の色はred green blueの3色で混ざることができます(そうは言えませんが、これは人間の目の視覚効果にすぎません.3色が混ざって他の色になったわけではありません.そうではありません.目が他の色になったように見えます)ので、16 bppは画素ごとに16ビットです.これにより,5,6,5または5,5,5,1でそれぞれ赤緑青が占めるビット数を表し,後の1で透明度を表すことができる.24 bppでは赤緑青がそれぞれ8位を占めているので、これでは異なる組み合わせでいろいろな色を表すことができますが、8 bppでは8位を使い、赤緑青では3位未満を使います.このように色表示が豊富ではなく、表示能力が弱いので、パレットを導入しました.デバッグボードは実はメモリで、mini 2440は256 x 16256が8 bppのインデックスとして、各ユニット16ビットは画素点を表し、lcdに16 bppの色が表示される.
2.0フレーム周波数、行周波数、ピクセルクロック
lcdを理解する鍵はlcdの働き方を理解することにあり、まず重要で簡単な事実はlcdディスプレイが左から右に、上から下まで私たちがノートを書くように、突然一緒に書いた作文帳がこのように似ていることを考えて、本当に、それは説明するのがいいです.1つの画素が表示されます.1ページを表示する周波数はフレーム周波数、フィールド周波数とも呼ばれ、垂直周波数と私达の比较的に熟知しているディスプレイの周波数(つまり私达が设置したあのディスプレイの周波数、私达が1年生の时を覚えていて、学校のコンピュータはとても腐っていて、あのコンピュータの先生は私达に言って、私达が机に行く时ディスプレイの周波数を75に変えましょう、覚えていません次に行周波数とは、1行を表示する周波数、液晶水平周波数、最後に画素周波数、各画素点の周波数です.
もちろんもう一つ重要な問題は、各フレームのデータが始まる前に準備する時間があり、一行の後にもいくつかの時間があり、次の行に戻る時間があります.そして、最後の画素を表示した後も画素点を表示できない時間があります.これは私たちの作文帳のように、上下左右に何も書いていないところがあります.私たちが書いたのは真ん中の四角い格子だけです.
本当にプログラムの中で使う必要があるのはlcdのクロック周波数を設定することで、これらのクロック周波数はこれらの使えない時間と私たちが表示する必要がある時間を考慮する必要がありますが、これらの使えない時間は2440マニュアルのTFT LCDのタイミングチャートを詳しく見て、その図は理解して、そのタイミングチャートは2つの部分を含んで、上は1フレームのタイミングです.次のフレームの中の1つの小さい周期は1行のタイミングで、具体的な対応するパラメータはVSPW、VBSD、VFPD、HSPW、HBSD、HFPDのようなパラメータは理解して、またLINEVAL HOZVALの2つはそれぞれ有効な行数と1行の有効な点数で、もちろんここのパラメータの手帳の上ですべて対応して1をプラスして、ここで注意して、例えば私達のスクリーン幅240、ここで有効な1行の画素点はLINEVAL+1=240なので、LINEVALの値は239です.
最後にスクリーンの幅と高さを知って、lcdマニュアルの表示できない時間パラメータを参照して、最後にlcdのフレーム周波数Frame Rateを計算することができます.もちろん、ここではクロックの基準信号にも関連しています.lcdが使用するVCLKはシステムのHCLKから分周されているので、この分周のパラメータを設定することに注意してください.
3.0レジスタの設定
lcdのレジスタは比較的多く17個あるが,TFT液晶パネルを用いて設定する必要があるレジスタは多くなく,主にlcdの制御レジスタ,LCDCON 1~5とlcdフレームメモリアドレスレジスタLCDSADDR 1~3である.具体的な設定は必要に応じて、主な参考マニュアルには提供されている参考プログラムもあります.
4.0発生したいくつかの問題
1私が买ったのはソニー3.5寸lcdで、フレンドリーな腕はX-35と呼ばれています.私が手に持っているこの画面のマニュアルはあまりよくありません.また、ネット上にもこの画面の资料がたくさんありません.マニュアルがそのように书かれているような気がします.ソニーのような会社のやり方ではありません.元の工场のマニュアルではないかと疑っています.タイミングチャートを見てみて結果が出るかどうかも分からないし、私のレベルが低すぎて見られなかったのではないか分からないので、これらのパラメータをどうやって出すか知っている人がいたら教えてください.ありがとうございます.后ろは仕方がなくて、ネット上で探して、またフォーラムの中で闻いて、も探し当てていないで、后ろは突然参考プログラムがあるのではないかと思って、急いで见て、中はやはりこのようなパラメータの値があって、しかしあなたは1つ1つを见て、命名の関系のため、でもやはりとても良いです.
2.プログラムを书いた后に液晶のスクリーンは反応していないで、プログラムが始まるのが比较的に简単なため、その上私はやはり参考プログラムと赵先生のブログによって书いたので、私の第1感じはこの问题は:时计の问题かメモリのアドレスの设置の问题で、やはりコードを见る时フレームのメモリのアドレスの间违いです.
3.液晶画面に縞ができて、画像がなくて、これはlcd信号の極性をチェックして、レジスタLCDCON 5の信号の極性について具体的には相応のデータマニュアルを参考にすべきで、しかし私のマニュアルにも見つからなかったので、私が参考にした参考コードの、ここINVDEN信号の極性は必ず反転して、ここは私のX-35スクリーンにとって、そうでないと前面のLCDストライプが表示されます.もちろんストライプが現れるのは他にも原因があるかもしれません.
コード:
/*************************************************
file name 	lcd.c
function	     TFT   
			  sunflower  
    	mini2440   
			  3.5 TFT    X35
    	    240 x 320
			16bpp      
			       
    	         ,        
			     lcd    
    	2011-08-06
  		   
problem		  
  		  
*************************************************/
#define	GLOBAL_CLK		1

#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"

#define baudrate 115200 

#define	LCD_WIDTH	240
#define	LCD_HEIGHT	320
//#define LCD_CLKCAL	17	//        17       4        
							//       25 30     
#define LCD_CLKCAL	17		

#define	LCD_RIGHT_MARGIN 25
#define	LCD_LEFT_MARGIN  0
#define	LCD_HSYNC_LEN    4

#define	LCD_UPPER_MARGIN 0
#define	LCD_LOWER_MARGIN 4
#define	LCD_VSYNC_LEN 9

#define	LCD_XSIZE	LCD_WIDTH
#define	LCD_YSIZE	LCD_HEIGHT
#define	SCR_XSIZE	LCD_WIDTH
#define	SCR_YSIZE	LCD_HEIGHT

extern const unsigned char sunflower_240x320[] ;

volatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE] ; //LCD BUFFER

#define M5D(n)		((n)&0x1fffff)  //             21 
#define	LCD_ADDR	((U32)(LCD_BUFFER))	
/**********************************
void delay(int times)
{
	int i = 1000 ;
	while(times--)
	{
		for(; i>0; --i)
			;
	}
}
************************************/
/***********************************
UART_int   led IO  GPBCON5-8
   GPBHCON     
         
       
************************************/
void UART_int_init(void)
{
	/********configuration LED IO port**********/
	rGPBCON &= ~(0xff<<10) ;
	rGPBCON |= 0x55<<10 ;
	
	/*******configuration GPHCON to UART*******/
	rGPHCON &= ~(0xf<<4) ;
	rGPHCON |=  0xa<<4 ;
	
	/****configuration UART0 communication register******/
	rULCON0 = 0x03 ;						//8-bits,1 stop bit, no parity
	rUCON0  = 0x05 ;
	rUBRDIV0= (int)(PCLK/baudrate/16) -1 ;	//configuration UART baudrate
	
	/*****clean interrupt bit clea RX_INT******/
	rSUBSRCPND |= 0x1 ;
	rSRCPND |= 1<<28 ;
	rINTPND |= 1<<28 ;

	/******open UART interrupt*********/
	rINTSUBMSK &= ~(0x1) ;
	rINTMSK &= ~(0x1<<28) ;	
}

//UART send byte
void UART_send_byte(char Tx_data)
{
	while(!(rUTRSTAT0&0x2)) ;//wait Tx empty
	if(Tx_data == '
') //Tx '
' { rUTXH0 = 0x0d ; while(!(rUTRSTAT0&0x2)) ; rUTXH0 = 0x0a ; } else { rUTXH0 = Tx_data ; } } //UART send string void UART_send_string(const char *str) { while(*str) { UART_send_byte(*str) ; str++ ; } } //UART receive byte void UART_receive_byte(void) { char temp ; while(!(rUTRSTAT0&0x1)) ; //wait RX ready temp = rURXH0 ; switch(temp) // { case 's': rGPBDAT &= ~(0xf<<5) ; break ; case 'p': rGPBDAT |= (0xf<<5) ; break ; } UART_send_byte(temp) ; } /******************************************* 1 , , led ********************************************/ void __irq UART0_interrupt(void) { /******clean interrupt bit*************/ rSUBSRCPND |= 0x1 ; rSRCPND |= 1<<28 ; rINTPND |= 1<<28 ; rGPBDAT &= ~(0xf<<5) ; //lighten led UART_receive_byte(); } /**************************************************************** function initialize LCD IO port VD[0:15] VM VLINE VCLK VFREAM input void return void *****************************************************************/ static void Lcd_port_init(void) { rGPCUP = 0xffffffff ; //Disable Pull-up register rGPCCON = 0xaaaa02a8 ; //Initialize VD[7:0],VM,VFREAM,VLINE,VCLK rGPDUP = 0xffffffff ; //Disable Pull-up register rGPDCON = 0xaaaaaaaa ; //Initialize VD[15:8] } /**************************************************************** function configarution LCDCON1-5 LCDSADDR1-3 LCD INTERRUPT TPAL etc register TFT 16bpp input void return void *****************************************************************/ static void Lcd_init(void) { rLCDCON1 = (LCD_CLKCAL<<8) | (3<<5) | (12<<1) ; rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0); rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH - 1) << 8) | (LCD_LEFT_MARGIN << 0); rLCDCON4 = (LCD_HSYNC_LEN << 0); rLCDCON5 = (1<<11) | (1 << 9) | (1 << 8) | (1<<6) | (1 << 3) | (1 << 0) ; rLCDSADDR1 = ((LCD_ADDR>>22)<<21) | (M5D(LCD_ADDR>>1)) ; //LCDBASEL OFFSIZE=0,PAGEWIDTH=LCD_WIDTH, x2 16bpp 2 ,>>1 16bpp rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2)>>1) ; rLCDSADDR3 = LCD_WIDTH ; rLCDINTMSK |= 3 ; // rTCONSEL = 0 ; //LPC3600 LCC3600 rTPAL = 0 ; // } /**************************************************************** function Envid turn on or off input onoff 1,Envid turn on return void *****************************************************************/ static void Lcd_EnvidOnOff(int onoff) { if(onoff==1) rLCDCON1 |= 1 ; //ENVID ON else rLCDCON1 &= ~(1<<0) ; //ENBID OFF } /**************************************************************** function LCD power enable input pwren 1, enable lcd power return void *****************************************************************/ static void Lcd_PowerEnable(int pwren) { rGPGUP |= (1<<4) ; //Pull-up Disable rGPGCON |= (3<<8) ; //GPG4 is LCD_PWREN rLCDCON5&= ~(1<<5) ; //invpwren rLCDCON5 = rLCDCON5 & ~(1<<3)|(pwren<<3) ; //PWREN } /**************************************************************** function Filling sole colour into LCD background input c colour return void *****************************************************************/ static void Lcd_FillCor(U16 c) { unsigned int x,y ; for(y=0; y<SCR_YSIZE; y++) { for(x=0; x<SCR_XSIZE; x++) { LCD_BUFFER[y][x] = c ; } } } /**************************************************************** function Paint picture input x0 y0 assign start bit level vertical the wide and high of picture *bmp the picture string return void *****************************************************************/ static void Paint_BMP(int x0, int y0, int level, int vertical, const unsigned char *bmp) { int x, y ; U32 col ; int p = 0 ; for(y=0; y<vertical; y++) { for(x=0; x<level; x++) { col = bmp[p+1] | (bmp[p]<<8) ; //16bpp if( ((x0+x)<SCR_XSIZE) && ((y0+y)<SCR_YSIZE)) LCD_BUFFER[y0+y][x0+x] = col ; p += 2 ; } } } /******************************************************************* UART PCLK , PCLK , 2440 。 PLLCON CPU (FCLK), FCLK HCLK PCLK , PCLK 。 *****************************************************************/ int Main(void) { /*****************【CLOCK】******************/ MMU_Init(); ChangeMPllValue(127,2,1); //405MHZ ChangeClockDivider(13,12); //1:3:6 /**************【UART】**********************/ UART_int_init() ; UART_send_string("wo zhen de hen yun si
") ; pISR_UART0 = (U32)UART0_interrupt ; /*************【LCD】************************/ Lcd_port_init() ; Lcd_init() ; Lcd_PowerEnable(1) ; Lcd_EnvidOnOff(1) ; UART_send_string("LCD initial
") ; while(1) { //Lcd_FillCor((0x00<<11) | (0x00<<5) | (0x00<<0)) ; //clear screen //Paint_BMP(0,0,240,320,sunflower_240x320) ; //filling picture sunflower Lcd_FillCor(0xffff) ; } return 0 ; }