📄 drv_glcd.c
字号:
/*************************************************************************
*
* complie BY keil v4.22
*
* 作者:YJ
* 创建时间:2011-07-25
* 版本:1.1
**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "drv_glcd.h"
#include "lpc177x_8x_clkpwr.h"
#include "lpc177x_8x_pinsel.h"
#include "sdram_k4s561632j.h"
#define C_GLCD_CLK_PER_LINE (C_GLCD_H_SIZE + C_GLCD_H_PULSE + C_GLCD_H_FRONT_PORCH + C_GLCD_H_BACK_PORCH)
#define C_GLCD_LINES_PER_FRAME (C_GLCD_V_SIZE + C_GLCD_V_PULSE + C_GLCD_V_FRONT_PORCH + C_GLCD_V_BACK_PORCH)
#define LCD_VRAM_BASE_ADDR ((uint32_t)SDRAM_BASE_ADDR + (uint32_t)SDRAM_SIZE - 0x01000000)
/*************************************************************************
*功能:LCD显示初始化
*参数:无
*************************************************************************/
void GLCD_Init (void)
{
// Assign pins
LPC_IOCON->P1_31 &= ~(0x1F); //set P1.31 GPIO
LPC_GPIO1->DIR |= (0x1<<31);
LPC_IOCON->P1_20 = 0x27;
LPC_IOCON->P1_21 = 0x27;
LPC_IOCON->P1_22 = 0x27;
LPC_IOCON->P1_23 = 0x27;
LPC_IOCON->P1_24 = 0x27;
LPC_IOCON->P1_25 = 0x27;
LPC_IOCON->P1_26 = 0x27;
LPC_IOCON->P1_27 = 0x27;
LPC_IOCON->P1_28 = 0x27;
LPC_IOCON->P1_29 = 0x27;
LPC_IOCON->P2_1 = 0x20;
LPC_IOCON->P2_2 = 0x27;
LPC_IOCON->P2_3 = 0x27;
LPC_IOCON->P2_4 = 0x27;
LPC_IOCON->P2_5 = 0x27;
LPC_IOCON->P2_6 = 0x27;
LPC_IOCON->P2_7 = 0x27;
LPC_IOCON->P2_8 = 0x27;
LPC_IOCON->P2_9 = 0x27;
LPC_IOCON->P2_13 = 0x27;
LPC_IOCON->P4_29 = 0x27;
#if (C_GLCD_BitsPP == 32)
LPC_GPIO1->CLR |= (0x1<<31);
LPC_IOCON->P0_4 = 0x27; //VD0
LPC_IOCON->P0_5 = 0x27; //VD1
LPC_IOCON->P4_28 = 0x27; //VD2
LPC_IOCON->P0_6 = 0x27; //VD8
LPC_IOCON->P0_7 = 0x27; //VD9
LPC_IOCON->P0_8 = 0x27; //VD16
LPC_IOCON->P0_9 = 0x27; //VD17
LPC_IOCON->P2_12 = 0x27; //VD18
#endif
#if (C_GLCD_BitsPP == 16)
LPC_GPIO1->CLR &= ~(0x1<<31);
LPC_IOCON->P0_4 &= ~(0x7); //VD0
LPC_IOCON->P0_5 &= ~(0x7); //VD1
LPC_IOCON->P4_28 &= ~(0x7); //VD2
LPC_IOCON->P0_6 &= ~(0x7); //VD8
LPC_IOCON->P0_7 &= ~(0x7); //VD9
LPC_IOCON->P0_8 &= ~(0x7); //VD16
LPC_IOCON->P0_9 &= ~(0x7); //VD17
LPC_IOCON->P2_12 &= ~(0x7); //VD18
#endif
/*Back light enable*/
LPC_GPIO2->DIR = (1<<1);
LPC_GPIO2->SET= (1<<1);
//Turn on LCD clock
CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCLCD, ENABLE);
// Disable cursor
LPC_LCD->CRSR_CTRL &=~(1<<0);
// disable GLCD controller
LPC_LCD->CTRL = 0;
// 24 bpp
#if (C_GLCD_BitsPP == 32)
LPC_LCD->CTRL &= ~(0x07 <<1);
LPC_LCD->CTRL |=(5<<1);
#endif
#if (C_GLCD_BitsPP == 16) //16bpp 5:6:5
LPC_LCD->CTRL &= ~(0x07 <<1);
LPC_LCD->CTRL |=(0x6<<1);
#endif
// 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);
// init pixel clock
LPC_SC->LCD_CFG = (int)(CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER) / ((uint32_t)C_GLCD_PIX_CLK))-1;
// bypass inrenal clk divider
LPC_LCD->POL |=(1<<26);
// clock source for the LCD block is HCLK
LPC_LCD->POL &= ~(1<<5);
// LCDFP pin is active LOW and inactive HIGH
LPC_LCD->POL |= (1<<11);
// LCDLP pin is active LOW and inactive HIGH
LPC_LCD->POL |= (1<<12);
// data is driven out into the LCD on the falling edge
LPC_LCD->POL |= (1<<13);
// active high
LPC_LCD->POL &= ~(1<<14);
LPC_LCD->POL &= ~(0x3FF <<16);
LPC_LCD->POL |= (C_GLCD_H_SIZE-1)<<16;
// init Horizontal Timing
LPC_LCD->TIMH = 0; //reset TIMH before set value
LPC_LCD->TIMH |= (C_GLCD_H_BACK_PORCH - 1)<<24;
LPC_LCD->TIMH |= (C_GLCD_H_FRONT_PORCH - 1)<<16;
LPC_LCD->TIMH |= (C_GLCD_H_PULSE - 1)<<8;
LPC_LCD->TIMH |= ((C_GLCD_H_SIZE/16) - 1)<<2;
// init Vertical Timing
LPC_LCD->TIMV = 0; //reset TIMV value before setting
LPC_LCD->TIMV |= (C_GLCD_V_BACK_PORCH)<<24;
LPC_LCD->TIMV |= (C_GLCD_V_FRONT_PORCH)<<16;
LPC_LCD->TIMV |= (C_GLCD_V_PULSE - 1)<<10;
LPC_LCD->TIMV |= C_GLCD_V_SIZE - 1;
// Frame Base Address doubleword aligned
LPC_LCD->UPBASE = LCD_VRAM_BASE_ADDR & ~7UL ;
LPC_LCD->LPBASE = LCD_VRAM_BASE_ADDR & ~7UL ;
}
/*************************************************************************
*功能:LCD显示使能
*参数:bEna = FALSE LCD不显示
* TRUE LCD显示
*************************************************************************/
void GLCD_Ctrl (Bool bEna)
{
volatile uint32_t i;
if (bEna)
{
// LCD_CTRL_bit.LcdEn = 1;
LPC_LCD->CTRL |= (1<<0);
for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
// LCD_CTRL_bit.LcdPwr= 1; // enable power
LPC_LCD->CTRL |= (1<<11);
}
else
{
// LCD_CTRL_bit.LcdPwr= 0; // disable power
LPC_LCD->CTRL &= ~(1<<11);
for(i = C_GLCD_PWR_ENA_DIS_DLY; i; i--);
// LCD_CTRL_bit.LcdEn = 0;
LPC_LCD->CTRL &= ~(1<<0);
}
}
/*************************************************************************
* Function Name: GLCD_SET_Pixel_16bpp
* Parameters: const uint32_t x, const uint32_t y ,const uint16_t colour
*
* Return: none
*
* Description: 填充LCD像素顔色
*
*************************************************************************/
void GLCD_SET_Pixel_16bpp (const uint32_t x, const uint32_t y ,const uint16_t colour){
uint16_t *pDst = (uint16_t *)LCD_VRAM_BASE_ADDR;
*(pDst+x+C_GLCD_H_SIZE*y)= colour;
}
/*************************************************************************
* Function Name: GLCD_Line_16bpp
* Parameters: uint32_t x1, uint32_t y1 起始坐标
uint32_t x2, uint32_t y2 结束坐标
uint32_t color
*
* Return: none
*
* Description: 填充LCD画线
*
*************************************************************************/
void GLCD_Line_16bpp(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint16_t color){
int dx, dy, e;
dx = x2 - x1;
dy = y2 - y1;
if(dx >= 0)
{
if(dy >= 0) // dy>=0
{
if(dx >= dy) // 1/8 octant
{
e = dy-dx/2;
while(x1 <= x2)
{
GLCD_SET_Pixel_16bpp(x1, y1, color);
if(e > 0) {y1+=1; e-=dx;}
x1 += 1;
e += dy;
}
}
else // 2/8 octant
{
e = dx-dy/2;
while(y1 <= y2)
{
GLCD_SET_Pixel_16bpp(x1, y1, color);
if(e > 0) {x1+=1; e-=dy;}
y1 += 1;
e += dx;
}
}
}
else // dy<0
{
dy = -dy; // dy=abs(dy)
if(dx >= dy) // 8/8 octant
{
e = dy-dx/2;
while(x1 <= x2)
{
GLCD_SET_Pixel_16bpp(x1, y1, color);
if(e > 0) {y1-=1; e-=dx;}
x1 += 1;
e += dy;
}
}
else // 7/8 octant
{
e = dx-dy/2;
while(y1 >= y2)
{
GLCD_SET_Pixel_16bpp(x1, y1, color);
if(e > 0) {x1+=1; e-=dy;}
y1 -= 1;
e += dx;
}
}
}
}
else //dx<0
{
dx=-dx; //dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
GLCD_SET_Pixel_16bpp(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
GLCD_SET_Pixel_16bpp(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else // dy<0
{
dy=-dy; // dy=abs(dy)
if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
GLCD_SET_Pixel_16bpp(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else // 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
GLCD_SET_Pixel_16bpp(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}
/*-----------------------------------------------------------------------------
* LCD 清屏操作
------------------------------------------------------------------------------*/
void GLCD_Dis_clr (void){
uint16_t *pdata = (uint16_t *)LCD_VRAM_BASE_ADDR;
uint32_t i;
#if (C_GLCD_BitsPP == 32)
for( i = 0; (C_GLCD_H_SIZE * C_GLCD_V_SIZE*4) > i; i++)
#else // C_GLCD_BitsPP = 16
for( i = 0; (C_GLCD_H_SIZE * C_GLCD_V_SIZE*2) > i; i++)
#endif
{
*pdata++ = 0x0;
}
}
/*-----------------------------------------------------------------------------
* 在LCD屏幕上指定坐标点画一个指定大小的图片
------------------------------------------------------------------------------*/
void Paint_Bmp_16bpp(uint32_t x0, uint32_t y0, uint32_t l, uint32_t h, uint8_t bmp[])
{
uint32_t x, y;
uint16_t c;
uint32_t p = 0;
uint16_t *pdata = (uint16_t *)LCD_VRAM_BASE_ADDR;
for( y = 0 ; y < h ; y++ )
{
for( x = 0 ; x < l ; x++ )
{
c = bmp[p] | (bmp[p+1]<<8) ;
if ( ( (x0+x) < C_GLCD_H_SIZE) && ( (y0+y) < C_GLCD_V_SIZE) )
*(pdata+(x0+x)+(y+y0)*C_GLCD_H_SIZE) = c ;
else break;
p = p + 2 ;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -