LPC1788 LCD 学习

/ 0评 / 0

好不容易继续来搞搞这个单片机,虽然出了好多年,但是被ST打得体无完肤.就有LCD控制器,SDRAM这个优势来说,基本上已经到了老的的程度了.而且用起这个LCD,好像也不是特别的复杂,原来以为很麻烦的,因为手册说的什么专用DMA啊,专用图形加速啊.在调试过程中出现了好多次的闪屏,差点以为是自己的板子画得有问题,不过后来发现是总线占用过长,需要优化一下.

开始做LCD,肯定要开辟RAM空间.先算算我的屏幕是1024*600[LPC1788能支持到1024*768,就算是LPC4357这种鸡血,也是这个分辨率.],然后从RAM的尾端开始截取部分RAM来用.计算公式:

0xA1FFFFFF - 1024[H]*600[V]*2[Bit] = 0xA1ED3FFF | 153.6KB

然后实际上就是往自己RAM写东西,他就会倒到屏幕上.可以支持24位模式的,但是好像用不着,所以我还是乖乖的看看565模式.反正我也是垃圾屏了.因为多次要用到基地址,另外应该写一个刷屏测试的,所以,就先做好头文件,好让自己知道该干什么.

#ifndef __LCD70_LPC177x_8x_H_
#define __LCD70_LPC177x_8x_H_
#define LCD_SDRAM_BASE 0xA1ED3FFF // 0xA1FFFFFF - 1024[H]*600[V]*2[Bit] = 0xA1ED3FFF | 153.6KB
extern void LCD_Clear(uint16_t x0, uint16_t y0, uint16_t xSize, uint16_t ySize, uint32_t color);
extern void vLCD_Init(void);
#endif

大致梳理初始化流程:

  1. 设置基地址UPBASE
  2. 设置IO复用
  3. 打开电源和背光
  4. 打开LCD外设时钟
  5. 设置分频和时序
  6. 清空调色板
  7. 使能LCD

其实初始化代码大多数抄我这个的就可以,哪里需要额外配置的,我这儿说说:

void vLCD_Init(void)
{
    uint32_t i;
    uint32_t *pPal;
    LPC_LCD->UPBASE = (uint32_t)LCD_SDRAM_BASE;
    LPC_IOCON->P2_12 = 0x25;		//LCDR3
    LPC_IOCON->P2_6  = 0x27;	    //LCDR4
    LPC_IOCON->P2_7  = 0x27;		//LCDR5
    LPC_IOCON->P2_8 =  0x27;		//LCDR6
    LPC_IOCON->P2_9  = 0x27;		//LCDR7
    LPC_IOCON->P1_20 = 0x27;		//LCDG2
    LPC_IOCON->P1_21 = 0x27;		//LCDG3
    LPC_IOCON->P1_22 = 0x27;		//LCDG4
    LPC_IOCON->P1_23 = 0x27;		//LCDG5
    LPC_IOCON->P1_24 = 0x27;		//LCDG6
    LPC_IOCON->P1_25 = 0x27;		//LCDG7
    LPC_IOCON->P2_13 = 0x27;		//LCDB3
    LPC_IOCON->P1_26 = 0x27;    	//LCDB4
    LPC_IOCON->P1_27 = 0x27;		//LCDB5
    LPC_IOCON->P1_28 = 0x27;		//LCDB6
    LPC_IOCON->P1_29 = 0x27;		//LCDB7
    LPC_IOCON->P2_0  = 0x27;		//PWR
    LPC_IOCON->P2_2  = 0x27;		//CP
    LPC_IOCON->P2_3  = 0x27;		//FP
    LPC_IOCON->P2_4  = 0x27;		//AC
    LPC_IOCON->P2_5  = 0x27;		//LP
    // 3V3电源控制脚
    LPC_IOCON->P5_1 = 0x20;
    // 5V电源控制脚
    LPC_IOCON->P5_2 = 0x20;
    /*3V3 5V power enable*/
    LPC_GPIO5->DIR = (1 << 1) | (1 << 2);
    LPC_GPIO5->CLR = (1 << 1) | (1 << 2);
    // 背光控制脚
    LPC_IOCON->P2_1 = 0x20;
    /*Back light enable for 4.3*/
    LPC_GPIO2->DIR |= (1 << 1);
    LPC_GPIO2->CLR |= (1 << 1);
    //Turn on LCD controller power/clock control bit
    LPC_SC->PCONP |= ((uint32_t)(1 << 0));
    LPC_SC->LCD_CFG = 0x03;
    // Disable cursor
    LPC_LCD->CRSR_CTRL &= ~(1 << 0);
    // disable GLCD controller
    LPC_LCD->CTRL = 0;
    // RGB565
    LPC_LCD->CTRL |= (6 << 1);
    // TFT panel
    LPC_LCD->CTRL |= (1 << 5);
    // single panel
    LPC_LCD->CTRL &= ~(1 << 7);
    // notmal output
    LPC_LCD->CTRL &= ~(1 << 8);
    // little endian byte order
    LPC_LCD->CTRL &= ~(1 << 9);
    // little endian pix order
    LPC_LCD->CTRL &= ~(1 << 10);
    // disable power
    LPC_LCD->CTRL &= ~(1 << 11);
    LPC_LCD->TIMH = 0x9F9F28FC;
    LPC_LCD->TIMV = 0x170C2657;
    LPC_LCD->LE = 0;
    LPC_LCD->INTMSK = 0;
    LPC_LCD->POL  = (0x01 << 26) | ((1024 - 1) << 16) | (0x0 << 14) | (0x0 << 13) | (0x0 << 12) | (0x0 << 11);
    LPC_LCD->UPBASE = (uint32_t)((uint16_t *)LCD_SDRAM_BASE);
    /* clear palette */
    pPal = (uint32_t *) (&(LPC_LCD->PAL));
    for(i = 0; i < 128; i++)
    {
        *pPal = 0;
        pPal++;
    }
    // 使用LCD控制器
    LPC_LCD->CTRL |= (1 << 0);
    LPC_LCD->CTRL |= (1 << 11);
}

如果布线不一样,就改IO的,LPC_LCD->TIMH和LPC_LCD->TIMV需要根据手册计算.

1

这些对着你屏幕手册写就可以,而POL,则只需要改掉1024这值,然后如果没显示,那肯定是时钟过高,那要调整CFG,CFG越低其实越好的,对于刷新率要求不是很高的情况下.因为我屏幕比较大,所以0x03已经足够低了,如果你分辨率很低的话,比如480x272.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注