You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

952 lines
26 KiB

/**
******************************************************************************
* 文件名程: bsp_lcd.c
* 作 者: 硬石嵌入式开发团队
* 版 本: V1.0
* 编写日期: 2015-10-04
* 功 能: 液晶底层驱动函数实现
******************************************************************************
* 说明:
* 本例程配套硬石stm32开发板YS-F1Pro使用。
*
* 淘宝:
* 论坛:http://www.ing10bbs.com
* 版权归硬石嵌入式开发团队所有,请勿商用。
******************************************************************************
*/
/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp_lcd.h"
#include "ascii.h"
#include "bsp_touch.h"
/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
// 保存当前检查到的液晶模块ID
volatile u32 lcd_id=0;
u16 TextColor=BLACK,BackColor=BACKGROUND;
/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/
/* 函数体 --------------------------------------------------------------------*/
/**
* 函数功能: 用于 LCD 简单延时函数
* 输入参数: nCount :延时计数值
* 返 回 值: 无
* 说 明:无
*/
static void LCD_DELAY( volatile u32 nCount )
{
for ( ; nCount != 0; nCount -- );
}
/**
* 函数功能: 初始化LCD的IO引脚
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
static void LCD_GPIO_Config ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能复用IO时钟:复用为fsmc功能 */
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_AFIO, ENABLE );
/* 使能FSMC对应相应管脚时钟 */
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE );
FSMC_LCD_CS_APBxClock_FUN ( FSMC_LCD_CS_CLK, ENABLE );
FSMC_LCD_DC_APBxClock_FUN ( FSMC_LCD_DC_CLK, ENABLE );
FSMC_LCD_BK_APBxClock_FUN ( FSMC_LCD_BK_CLK, ENABLE );
/* 配置FSMC相对应的数据线,FSMC-D0~D15: PD 14 15 0 1,PE 7 8 9 10 11 12 13 14 15,PD 8 9 10 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init ( GPIOD, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_Init ( GPIOE, & GPIO_InitStructure );
/* 配置FSMC相对应的控制线
* PD4-FSMC_NOE :LCD-RD
* PD5-FSMC_NWE :LCD-WR
* PG12-FSMC_NE4 :LCD-CS
* PF0-FSMC_A0 :LCD-DC
*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init (GPIOD, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init (GPIOD, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = FSMC_LCD_CS_PIN;
GPIO_Init ( FSMC_LCD_CS_PORT, & GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = FSMC_LCD_DC_PIN;
GPIO_Init ( FSMC_LCD_DC_PORT, & GPIO_InitStructure );
/* 配置LCD背光控制管脚BK*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Pin = FSMC_LCD_BK_PIN;
GPIO_Init ( FSMC_LCD_BK_PORT, & GPIO_InitStructure );
/* 初始化时先不开背光 */
GPIO_ResetBits(FSMC_LCD_BK_PORT,FSMC_LCD_BK_PIN);
}
/**
* 函数功能: LCD FSMC 模式配置
* 输入参数: 无
* 返 回 值: 无
* 说 明:读写使用相同时间配置
*/
static void LCD_FSMC_Config ( void )
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef fsmc_lcd;
/* 使能FSMC时钟*/
RCC_AHBPeriphClockCmd ( RCC_AHBPeriph_FSMC, ENABLE );
fsmc_lcd.FSMC_AddressSetupTime = 0x02; //地址建立时间
fsmc_lcd.FSMC_AddressHoldTime = 0x00; //地址保持时间
fsmc_lcd.FSMC_DataSetupTime = 0x05; //数据建立时间
fsmc_lcd.FSMC_BusTurnAroundDuration = 0x00;
fsmc_lcd.FSMC_CLKDivision = 0x00;
fsmc_lcd.FSMC_DataLatency = 0x00;
fsmc_lcd.FSMC_AccessMode = FSMC_AccessMode_B; //模式B比较适用于LCD
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_LCD_BACKx;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = & fsmc_lcd;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = & fsmc_lcd;
FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
/* 使能 FSMC_Bank1_NORSRAM4 */
FSMC_NORSRAMCmd ( FSMC_LCD_BACKx, ENABLE );
}
/**
* 函数功能: 初始化LCD寄存器
* 输入参数: 无
* 返 回 值: 无
* 说 明:需要配置哪些寄存器,需要设置什么值与液晶厂家生产环境密切相关,
* 所以这些参数由厂家提供,不同厂家可能不同。也可以根据ILI9488芯片
* 手册内容参考修改。
*/
static void ILI9488_REG_Config ( void )
{
//************* Start Initial Sequence **********//
/* PGAMCTRL (Positive Gamma Control) (E0h) */
LCD_WRITE_CMD(0xE0);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x07);
LCD_WRITE_DATA(0x10);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x17);
LCD_WRITE_DATA(0x0B);
LCD_WRITE_DATA(0x41);
LCD_WRITE_DATA(0x89);
LCD_WRITE_DATA(0x4B);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x0C);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x18);
LCD_WRITE_DATA(0x1B);
LCD_WRITE_DATA(0x0F);
/* NGAMCTRL (Negative Gamma Control) (E1h) */
LCD_WRITE_CMD(0XE1);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x17);
LCD_WRITE_DATA(0x1A);
LCD_WRITE_DATA(0x04);
LCD_WRITE_DATA(0x0E);
LCD_WRITE_DATA(0x06);
LCD_WRITE_DATA(0x2F);
LCD_WRITE_DATA(0x45);
LCD_WRITE_DATA(0x43);
LCD_WRITE_DATA(0x02);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x09);
LCD_WRITE_DATA(0x32);
LCD_WRITE_DATA(0x36);
LCD_WRITE_DATA(0x0F);
/* Adjust Control 3 (F7h) */
LCD_WRITE_CMD(0XF7);
LCD_WRITE_DATA(0xA9);
LCD_WRITE_DATA(0x51);
LCD_WRITE_DATA(0x2C);
LCD_WRITE_DATA(0x82);/* DSI write DCS command, use loose packet RGB 666 */
/* Power Control 1 (C0h) */
LCD_WRITE_CMD(0xC0);
LCD_WRITE_DATA(0x11);
LCD_WRITE_DATA(0x09);
/* Power Control 2 (C1h) */
LCD_WRITE_CMD(0xC1);
LCD_WRITE_DATA(0x41);
/* VCOM Control (C5h) */
LCD_WRITE_CMD(0XC5);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x0A);
LCD_WRITE_DATA(0x80);
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
LCD_WRITE_CMD(0xB1);
LCD_WRITE_DATA(0xB0);
LCD_WRITE_DATA(0x11);
/* Display Inversion Control (B4h) */
LCD_WRITE_CMD(0xB4);
LCD_WRITE_DATA(0x02);
/* Display Function Control (B6h) */
LCD_WRITE_CMD(0xB6);
LCD_WRITE_DATA(0x02);
LCD_WRITE_DATA(0x22);
/* Entry Mode Set (B7h) */
LCD_WRITE_CMD(0xB7);
LCD_WRITE_DATA(0xc6);
/* HS Lanes Control (BEh) */
LCD_WRITE_CMD(0xBE);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x04);
/* Set Image Function (E9h) */
LCD_WRITE_CMD(0xE9);
LCD_WRITE_DATA(0x00);
/* 设置屏幕方向和尺寸 */
LCD_SetDirection(LCD_DIRECTION);
/* Interface Pixel Format (3Ah) */
LCD_WRITE_CMD(0x3A);
LCD_WRITE_DATA(0x55);/* 0x55 : 16 bits/pixel */
/* Sleep Out (11h) */
LCD_WRITE_CMD(0x11);
LCD_DELAY(120*2000);
/* Display On */
LCD_WRITE_CMD(0x29);
}
/**
* 函数功能: 读取液晶模组ID
* 输入参数: 无
* 返 回 值: 液晶模组的ID
* 说 明:这是通过读取04H寄存器获取得到液晶模组ID,该ID值有液晶厂家编程,不同液晶
* 厂家的液晶模组得到的ID值可能不同。这也可以分辨不同型号的液晶模组。
*/
static u32 LCD_ReadID(void)
{
u16 buf[4];
LCD_WRITE_CMD(0x04);
buf[0] = LCD_READ_DATA(); // 第一个读取数据无效
buf[1] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效
buf[2] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效
buf[3] = LCD_READ_DATA()&0x00ff; // 只有低8位数据有效
return (buf[1] << 16) + (buf[2] << 8) + buf[3];
}
/**
* 函数功能: 画板初始化,用于取色用
* 输入参数: 无
* 返 回 值: 无
* 说 明: 无
*/
void Palette_Init(void)
{
/* 整屏清为白色 */
LCD_Clear( 0, 0,480, 320,BACKGROUND);
LCD_Clear( 0,280, 68, 40, LIGHTBLUE);
LCD_DispString_EN(16,285,"SEL",LIGHTBLUE,BLACK,FONT_24);
LCD_Clear( 68,280, 68, 40, RED );
LCD_DispString_EN(93,285,"UP",RED,BLACK,FONT_24);
LCD_Clear(136,280, 68, 40, GREEN );
LCD_DispString_EN(145,285,"DOWN",GREEN,BLACK,FONT_24);
LCD_Clear(204,280, 68, 40, ORANGE);
LCD_DispString_EN(214,285,"LEFT",ORANGE,BLACK,FONT_24);
LCD_Clear(272,280, 68, 40, CYAN);
LCD_DispString_EN(275,285,"RIGHT",CYAN,BLACK,FONT_24);
LCD_Clear(340,280, 68, 40, YELLOW);
LCD_DispString_EN(356,285,"KEY1",YELLOW,BLACK,FONT_24);
LCD_Clear(408,280, 72, 40, MAGENTA);
LCD_DispString_EN(424,285,"KEY2",MAGENTA,BLACK,FONT_24);
}
/**
* 函数功能: 液晶模组初始化
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
u32 BSP_LCD_Init(void)
{
LCD_GPIO_Config();
LCD_FSMC_Config();
lcd_id=LCD_ReadID();
if(lcd_id==0x548066 || lcd_id==0x8066)
{
ILI9488_REG_Config();
}
/* 触摸屏IO初始化 */
Touch_Init_GPIO();
Palette_Init();
/* 开背光 */
LCD_BK_ON();
return lcd_id;
}
/**
* 函数功能: 设置LCD的GRAM的扫描方向
* 输入参数: ucOption :选择GRAM的扫描方向
* 可选值:1 :原点在屏幕左上角 X*Y=320*480
* 2 :原点在屏幕右上角 X*Y=480*320
* 3 :原点在屏幕右下角 X*Y=320*480
* 4 :原点在屏幕左下角 X*Y=480*320
* 返 回 值: 无
* 说 明:无
*/
void LCD_SetDirection( u8 ucOption )
{
/**
* Memory Access Control (36h)
* This command defines read/write scanning direction of the frame memory.
*
* These 3 bits control the direction from the MPU to memory write/read.
*
* Bit Symbol Name Description
* D7 MY Row Address Order -- 以X轴镜像
* D6 MX Column Address Order -- 以Y轴镜像
* D5 MV Row/Column Exchange -- X轴与Y轴交换
* D4 ML Vertical Refresh Order LCD vertical refresh direction control.
*
* D3 BGR RGB-BGR Order Color selector switch control
* (0 = RGB color filter panel, 1 = BGR color filter panel )
* D2 MH Horizontal Refresh ORDER LCD horizontal refreshing direction control.
* D1 X Reserved Reserved
* D0 X Reserved Reserved
*/
switch ( ucOption )
{
case 1:
// 左上角->右下角
// (0,0) ___ x(320)
// |
// |
// | y(480)
LCD_WRITE_CMD(0x36);
LCD_WRITE_DATA(0x08);
LCD_WRITE_CMD(0x2A);
LCD_WRITE_DATA(0x00); /* x start */
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01); /* x end */
LCD_WRITE_DATA(0x3F);
LCD_WRITE_CMD(0x2B);
LCD_WRITE_DATA(0x00); /* y start */
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01); /* y end */
LCD_WRITE_DATA(0xDF);
break;
case 2:
// 右上角-> 左下角
// y(320)___ (0,0)
// |
// |
// |x(480)
LCD_WRITE_CMD(0x36);
LCD_WRITE_DATA(0x68);
LCD_WRITE_CMD(0x2A);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0xDF);
LCD_WRITE_CMD(0x2B);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0x3F);
break;
case 3:
// 右下角->左上角
// |y(480)
// |
// x(320) ___|(0,0)
LCD_WRITE_CMD(0x36);
LCD_WRITE_DATA(0xC8);
LCD_WRITE_CMD(0x2A);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0x3F);
LCD_WRITE_CMD(0x2B);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0x3F);
break;
case 4:
// 左下角->右上角
// |x(480)
// |
// |___ y(320)
LCD_WRITE_CMD(0x36);
LCD_WRITE_DATA(0xA8);
LCD_WRITE_CMD(0x2A);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0xDF);
LCD_WRITE_CMD(0x2B);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x00);
LCD_WRITE_DATA(0x01);
LCD_WRITE_DATA(0x3F);
break;
}
/* 开始向GRAM写入数据 */
LCD_WRITE_CMD (0x2C);
}
/**
* 函数功能: 在LCD显示器上开辟一个窗口
* 输入参数: usX :在特定扫描方向下窗口的起点X坐标
* usY :在特定扫描方向下窗口的起点Y坐标
* usWidth :窗口的宽度
* usHeight :窗口的高度
* 返 回 值: 无
* 说 明:无
*/
void LCD_OpenWindow(u16 usX, u16 usY, u16 usWidth, u16 usHeight)
{
LCD_WRITE_CMD(0x2A ); /* 设置X坐标 */
LCD_WRITE_DATA(usX>>8); /* 设置起始点:先高8位 */
LCD_WRITE_DATA(usX&0xff); /* 然后低8位 */
LCD_WRITE_DATA((usX+usWidth-1)>>8); /* 设置结束点:先高8位 */
LCD_WRITE_DATA((usX+usWidth-1)&0xff);/* 然后低8位 */
LCD_WRITE_CMD(0x2B); /* 设置Y坐标*/
LCD_WRITE_DATA(usY>>8); /* 设置起始点:先高8位 */
LCD_WRITE_DATA(usY&0xff); /* 然后低8位 */
LCD_WRITE_DATA((usY+usHeight-1)>>8); /* 设置结束点:先高8位 */
LCD_WRITE_DATA((usY+usHeight-1)&0xff);/* 然后低8位 */
}
/**
* 函数功能: 设定LCD的光标坐标
* 输入参数: usX :在特定扫描方向下窗口的起点X坐标
* usY :在特定扫描方向下窗口的起点Y坐标
* 返 回 值: 无
* 说 明:无
*/
static void LCD_SetCursor ( u16 usX, u16 usY )
{
LCD_OpenWindow ( usX, usY, 1, 1 );
}
/**
* 函数功能: 在LCD显示器上以某一颜色填充像素点
* 输入参数: ulAmout_Point :要填充颜色的像素点的总数目
* usColor :颜色
* 返 回 值: 无
* 说 明:无
*/
#if defined ( __CC_ARM ) // 使用Keil编译环境
static __inline void LCD_FillColor ( u32 ulAmout_Point, u16 usColor )
{
u32 i = 0;
/* 开始向GRAM写入数据 */
LCD_WRITE_CMD ( 0x2C );
for ( i = 0; i < ulAmout_Point; i ++ )
LCD_WRITE_DATA ( usColor );
}
#elif defined ( __ICCARM__ ) // 使用IAR编译环境
#pragma inline
static void LCD_FillColor ( u32 ulAmout_Point, u16 usColor )
{
u32 i = 0;
/* 开始向GRAM写入数据 */
LCD_WRITE_CMD ( 0x2C );
for ( i = 0; i < ulAmout_Point; i ++ )
LCD_WRITE_DATA ( usColor );
}
#endif
/**
* 函数功能: 对LCD显示器的某一窗口以某种颜色进行清屏
* 输入参数: usX :在特定扫描方向下窗口的起点X坐标
* usY :在特定扫描方向下窗口的起点Y坐标
* usWidth :窗口的宽度
* usHeight :窗口的高度
* usColor :颜色
* 返 回 值: 无
* 说 明:无
*/
void LCD_Clear(u16 usX,u16 usY,u16 usWidth,u16 usHeight,u16 usColor)
{
#if 0 /* 优化代码执行速度 */
u32 i;
u32 n,m;
/* 在LCD显示器上开辟一个窗口 */
LCD_OpenWindow(usX,usY,usWidth,usHeight);
/* 开始向GRAM写入数据 */
LCD_WRITE_CMD(0x2C);
m=usWidth * usHeight;
n=m/8;
m=m-8*n;
for(i=0;i<n;i++)
{
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
LCD_WRITE_DATA(usColor);
}
for(i=0;i<m;i++)
{
LCD_WRITE_DATA(usColor);
}
#else
/* 在LCD显示器上开辟一个窗口 */
LCD_OpenWindow(usX,usY,usWidth,usHeight);
/* 在LCD显示器上以某一颜色填充像素点 */
LCD_FillColor(usWidth*usHeight,usColor);
#endif
}
/**
* 函数功能: 对LCD显示器的某一点以某种颜色进行填充
* 输入参数: usX :在特定扫描方向下窗口的起点X坐标
* usY :在特定扫描方向下窗口的起点Y坐标
* usColor :颜色
* 返 回 值: 无
* 说 明:无
*/
void LCD_SetPointPixel(u16 usX,u16 usY,u16 usColor)
{
if((usX<LCD_DEFAULT_WIDTH)&&(usY<LCD_DEFAULT_HEIGTH))
{
LCD_OpenWindow(usX,usY,1,1);
LCD_FillColor(1,usColor);
}
}
/**
* 函数功能: 对LCD显示器的某一点以某种颜色进行填充
* 输入参数: 无
* 返 回 值: u16:像素数据RGB565
* 说 明:无
*/
static u16 LCD_Read_PixelData ( void )
{
u16 usR=0, usG=0, usB=0 ;
LCD_WRITE_CMD ( 0x2E ); /* 读数据 */
usR = LCD_READ_DATA (); /*FIRST READ OUT DUMMY DATA*/
usR = LCD_READ_DATA (); /*READ OUT RED DATA */
usB = LCD_READ_DATA (); /*READ OUT BLUE DATA*/
usG = LCD_READ_DATA (); /*READ OUT GREEN DATA*/
return (((usR>>11)<<11) | ((usG>>10)<<5) | (usB>>11));
}
/**
* 函数功能: 获取 LCD 显示器上某一个坐标点的像素数据
* 输入参数: usX :在特定扫描方向下窗口的起点X坐标
* usY :在特定扫描方向下窗口的起点Y坐标
* 返 回 值: u16:像素数据RGB565
* 说 明:无
*/
u16 LCD_GetPointPixel ( u16 usX, u16 usY )
{
u16 usPixelData;
LCD_SetCursor ( usX, usY );
usPixelData = LCD_Read_PixelData ();
return usPixelData;
}
/**
* 函数功能: 在 LCD 显示器上使用 Bresenham 算法画线段
* 输入参数: usX1 :在特定扫描方向下窗口的起点X坐标
* usY1 :在特定扫描方向下窗口的起点Y坐标
* usX2 :在特定扫描方向下线段的另一个端点X坐标
* usY2 :在特定扫描方向下线段的另一个端点Y坐标
* usColor :线段的颜色
* 返 回 值: 无
* 说 明:无
*/
void LCD_DrawLine(u16 usX1,u16 usY1,u16 usX2,u16 usY2,u16 usColor)
{
u16 us;
u16 usX_Current, usY_Current;
s32 lError_X=0,lError_Y=0,lDelta_X,lDelta_Y,lDistance;
s32 lIncrease_X, lIncrease_Y;
lDelta_X=usX2-usX1; //计算坐标增量
lDelta_Y=usY2-usY1;
usX_Current = usX1;
usY_Current = usY1;
if(lDelta_X>0)
{
lIncrease_X=1; //设置单步方向
}
else if(lDelta_X==0)
{
lIncrease_X=0;//垂直线
}
else
{
lIncrease_X=-1;
lDelta_X=-lDelta_X;
}
if(lDelta_Y>0)
{
lIncrease_Y=1;
}
else if(lDelta_Y==0)
{
lIncrease_Y=0;//水平线
}
else
{
lIncrease_Y=-1;
lDelta_Y=-lDelta_Y;
}
if(lDelta_X>lDelta_Y)
{
lDistance=lDelta_X; //选取基本增量坐标轴
}
else
{
lDistance=lDelta_Y;
}
for(us=0;us<=lDistance+1;us++)//画线输出
{
LCD_SetPointPixel(usX_Current,usY_Current,usColor);//画点
lError_X+=lDelta_X;
lError_Y+=lDelta_Y;
if(lError_X>lDistance)
{
lError_X-=lDistance;
usX_Current+=lIncrease_X;
}
if(lError_Y>lDistance)
{
lError_Y-=lDistance;
usY_Current+=lIncrease_Y;
}
}
}
/**
* 函数功能: 在LCD显示器上画一个矩形
* 输入参数: usX_Start :在特定扫描方向下窗口的起点X坐标
* usY_Start :在特定扫描方向下窗口的起点Y坐标
* usWidth:矩形的宽度(单位:像素)
* usHeight:矩形的高度(单位:像素)
* usColor :矩形的颜色
* ucFilled :选择是否填充该矩形
* 可选值:0:空心矩形
* 1:实心矩形
* 返 回 值: 无
* 说 明:无
*/
void LCD_DrawRectangle ( u16 usX_Start, u16 usY_Start, u16 usWidth, u16 usHeight, u16 usColor, u8 ucFilled )
{
if(ucFilled)
{
LCD_Clear ( usX_Start, usY_Start, usWidth, usHeight, usColor);
}
else
{
LCD_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start, usColor );
LCD_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1, usColor );
LCD_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1, usColor );
LCD_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1, usColor );
}
}
/**
* 函数功能: 在 LCD 显示器上使用 Bresenham 算法画圆
* 输入参数: usX_Center :在特定扫描方向下圆心的X坐标
* usY_Center :在特定扫描方向下圆心的Y坐标
* usRadius:圆的半径(单位:像素)
* usColor :圆的颜色
* ucFilled :选择是否填充该圆
* 可选值:0:空心圆
* 1:实心圆
* 返 回 值: 无
* 说 明:无
*/
void LCD_DrawCircle(u16 usX_Center,u16 usY_Center,u16 usRadius,u16 usColor,u8 ucFilled)
{
s16 sCurrentX, sCurrentY;
s16 sError;
sCurrentX=0;
sCurrentY=usRadius;
sError=3-(usRadius<<1); //判断下个点位置的标志
while(sCurrentX<=sCurrentY)
{
s16 sCountY;
if(ucFilled)
{
for(sCountY=sCurrentX;sCountY<=sCurrentY;sCountY++)
{
LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center+sCountY,usColor); //1,研究对象
LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center+sCountY,usColor); //2
LCD_SetPointPixel(usX_Center-sCountY, usY_Center+sCurrentX,usColor); //3
LCD_SetPointPixel(usX_Center-sCountY, usY_Center-sCurrentX,usColor); //4
LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center-sCountY,usColor); //5
LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center-sCountY,usColor); //6
LCD_SetPointPixel(usX_Center+sCountY, usY_Center-sCurrentX,usColor); //7
LCD_SetPointPixel(usX_Center+sCountY, usY_Center+sCurrentX,usColor); //0
}
}
else
{
LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center+sCurrentY,usColor); //1,研究对象
LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center+sCurrentY,usColor); //2
LCD_SetPointPixel(usX_Center-sCurrentY,usY_Center+sCurrentX,usColor); //3
LCD_SetPointPixel(usX_Center-sCurrentY,usY_Center-sCurrentX,usColor); //4
LCD_SetPointPixel(usX_Center-sCurrentX,usY_Center-sCurrentY,usColor); //5
LCD_SetPointPixel(usX_Center+sCurrentX,usY_Center-sCurrentY,usColor); //6
LCD_SetPointPixel(usX_Center+sCurrentY,usY_Center-sCurrentX,usColor); //7
LCD_SetPointPixel(usX_Center+sCurrentY,usY_Center+sCurrentX,usColor); //0
}
sCurrentX ++;
if(sError<0)
{
sError+=(4*sCurrentX+6);
}
else
{
sError +=(10+4*(sCurrentX-sCurrentY));
sCurrentY--;
}
}
}
/**
* 函数功能: 在 LCD 显示器上显示一个英文字符
* 输入参数: usX:在特定扫描方向下字符的起始X坐标
* usY :在特定扫描方向下该点的起始Y坐标
* cChar :要显示的英文字符
* usColor_Background :选择英文字符的背景色
* usColor_Foreground :选择英文字符的前景色
* font:字体选择
* 可选值:FONT_16 :16号字体
* FONT_24 :24号字体
* 返 回 值: 无
* 说 明:该函数必须与ascii.h内容对应使用
*/
void LCD_DispChar_EN( u16 usX, u16 usY, const char cChar, u16 usColor_Background, u16 usColor_Foreground,FONT_Typdef font)
{
u8 ucTemp, ucRelativePositon, ucPage, ucColumn;
/* 检查输入参数是否合法 */
assert_param(IS_FONT(font));
ucRelativePositon = cChar - ' ';
if(font==FONT_16)
{
LCD_OpenWindow(usX,usY,8,16);
LCD_WRITE_CMD(0x2C);
for(ucPage=0;ucPage<16;ucPage++)
{
ucTemp=ucAscii_1608[ucRelativePositon][ucPage];
for(ucColumn=0;ucColumn<8;ucColumn++)
{
if(ucTemp&0x01)
LCD_WRITE_DATA(usColor_Foreground);
else
LCD_WRITE_DATA(usColor_Background);
ucTemp >>= 1;
}
}
}
else
{
LCD_OpenWindow(usX,usY,12,24);
LCD_WRITE_CMD(0x2C);
for(ucPage=0;ucPage<48;ucPage++)
{
ucTemp=ucAscii_2412[ucRelativePositon][ucPage];
for(ucColumn=0;ucColumn<8;ucColumn++)
{
if(ucTemp&0x01)
LCD_WRITE_DATA(usColor_Foreground);
else
LCD_WRITE_DATA(usColor_Background);
ucTemp >>= 1;
}
ucPage++;
ucTemp=ucAscii_2412[ucRelativePositon][ucPage];
/* 只显示前面4个位,与什么8位总共12位 */
for(ucColumn=0;ucColumn<4;ucColumn++)
{
if(ucTemp&0x01)
LCD_WRITE_DATA(usColor_Foreground);
else
LCD_WRITE_DATA(usColor_Background);
ucTemp >>= 1;
}
}
}
}
/**
* 函数功能: 在 LCD 显示器上显示英文字符串
* 输入参数: usX:在特定扫描方向下字符的起始X坐标
* usY :在特定扫描方向下该点的起始Y坐标
* pStr :要显示的英文字符串的首地址
* usColor_Background :选择英文字符的背景色
* usColor_Foreground :选择英文字符的前景色
* font:字体选择
* 可选值:FONT_16 :16号字体
* FONT_24 :24号字体
* 返 回 值: 无
* 说 明:该函数必须与ascii.h内容对应使用
*/
void LCD_DispString_EN ( u16 usX, u16 usY, const char * pstr, u16 usColor_Background, u16 usColor_Foreground,FONT_Typdef font)
{
/* 检查输入参数是否合法 */
assert_param(IS_FONT(font));
while(*pstr != '\0')
{
if(font==FONT_16)
{
if((usX+8)>LCD_DEFAULT_WIDTH)
{
usX = 0;
usY += 16;
}
if((usY+16)>LCD_DEFAULT_HEIGTH)
{
usX=0;
usY=0;
}
LCD_DispChar_EN(usX,usY,*pstr,usColor_Background,usColor_Foreground,FONT_16);
pstr++;
usX+=8;
}
else
{
if((usX+12)>LCD_DEFAULT_WIDTH)
{
usX=0;
usY+=24;
}
if((usY+24)>LCD_DEFAULT_HEIGTH)
{
usX=0;
usY=0;
}
LCD_DispChar_EN(usX,usY,*pstr,usColor_Background,usColor_Foreground,FONT_24);
pstr++;
usX+=12;
}
}
}
void LCD_SetTextColor(volatile u16 Color)
{
TextColor = Color;
}
void LCD_SetBackColor(volatile u16 Color)
{
BackColor = Color;
}
#define SCREEN_OFFSET 100
void LCD_DrawRect(u16 usX_Start,u16 usY_Start, u16 usWidth,u16 usHeight)
{
usX_Start +=SCREEN_OFFSET;
LCD_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start, TextColor );
LCD_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1, TextColor );
LCD_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1, TextColor );
LCD_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1, TextColor );
}
void LCD_ClearLine(volatile u8 Line)
{
LCD_Clear(SCREEN_OFFSET,Line, 480-SCREEN_OFFSET, 24, BackColor);
}
void LCD_DisplayChar(u8 Line, u16 Column, u8 Ascii)
{
LCD_DispChar_EN(Column+SCREEN_OFFSET,Line,Ascii,BackColor,TextColor,FONT_24);
}
void LCD_DisplayStringLine(volatile u16 Line, volatile u8 *pstr)
{
LCD_DispString_EN(SCREEN_OFFSET,Line,(const char *)pstr,BackColor,TextColor,FONT_24);
}
/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/