65-DMA-LCM液晶屏接口测试,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64
65-DMA-LCM液晶屏接口测试,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64LCM_Test_6800_DMA_8bit_ST7920主程序main.C代码如下(汇编版本在附件中):
/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
/*************功能说明 **************
本例程基于STC32G为主控芯片的实验箱9.6进行编写测试。
9.6之前实验箱版本,12864模块接口,P4.2与P4.4接口需要进行调换才能使用硬件LCM接口通信.
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
LCM接口驱动液晶屏程序
8bit M6800模式, P6口接D0~D7
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_RW = P4^2; //读写控制
sbit LCD_E = P4^4; //使能
sbit LCD_RESET = P3^4; //复位
LCM指令通过中断方式等待发送完成
DMA设置长度16字节,通过中断方式判断传输完成
设置时钟 1.2MHz (128*64屏, ST7920驱动, 速度太快显示会不正常).
(通过USB下载不能自定义时钟,需要使用串口方式下载)
******************************************/
#include "..\..\comm\STC32G.h"
#include "stdio.h"
#include "intrins.h"
#include "LCD_IMG.h"
#define MAIN_Fosc 1200000L //定义计算时钟参数
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_RW = P4^2; //读写控制
sbit LCD_E = P4^4; //使能
//sbit LCD_PSB = P3^5; //PSB脚为12864的串、并通讯功能切换,我们使用8位并行接口,PSB=1
sbit LCD_RESET = P3^4; //复位
//IO连接
#defineLCD_DataPort P6 //8位数据口
#defineUSR_LCM_IF 1 //1: use LCM Interface
u16 index;
bit DmaFlag=0;
bit LcmFlag=0;
u8code uctech[] = {"南通国芯微电子"};
u8code net[] = {" www.stcmcu.com "};
u8code mcu[] = {"专业制造51单片机"};
u8code qq[] = {" QQ: 800003751"};
void delay_ms(u16 ms);
void GPIO_Init(void);
void LCM_Config(void);
void DMA_Config(void);
void LCD_Init(void);
void DisplayImage (u8 *DData);
void DisplayListChar(u8 X, u8 Y, u8 code *DData);
void Write_Cmd(unsigned char WCLCD,unsigned char BuysC);
void Write_Data(unsigned char WDLCD);
void LCDClear(void);
void main(void)
{
// WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快(本例程需要降低速度才能正常显示)
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 1; //避免 DMA 与 CPU 同时访问 xdata 时产生总线冲突
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
// GPIO_Init();
#if USR_LCM_IF == 1
LCM_Config();
DMA_Config();
EA = 1;
#endif
// delay_ms(100); //启动等待,等LCD进入工作状态
LCD_Init(); //LCM初始化
while(1)
{
LCDClear();
DisplayImage(gImage_gxw);
delay_ms(200);
LCDClear();
DisplayListChar(0,1,uctech); //显示字库中的中文数字
DisplayListChar(0,2,net); //显示字库中的中文数字
DisplayListChar(0,3,mcu); //显示字库中的中文
DisplayListChar(0,4,qq); //显示字库中的中文数字
delay_ms(200);
}
}
//按指定位置显示一串字符
void DisplayListChar(u8 X, u8 Y, u8 code *DData)
{
u8 ListLength,X2;
ListLength = 0;
X2 = X;
if(Y < 1) Y=1;
if(Y > 4) Y=4;
X &= 0x0F; //限制X不能大于16,Y在1-4之内
switch(Y)
{
case 1: X2 |= 0X80; break;//根据行数来选择相应地址
case 2: X2 |= 0X90; break;
case 3: X2 |= 0X88; break;
case 4: X2 |= 0X98; break;
}
Write_Cmd(X2, 1); //发送地址码
while (DData >= 0x20) //若到达字串尾则退出
{
if (X <= 0x0F) //X坐标应小于0xF
{
Write_Data(DData); //
ListLength++;
X++;
}
}
}
//图形显示122*32
void DisplayImage (u8 *DData)
{
#if USR_LCM_IF == 0
u8 y;
#endif
u8 x,i;
unsigned int tmp=0;
for(i=0;i<9;) //分两屏,上半屏和下半屏,因为起始地址不同,需要分开
{
for(x=0;x<32;x++) //32行
{
Write_Cmd(0x34,1);
Write_Cmd((u8)(0x80+x),1); //列地址
Write_Cmd((u8)(0x80+i),1); //行地址,下半屏,即第三行地址0X88
Write_Cmd(0x30,1);
#if USR_LCM_IF == 1
DMA_LCM_TXAH = (u8)((u16)&DData >> 8);
DMA_LCM_TXAL = (u8)((u16)&DData);
while(DmaFlag);
DmaFlag = 1;
DMA_LCM_CR = 0xa0; //Write data
#else
for(y=0;y<16;y++)
Write_Data(DData);//读取数据写入LCD
#endif
tmp+=16;
}
i+=8;
}
Write_Cmd(0x36,1); //扩充功能设定
Write_Cmd(0x30,1);
}
//========================================================================
// 函数: void delay_ms(u16 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u16 ms)
{
u16 i;
do{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
#if USR_LCM_IF == 0
void LCD_delay(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
#endif
//读状态
void ReadStatusLCD(void)
{
#if USR_LCM_IF == 1
do{
LcmFlag = 1;
LCMIFCR = 0x86; //Enable interface, Read command
while(LcmFlag);
LCD_E = 0;
}while(LCMIFDATL & 0x80);
#else
LCD_RS = 0;
LCD_RW = 1;
LCD_delay();
LCD_E = 1;
LCD_delay();
while (LCD_DataPort & 0x80); //检测忙信号
LCD_E = 0;
#endif
}
void Write_Cmd(unsigned char WCLCD,unsigned char BuysC)
{
#if USR_LCM_IF == 1
if (BuysC) ReadStatusLCD(); //根据需要检测忙
LCMIFDATL = WCLCD;
LcmFlag = 1;
LCMIFCR = 0x84; //Enable interface, write command out
while(LcmFlag);
#else
if (BuysC) ReadStatusLCD(); //根据需要检测忙
LCD_RS = 0;
LCD_RW = 0;
LCD_DataPort = WCLCD;
LCD_delay();
LCD_E = 1;
LCD_delay();
LCD_E = 0;
#endif
}
void Write_Data(unsigned char WDLCD)
{
#if USR_LCM_IF == 1
LCMIFDATL = WDLCD;
LcmFlag = 1;
LCMIFCR = 0x85; //Enable interface, write data out
while(LcmFlag);
#else
ReadStatusLCD(); //检测忙
LCD_RS = 1;
LCD_RW = 0;
LCD_DataPort = WDLCD;
LCD_delay();
LCD_E = 1;
LCD_delay();
LCD_E = 0;
#endif
}
/*****************************************************************************
* @name :void GPIO_Init(void)
* @date :2018-11-13
* @function :Set the gpio to push-pull mode
* @parameters :None
* @retvalue :None
******************************************************************************/
//void GPIO_Init(void)
//{
// //P6口设置成推挽输出
// P6M0 |= 0xff;
// P6M1 &= 0x00;
// //P3.4口设置成推挽输出
// P3M0 |= 0x10;
// P3M1 &= ~0x10;
// //P4.2,P4.4,P4.5口设置成推挽输出
// P4M0 |= 0x34;
// P4M1 &= ~0x34;
//}
#if USR_LCM_IF == 1
/*****************************************************************************
* @name :void LCM_Config(void)
* @date :2018-11-13
* @function :Config LCM
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCM_Config(void)
{
LCMIFCFG = 0x85; //bit7 1:Enable Interrupt, bit1 0:8bit mode; bit0 0:8080,1:6800
LCMIFCFG2 = 0x1f;//RS:P45,RD:P44,WR:P42; Setup Time,HOLD Time
LCMIFSTA = 0x00;
}
/*****************************************************************************
* @name :void DMA_Config(void)
* @date :2020-12-09
* @function :Config DMA
* @parameters :None
* @retvalue :None
******************************************************************************/
void DMA_Config(void)
{
DMA_LCM_AMT = 0x0f; //设置传输总字节数(低8位):n+1
DMA_LCM_AMTH = 0x00; //设置传输总字节数(高8位):n+1
DMA_LCM_TXAH = (u8)((u16)&gImage_gxw >> 8);
DMA_LCM_TXAL = (u8)((u16)&gImage_gxw);
DMA_LCM_STA = 0x00;
DMA_LCM_CFG = 0x82;
DMA_LCM_CR = 0x80;
}
#endif
/*****************************************************************************
* @name :void LCDReset(void)
* @date :2018-08-09
* @function :Reset LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCDReset(void)
{
// LCD_PSB = 1; //并口
delay_ms(10);
LCD_RESET = 0;
delay_ms(10);
LCD_RESET = 1;
delay_ms(100);
}
/*****************************************************************************
* @name :void LCD_Init(void)
* @date :2018-08-09
* @function :Initialization LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCD_Init(void)
{
LCDReset(); //初始化之前复位
//*************LCD 初始化**********//
Write_Cmd(0x30,1); //显示模式设置,开始要求每次检测忙信号
Write_Cmd(0x01,1); //显示清屏
Write_Cmd(0x06,1); // 显示光标移动设置
Write_Cmd(0x0C,1); // 显示开及光标设置
}
void LCDClear(void) //清屏
{
Write_Cmd(0x01,1); //显示清屏
Write_Cmd(0x34,1); // 显示光标移动设置
Write_Cmd(0x30,1); // 显示开及光标设置
}
/*****************************************************************************
* @name :void LCM_Interrupt(void)
* @date :2018-11-13
* @function :None
* @parameters :None
* @retvalue :
******************************************************************************/
void LCMIF_DMA_Interrupt(void) interrupt 13
{
if(LCMIFSTA & 0x01)
{
LCMIFSTA = 0x00;
LcmFlag = 0;
}
if(DMA_LCM_STA & 0x01)
{
DmaFlag = 0;
DMA_LCM_CR = 0;
DMA_LCM_STA = 0;
}
}
65-DMA-LCM液晶屏接口测试,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64
LCM_Test_8080_DMA_8bit_ILI9341主程序main.C代码如下(汇编版本在附件中):
/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
/*************功能说明 **************
本例程基于STC32G为主控芯片的实验箱进行编写测试。
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
LCM接口+DMA驱动液晶屏程序
8bit I8080模式, P6口接D8~D15
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_WR = P4^2; //写控制
sbit LCD_RD = P4^4; //读控制
sbit LCD_CS = P3^4; //片选
sbit LCD_RESET = P4^3; //复位
LCM指令通过中断方式等待发送完成
DMA设置长度256字节,通过中断方式判断传输完成
下载时, 选择时钟 24MHz (用户可自行修改频率).
******************************************/
#include "..\..\comm\STC32G.h"
#include "stdio.h"
#include "intrins.h"
#include "font.h"
#define MAIN_Fosc 24000000L //定义主时钟
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_WR = P4^2; //写控制
sbit LCD_RD = P4^4; //读控制
sbit LCD_CS = P3^4; //片选
sbit LCD_RESET = P4^3; //复位
//IO连接
#defineLCD_DataPort P6 //8位数据口
//支持横竖屏快速定义切换
#define USE_HORIZONTAL 0 //定义液晶屏顺时针旋转方向 0-0度旋转,1-90度旋转,2-180度旋转,3-270度旋转
//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
//定义LCD的尺寸
#define LCD_W 240
#define LCD_H 320
#define DMA_AMT_LEN2047//n+1
u16 POINT_COLOR=0x0000; //画笔颜色
u16 index;
//u16 xdata Buffer={0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
u16 xdata Color;
bit DmaFlag;
bit LcmFlag;
typedef struct
{
u16 width; //LCD 宽度
u16 height; //LCD 高度
u16 id; //LCD ID
u8dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
u8 wramcmd; //开始写gram指令
u8 rramcmd; //开始读gram指令
u8 setxcmd; //设置x坐标指令
u8 setycmd; //设置y坐标指令
}_lcd_dev;
_lcd_dev lcddev;
void delay_ms(u16 ms);
void GPIO_Init(void);
void LCM_Config(void);
void DMA_Config(void);
void LCD_Init(void);
void Test_Color(void);
void LCD_WR_DATA_16Bit(u16 Data);
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd);
void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode);
void LCD_direction(u8 direction);
void main(void)
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 1; //避免 DMA 与 CPU 同时访问 xdata 时产生总线冲突
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
GPIO_Init();
LCM_Config();
DMA_Config();
EA = 1;
LCD_Init(); //LCM初始化
while(1)
{
Test_Color();
}
}
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{
u16 i,j;
u16 width=ex-sx+1; //得到填充的宽度
u16 height=ey-sy+1; //高度
LCD_SetWindows(sx,sy,ex,ey);//设置显示窗口
for(j=0,i=0;i<=DMA_AMT_LEN;i++)
{
Color = color;
}
index = 75; //(320 * 240 * 2) / 2048 = 75
LCD_CS=0;
DMA_LCM_CR = 0xa0; //Write dat
while(!LCD_CS);
}
void Test_Color(void)
{
u8 buf = {0};
LCD_Fill(0,0,lcddev.width,lcddev.height,WHITE);
Show_Str(20,30,BLUE,YELLOW,"LCM Test",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,RED);
Show_Str(20,30,BLUE,YELLOW,"RED ",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,GREEN);
Show_Str(20,30,BLUE,YELLOW,"GREEN ",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,BLUE);
Show_Str(20,30,RED,YELLOW,"BLUE ",16,1);delay_ms(800);
}
//========================================================================
// 函数: void delay_ms(u16 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u16 ms)
{
u16 i;
do{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
/*****************************************************************************
* @name :void LCD_WR_REG(u8 Reg)
* @date :2018-08-09
* @function :Write an 16-bit command to the LCD screen
* @parameters :data:Command value to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_REG(u8 Reg)
{
LCMIFDATL = Reg;
LCD_CS=0;
LCMIFCR = 0x84; //Enable interface, write command out
while(LcmFlag);
LCD_CS = 1 ;
}
/*****************************************************************************
* @name :void LCD_WR_DATA(u8 Data)
* @date :2018-08-09
* @function :Write an 16-bit data to the LCD screen
* @parameters :data:data value to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_DATA(u8 Data)
{
LCMIFDATL = Data;
LCD_CS=0;
LCMIFCR = 0x85; //Enable interface, write data out
while(LcmFlag);
LCD_CS = 1 ;
}
/*****************************************************************************
* @name :void LCD_WR_DATA_16Bit(u16 Data)
* @date :2018-08-09
* @function :Write an 16-bit command to the LCD screen
* @parameters :Data:Data to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_DATA_16Bit(u16 Data)
{
LCD_WR_DATA((u8)(Data>>8));
LCD_WR_DATA((u8)Data);
}
/*****************************************************************************
* @name :void LCD_WriteReg(u8 LCD_Reg, u8 LCD_RegValue)
* @date :2018-08-09
* @function :Write data into registers
* @parameters :LCD_Reg:Register address
LCD_RegValue:Data to be written
* @retvalue :None
******************************************************************************/
void LCD_WriteReg(u8 LCD_Reg, u8 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
/*****************************************************************************
* @name :void LCD_WriteRAM_Prepare(void)
* @date :2018-08-09
* @function :Write GRAM
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(lcddev.wramcmd);
}
/*****************************************************************************
* @name :void LCD_DrawPoint(u16 x,u16 y)
* @date :2018-08-09
* @function :Write a pixel data at a specified location
* @parameters :x:the x coordinate of the pixel
y:the y coordinate of the pixel
* @retvalue :None
******************************************************************************/
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetWindows(x,y,x,y);//设置光标位置
LCD_WR_DATA_16Bit(POINT_COLOR);
}
/*****************************************************************************
* @name :void GPIO_Init(void)
* @date :2018-11-13
* @function :Set the gpio to push-pull mode
* @parameters :None
* @retvalue :None
******************************************************************************/
void GPIO_Init(void)
{
//P6口设置成推挽输出
P6M0 |= 0xff;
P6M1 &= 0x00;
//P3.4口设置成推挽输出
P3M0 |= 0x10;
P3M1 &= ~0x10;
//P4.2,P4.3,P4.4,P4.5口设置成推挽输出
P4M0 |= 0x3c;
P4M1 &= ~0x3c;
}
/*****************************************************************************
* @name :void LCM_Config(void)
* @date :2018-11-13
* @function :Config LCM
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCM_Config(void)
{
LCMIFCFG = 0x84; //bit7 1:Enable Interrupt, bit1 0:8bit mode; bit0 0:8080,1:6800
LCMIFCFG2 = 0x09; //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
LCMIFSTA = 0x00;
}
/*****************************************************************************
* @name :void DMA_Config(void)
* @date :2020-12-09
* @function :Config DMA
* @parameters :None
* @retvalue :None
******************************************************************************/
void DMA_Config(void)
{
DMA_LCM_AMT = (u8)DMA_AMT_LEN; //设置传输总字节数(低8位):n+1
DMA_LCM_AMTH = (u8)(DMA_AMT_LEN>>8); //设置传输总字节数(高8位):n+1
DMA_LCM_TXAH = (u8)((u16)&Color >> 8);
DMA_LCM_TXAL = (u8)((u16)&Color);
// DMA_LCM_RXAH = (u8)((u16)&Buffer >> 8);
// DMA_LCM_RXAL = (u8)((u16)&Buffer);
DMA_LCM_STA = 0x00;
DMA_LCM_CFG = 0x82;
DMA_LCM_CR = 0x00;
}
/*****************************************************************************
* @name :void LCDReset(void)
* @date :2018-08-09
* @function :Reset LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCDReset(void)
{
LCD_CS=1;
delay_ms(50);
LCD_RESET=0;
delay_ms(150);
LCD_RESET=1;
delay_ms(50);
}
/*****************************************************************************
* @name :void LCD_Init(void)
* @date :2018-08-09
* @function :Initialization LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCD_Init(void)
{
LCDReset(); //初始化之前复位
// delay_ms(150); //根据不同晶振速度可以调整延时,保障稳定显示
//*************2.4inch ILI9341初始化**********//
LCD_WR_REG(0xCF);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xD9); //0xC1
LCD_WR_DATA(0X30);
LCD_WR_REG(0xED);
LCD_WR_DATA(0x64);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0X12);
LCD_WR_DATA(0X81);
LCD_WR_REG(0xE8);
LCD_WR_DATA(0x85);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x7A);
LCD_WR_REG(0xCB);
LCD_WR_DATA(0x39);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x34);
LCD_WR_DATA(0x02);
LCD_WR_REG(0xF7);
LCD_WR_DATA(0x20);
LCD_WR_REG(0xEA);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xC0); //Power control
LCD_WR_DATA(0x1B); //VRH
LCD_WR_REG(0xC1); //Power control
LCD_WR_DATA(0x12); //SAP;BT 0x01
LCD_WR_REG(0xC5); //VCM control
LCD_WR_DATA(0x08); //30
LCD_WR_DATA(0x26); //30
LCD_WR_REG(0xC7); //VCM control2
LCD_WR_DATA(0XB7);
LCD_WR_REG(0x36); // Memory Access Control
LCD_WR_DATA(0x08);
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x1A);
LCD_WR_REG(0xB6); // Display Function Control
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0xA2);
LCD_WR_REG(0xF2); // 3Gamma Function Disable
LCD_WR_DATA(0x00);
LCD_WR_REG(0x26); //Gamma curve selected
LCD_WR_DATA(0x01);
LCD_WR_REG(0xE0); //Set Gamma
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x1A);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x49);
LCD_WR_DATA(0X66);
LCD_WR_DATA(0x3B);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x11);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x04);
LCD_WR_REG(0XE1); //Set Gamma
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x02);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x36);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x4C);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x2F);
LCD_WR_DATA(0x05);
LCD_WR_REG(0x2B);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x3f);
LCD_WR_REG(0x2A);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xef);
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //display on
//设置LCD属性参数
LCD_direction(USE_HORIZONTAL);//设置LCD显示方向
}
/*****************************************************************************
* @name :void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
* @date :2018-08-09
* @function :Setting LCD display window
* @parameters :xStar:the bebinning x coordinate of the LCD display window
yStar:the bebinning y coordinate of the LCD display window
xEnd:the endning x coordinate of the LCD display window
yEnd:the endning y coordinate of the LCD display window
* @retvalue :None
******************************************************************************/
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA((u8)(xStar>>8));
LCD_WR_DATA((u8)(0x00FF&xStar));
LCD_WR_DATA((u8)(xEnd>>8));
LCD_WR_DATA((u8)(0x00FF&xEnd));
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA((u8)(yStar>>8));
LCD_WR_DATA((u8)(0x00FF&yStar));
LCD_WR_DATA((u8)(yEnd>>8));
LCD_WR_DATA((u8)(0x00FF&yEnd));
LCD_WriteRAM_Prepare(); //开始写入GRAM
}
/*****************************************************************************
* @name :void LCD_direction(u8 direction)
* @date :2018-08-09
* @function :Setting the display direction of LCD screen
* @parameters :direction:0-0 degree
1-90 degree
2-180 degree
3-270 degree
* @retvalue :None
******************************************************************************/
void LCD_direction(u8 direction)
{
lcddev.setxcmd=0x2A;
lcddev.setycmd=0x2B;
lcddev.wramcmd=0x2C;
lcddev.rramcmd=0x2E;
switch(direction){
case 0:
lcddev.width=LCD_W;
lcddev.height=LCD_H;
LCD_WriteReg(0x36,(1<<3));
break;
case 1:
lcddev.width=LCD_H;
lcddev.height=LCD_W;
LCD_WriteReg(0x36,(1<<3)|(1<<7)|(1<<5)|(1<<4));
break;
case 2:
lcddev.width=LCD_W;
lcddev.height=LCD_H;
LCD_WriteReg(0x36,(1<<3)|(1<<4)|(1<<6)|(1<<7));
break;
case 3:
lcddev.width=LCD_H;
lcddev.height=LCD_W;
LCD_WriteReg(0x36,(1<<3)|(1<<5)|(1<<6));
break;
default:break;
}
}
/*****************************************************************************
* @name :void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode)
* @date :2018-08-09
* @function :Display a single English character
* @parameters :x:the beginning x coordinate of the Character display position
y:the beginning y coordinate of the Character display position
fc:the color value of display character
bc:the background color of display character
num:the ascii code of display character(0~94)
size:the size of display character
mode:0-no overlying,1-overlying
* @retvalue :None
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode)
{
u8 temp;
u8 pos,t;
u16 colortemp=POINT_COLOR;
num=num-' ';//得到偏移后的值
LCD_SetWindows(x,y,x+size/2-1,y+size-1);//设置单个文字显示窗口
if(!mode) //非叠加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206;//调用1206字体
else temp=asc2_1608; //调用1608字体
for(t=0;t<size/2;t++)
{
if(temp&0x01)LCD_WR_DATA_16Bit(fc);
else LCD_WR_DATA_16Bit(bc);
temp>>=1;
}
}
}
else//叠加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206;//调用1206字体
else temp=asc2_1608; //调用1608字体
for(t=0;t<size/2;t++)
{
POINT_COLOR=fc;
if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//画一个点
temp>>=1;
}
}
}
POINT_COLOR=colortemp;
LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏
}
/*****************************************************************************
* @name :void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode)
* @date :2018-08-09
* @function :Display Chinese and English strings
* @parameters :x:the beginning x coordinate of the Chinese and English strings
y:the beginning y coordinate of the Chinese and English strings
fc:the color value of Chinese and English strings
bc:the background color of Chinese and English strings
str:the start address of the Chinese and English strings
size:the size of Chinese and English strings
mode:0-no overlying,1-overlying
* @retvalue :None
******************************************************************************/
void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode)
{
u16 x0=x;
u8 bHz=0; //字符或者中文
while(*str!=0)//数据未结束
{
if(!bHz)
{
if(x>(lcddev.width-size/2)||y>(lcddev.height-size))
return;
if(*str>0x80) bHz=1;//中文
else //字符
{
if(*str==0x0D)//换行符号
{
y+=size;
x=x0;
str++;
}
else
{
if(size>16)//字库中没有集成12X24 16X32的英文字体,用8X16代替
{
LCD_ShowChar(x,y,fc,bc,*str,16,mode);
x+=8; //字符,为全字的一半
}
else
{
LCD_ShowChar(x,y,fc,bc,*str,size,mode);
x+=size/2; //字符,为全字的一半
}
}
str++;
}
}
else//中文
{
// if(x>(lcddev.width-size)||y>(lcddev.height-size))
// return;
// bHz=0;//有汉字库
// if(size==32)
// GUI_DrawFont32(x,y,fc,bc,str,mode);
// else if(size==24)
// GUI_DrawFont24(x,y,fc,bc,str,mode);
// else
// GUI_DrawFont16(x,y,fc,bc,str,mode);
str+=2;
x+=size;//下一个汉字偏移
}
}
}
/*****************************************************************************
* @name :void LCM_Interrupt(void)
* @date :2018-11-13
* @function :None
* @parameters :None
* @retvalue :
******************************************************************************/
void LCMIF_DMA_Interrupt(void) interrupt 13
{
if(LCMIFSTA & 0x01)
{
LCMIFSTA = 0x00;
LcmFlag = 0;
}
if(DMA_LCM_STA & 0x01)
{
if(DmaFlag)
{
DmaFlag = 0;
DMA_LCM_CR = 0;
}
else
{
index--;
if(index == 0)
{
DMA_LCM_CR = 0;
LCD_CS=1;
}
else
{
DMA_LCM_CR = 0xa0; //Write dat
}
}
DMA_LCM_STA = 0;
}
}
65-DMA-LCM液晶屏接口测试,STC32G12K128实验箱演示程序,STC32G8K64,STC32CL8K64
LCM_Test_8080_LCM_8bit_ILI9341主程序main.C代码如下(汇编版本在附件中):
/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
/*---------------------------------------------------------------------*/
/*************功能说明 **************
本例程基于STC32G为主控芯片的实验箱进行编写测试。
使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
LCM接口+DMA驱动液晶屏程序
8bit I8080模式, P6口接D8~D15
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_WR = P4^2; //写控制
sbit LCD_RD = P4^4; //读控制
sbit LCD_CS = P3^4; //片选
sbit LCD_RESET = P4^3; //复位
LCM指令通过中断方式等待发送完成
DMA设置长度256字节,通过中断方式判断传输完成
下载时, 选择时钟 24MHz (用户可自行修改频率).
******************************************/
#include "..\..\comm\STC32G.h"
#include "stdio.h"
#include "intrins.h"
#include "font.h"
#define MAIN_Fosc 24000000L //定义主时钟
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit LCD_RS = P4^5; //数据/命令切换
sbit LCD_WR = P4^2; //写控制
sbit LCD_RD = P4^4; //读控制
sbit LCD_CS = P3^4; //片选
sbit LCD_RESET = P4^3; //复位
//IO连接
#defineLCD_DataPort P6 //8位数据口
//支持横竖屏快速定义切换
#define USE_HORIZONTAL 0 //定义液晶屏顺时针旋转方向 0-0度旋转,1-90度旋转,2-180度旋转,3-270度旋转
//画笔颜色
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40 //棕色
#define BRRED 0XFC07 //棕红色
#define GRAY 0X8430 //灰色
#define DARKBLUE 0X01CF //深蓝色
#define LIGHTBLUE 0X7D7C //浅蓝色
#define GRAYBLUE 0X5458 //灰蓝色
#define LIGHTGREEN 0X841F //浅绿色
#define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)
//定义LCD的尺寸
#define LCD_W 240
#define LCD_H 320
u16 POINT_COLOR=0x0000; //画笔颜色
typedef struct
{
u16 width; //LCD 宽度
u16 height; //LCD 高度
u16 id; //LCD ID
u8dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
u8 wramcmd; //开始写gram指令
u8 rramcmd; //开始读gram指令
u8 setxcmd; //设置x坐标指令
u8 setycmd; //设置y坐标指令
}_lcd_dev;
_lcd_dev lcddev;
void delay_ms(u16 ms);
void GPIO_Init(void);
void LCM_Config(void);
void LCD_Init(void);
void Test_Color(void);
void LCD_WR_DATA_16Bit(u16 Data);
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd);
void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode);
void LCD_direction(u8 direction);
void main(void)
{
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x30; P0M0 = 0x30; //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
P1M1 = 0x32; P1M0 = 0x32; //设置P1.1、P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V), P1.1在PWM当DAC电路通过电阻串联到P2.3
P2M1 = 0x3c; P2M0 = 0x3c; //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V),设置开漏模式需要断开PWM当DAC电路中的R2电阻
P3M1 = 0x50; P3M0 = 0x50; //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
P4M1 = 0x3c; P4M0 = 0x3c; //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
P5M1 = 0x0c; P5M0 = 0x0c; //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
P6M1 = 0xff; P6M0 = 0xff; //设置为漏极开路(实验箱加了上拉电阻到3.3V)
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
GPIO_Init();
LCM_Config();
EA = 1;
LCD_Init(); //LCM初始化
while(1)
{
Test_Color();
}
}
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{
u16 i,j;
u16 width=ex-sx+1; //得到填充的宽度
u16 height=ey-sy+1; //高度
LCD_SetWindows(sx,sy,ex,ey);//设置显示窗口
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
LCD_WR_DATA_16Bit(color); //写入数据
}
}
void Test_Color(void)
{
u8 buf = {0};
LCD_Fill(0,0,lcddev.width,lcddev.height,WHITE);
Show_Str(20,30,BLUE,YELLOW,"LCM Test",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,RED);
Show_Str(20,30,BLUE,YELLOW,"RED ",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,GREEN);
Show_Str(20,30,BLUE,YELLOW,"GREEN ",16,1);delay_ms(800);
LCD_Fill(0,0,lcddev.width,lcddev.height,BLUE);
Show_Str(20,30,RED,YELLOW,"BLUE ",16,1);delay_ms(800);
}
//========================================================================
// 函数: void delay_ms(u16 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void delay_ms(u16 ms)
{
u16 i;
do{
i = MAIN_Fosc / 6000;
while(--i);
}while(--ms);
}
/*****************************************************************************
* @name :void LCD_WR_REG(u8 Reg)
* @date :2018-08-09
* @function :Write an 16-bit command to the LCD screen
* @parameters :data:Command value to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_REG(u8 Reg)
{
LCMIFDATL = Reg;
LCD_CS=0;
LCMIFCR = 0x84; //Enable interface, write command out
while(!LCD_CS);
}
/*****************************************************************************
* @name :void LCD_WR_DATA(u8 Data)
* @date :2018-08-09
* @function :Write an 16-bit data to the LCD screen
* @parameters :data:data value to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_DATA(u8 Data)
{
LCMIFDATL = Data;
LCD_CS=0;
LCMIFCR = 0x85; //Enable interface, write data out
while(!LCD_CS);
}
/*****************************************************************************
* @name :void LCD_WR_DATA_16Bit(u16 Data)
* @date :2018-08-09
* @function :Write an 16-bit command to the LCD screen
* @parameters :Data:Data to be written
* @retvalue :None
******************************************************************************/
void LCD_WR_DATA_16Bit(u16 Data)
{
LCD_WR_DATA((u8)(Data>>8));
LCD_WR_DATA((u8)Data);
}
/*****************************************************************************
* @name :void LCD_WriteReg(u8 LCD_Reg, u8 LCD_RegValue)
* @date :2018-08-09
* @function :Write data into registers
* @parameters :LCD_Reg:Register address
LCD_RegValue:Data to be written
* @retvalue :None
******************************************************************************/
void LCD_WriteReg(u8 LCD_Reg, u8 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
/*****************************************************************************
* @name :void LCD_WriteRAM_Prepare(void)
* @date :2018-08-09
* @function :Write GRAM
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(lcddev.wramcmd);
}
/*****************************************************************************
* @name :void LCD_DrawPoint(u16 x,u16 y)
* @date :2018-08-09
* @function :Write a pixel data at a specified location
* @parameters :x:the x coordinate of the pixel
y:the y coordinate of the pixel
* @retvalue :None
******************************************************************************/
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetWindows(x,y,x,y);//设置光标位置
LCD_WR_DATA_16Bit(POINT_COLOR);
}
/*****************************************************************************
* @name :void GPIO_Init(void)
* @date :2018-11-13
* @function :Set the gpio to push-pull mode
* @parameters :None
* @retvalue :None
******************************************************************************/
void GPIO_Init(void)
{
//P6口设置成推挽输出
P6M0 |= 0xff;
P6M1 &= 0x00;
//P3.4口设置成推挽输出
P3M0 |= 0x10;
P3M1 &= ~0x10;
//P4.2,P4.3,P4.4,P4.5口设置成推挽输出
P4M0 |= 0x3c;
P4M1 &= ~0x3c;
}
/*****************************************************************************
* @name :void LCM_Config(void)
* @date :2018-11-13
* @function :Config LCM
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCM_Config(void)
{
LCMIFCFG = 0x84; //bit7 1:Enable Interrupt, bit1 0:8bit mode; bit0 0:8080,1:6800
LCMIFCFG2 = 0x09; //RS:P45,RD:P44,WR:P42; Setup Time=2,HOLD Time=1
LCMIFSTA = 0x00;
}
/*****************************************************************************
* @name :void LCDReset(void)
* @date :2018-08-09
* @function :Reset LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCDReset(void)
{
LCD_CS=1;
delay_ms(50);
LCD_RESET=0;
delay_ms(150);
LCD_RESET=1;
delay_ms(50);
}
/*****************************************************************************
* @name :void LCD_Init(void)
* @date :2018-08-09
* @function :Initialization LCD screen
* @parameters :None
* @retvalue :None
******************************************************************************/
void LCD_Init(void)
{
LCDReset(); //初始化之前复位
// delay_ms(150); //根据不同晶振速度可以调整延时,保障稳定显示
//*************2.4inch ILI9341初始化**********//
LCD_WR_REG(0xCF);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xD9); //0xC1
LCD_WR_DATA(0X30);
LCD_WR_REG(0xED);
LCD_WR_DATA(0x64);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0X12);
LCD_WR_DATA(0X81);
LCD_WR_REG(0xE8);
LCD_WR_DATA(0x85);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x7A);
LCD_WR_REG(0xCB);
LCD_WR_DATA(0x39);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x34);
LCD_WR_DATA(0x02);
LCD_WR_REG(0xF7);
LCD_WR_DATA(0x20);
LCD_WR_REG(0xEA);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_REG(0xC0); //Power control
LCD_WR_DATA(0x1B); //VRH
LCD_WR_REG(0xC1); //Power control
LCD_WR_DATA(0x12); //SAP;BT 0x01
LCD_WR_REG(0xC5); //VCM control
LCD_WR_DATA(0x08); //30
LCD_WR_DATA(0x26); //30
LCD_WR_REG(0xC7); //VCM control2
LCD_WR_DATA(0XB7);
LCD_WR_REG(0x36); // Memory Access Control
LCD_WR_DATA(0x08);
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x55);
LCD_WR_REG(0xB1);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x1A);
LCD_WR_REG(0xB6); // Display Function Control
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0xA2);
LCD_WR_REG(0xF2); // 3Gamma Function Disable
LCD_WR_DATA(0x00);
LCD_WR_REG(0x26); //Gamma curve selected
LCD_WR_DATA(0x01);
LCD_WR_REG(0xE0); //Set Gamma
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x1A);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x49);
LCD_WR_DATA(0X66);
LCD_WR_DATA(0x3B);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x11);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x05);
LCD_WR_DATA(0x04);
LCD_WR_REG(0XE1); //Set Gamma
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x02);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x36);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x4C);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x2E);
LCD_WR_DATA(0x2F);
LCD_WR_DATA(0x05);
LCD_WR_REG(0x2B);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x01);
LCD_WR_DATA(0x3f);
LCD_WR_REG(0x2A);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0xef);
LCD_WR_REG(0x11); //Exit Sleep
delay_ms(120);
LCD_WR_REG(0x29); //display on
//设置LCD属性参数
LCD_direction(USE_HORIZONTAL);//设置LCD显示方向
}
/*****************************************************************************
* @name :void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
* @date :2018-08-09
* @function :Setting LCD display window
* @parameters :xStar:the bebinning x coordinate of the LCD display window
yStar:the bebinning y coordinate of the LCD display window
xEnd:the endning x coordinate of the LCD display window
yEnd:the endning y coordinate of the LCD display window
* @retvalue :None
******************************************************************************/
void LCD_SetWindows(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA((u8)(xStar>>8));
LCD_WR_DATA((u8)(0x00FF&xStar));
LCD_WR_DATA((u8)(xEnd>>8));
LCD_WR_DATA((u8)(0x00FF&xEnd));
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA((u8)(yStar>>8));
LCD_WR_DATA((u8)(0x00FF&yStar));
LCD_WR_DATA((u8)(yEnd>>8));
LCD_WR_DATA((u8)(0x00FF&yEnd));
LCD_WriteRAM_Prepare(); //开始写入GRAM
}
/*****************************************************************************
* @name :void LCD_direction(u8 direction)
* @date :2018-08-09
* @function :Setting the display direction of LCD screen
* @parameters :direction:0-0 degree
1-90 degree
2-180 degree
3-270 degree
* @retvalue :None
******************************************************************************/
void LCD_direction(u8 direction)
{
lcddev.setxcmd=0x2A;
lcddev.setycmd=0x2B;
lcddev.wramcmd=0x2C;
lcddev.rramcmd=0x2E;
switch(direction){
case 0:
lcddev.width=LCD_W;
lcddev.height=LCD_H;
LCD_WriteReg(0x36,(1<<3));
break;
case 1:
lcddev.width=LCD_H;
lcddev.height=LCD_W;
LCD_WriteReg(0x36,(1<<3)|(1<<7)|(1<<5)|(1<<4));
break;
case 2:
lcddev.width=LCD_W;
lcddev.height=LCD_H;
LCD_WriteReg(0x36,(1<<3)|(1<<4)|(1<<6)|(1<<7));
break;
case 3:
lcddev.width=LCD_H;
lcddev.height=LCD_W;
LCD_WriteReg(0x36,(1<<3)|(1<<5)|(1<<6));
break;
default:break;
}
}
/*****************************************************************************
* @name :void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode)
* @date :2018-08-09
* @function :Display a single English character
* @parameters :x:the beginning x coordinate of the Character display position
y:the beginning y coordinate of the Character display position
fc:the color value of display character
bc:the background color of display character
num:the ascii code of display character(0~94)
size:the size of display character
mode:0-no overlying,1-overlying
* @retvalue :None
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u16 fc, u16 bc, u8 num,u8 size,u8 mode)
{
u8 temp;
u8 pos,t;
u16 colortemp=POINT_COLOR;
num=num-' ';//得到偏移后的值
LCD_SetWindows(x,y,x+size/2-1,y+size-1);//设置单个文字显示窗口
if(!mode) //非叠加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206;//调用1206字体
else temp=asc2_1608; //调用1608字体
for(t=0;t<size/2;t++)
{
if(temp&0x01)LCD_WR_DATA_16Bit(fc);
else LCD_WR_DATA_16Bit(bc);
temp>>=1;
}
}
}else//叠加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206;//调用1206字体
else temp=asc2_1608; //调用1608字体
for(t=0;t<size/2;t++)
{
POINT_COLOR=fc;
if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//画一个点
temp>>=1;
}
}
}
POINT_COLOR=colortemp;
LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);//恢复窗口为全屏
}
/*****************************************************************************
* @name :void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode)
* @date :2018-08-09
* @function :Display Chinese and English strings
* @parameters :x:the beginning x coordinate of the Chinese and English strings
y:the beginning y coordinate of the Chinese and English strings
fc:the color value of Chinese and English strings
bc:the background color of Chinese and English strings
str:the start address of the Chinese and English strings
size:the size of Chinese and English strings
mode:0-no overlying,1-overlying
* @retvalue :None
******************************************************************************/
void Show_Str(u16 x, u16 y, u16 fc, u16 bc, u8 *str,u8 size,u8 mode)
{
u16 x0=x;
u8 bHz=0; //字符或者中文
while(*str!=0)//数据未结束
{
if(!bHz)
{
if(x>(lcddev.width-size/2)||y>(lcddev.height-size))
return;
if(*str>0x80) bHz=1;//中文
else //字符
{
if(*str==0x0D)//换行符号
{
y+=size;
x=x0;
str++;
}
else
{
if(size>16)//字库中没有集成12X24 16X32的英文字体,用8X16代替
{
LCD_ShowChar(x,y,fc,bc,*str,16,mode);
x+=8; //字符,为全字的一半
}
else
{
LCD_ShowChar(x,y,fc,bc,*str,size,mode);
x+=size/2; //字符,为全字的一半
}
}
str++;
}
}
else//中文
{
// if(x>(lcddev.width-size)||y>(lcddev.height-size))
// return;
// bHz=0;//有汉字库
// if(size==32)
// GUI_DrawFont32(x,y,fc,bc,str,mode);
// else if(size==24)
// GUI_DrawFont24(x,y,fc,bc,str,mode);
// else
// GUI_DrawFont16(x,y,fc,bc,str,mode);
str+=2;
x+=size;//下一个汉字偏移
}
}
}
/*****************************************************************************
* @name :void LCM_Interrupt(void)
* @date :2018-11-13
* @function :None
* @parameters :None
* @retvalue :
******************************************************************************/
void LCMIF_DMA_Interrupt(void) interrupt 13
{
if(LCMIFSTA & 0x01)
{
LCMIFSTA = 0x00;
LCD_CS=1;
}
}
页:
[1]