STM32F103驱动晶联讯2.8寸TFT彩色屏
JLX280-020-PC是深圳晶联讯生产的一款彩色TFT点阵显示屏,分辨率为320*240。


U1是存储字库的芯片。内部包含以下字符的点阵数据,

在提供的接口中可以SPI方式获取字符的点阵数据。这样就不需要在程序中为自己想要的字符提供数据,转而从字库中获取,在液晶屏上显示了。
从提供的接口印字看,似乎提供了并口的通讯引脚,实际上这一款是采用串口通讯的。根据说明,当R4和R7被焊接,R5、R6、R8、R9断开时,使用并口;当R4和R7被断开,R5、R6、R8、R9被焊接时,使用串行模式。串口模式下,

其它不使用的引脚可以悬空。
使用STM32F103驱动这个显示屏的时候,只需要提供给以下几个信号就可:
1、SCLK - 串行时钟
2、SDA - 串行数据
3、CS - 片选
4、RST - 硬件复位
5、RS - 命令寄存器/数据寄存器选择
如果希望使用字库,还需要提供字库用到的几个信号
1、ROM_SCLK - 字库串行时钟
2、ROM_IN - 字库数据输入
3、ROM_OUT - 字库数据输出
4、ROM_CS - 字库选择
字库方面需要串行输入,是为了定位字符在字库中的地址用的。
驱动程序如下:
lcd.h
#include "sys.h"
#include "stdlib.h"
//LCD重要参数集
typedef struct
{
u16 width;//LCD 宽度
u16 height;//LCD 高度
u16 id; //LCD ID
u8 dir; //横屏还是竖屏控制:0,竖屏;1,横屏。
u16wramcmd;//开始写gram指令
u16 setxcmd;//设置x坐标指令
u16 setycmd;//设置y坐标指令
}_lcd_dev;
//LCD参数
extern _lcd_dev lcddev;//管理LCD重要参数
//LCD的画笔颜色和背景色
extern u16 POINT_COLOR;//默认红色
extern u16 BACK_COLOR; //背景颜色.默认为白色
////////////////////////////////////////////////////////////////////
/******************************************************************************
//本程序适用于STM32F103C8驱动晶联讯电子JLX280-020-PC(带字库)
//
// STM32F103C8T6 连线 液晶管脚 名称
//-----------------------------------------------------------------------------
// PB0 黄色 1 ROM_IN 字库串行数据输入
// PB1 白色 2 ROM_OUT 字库串行数据输出
// PB2 绿色 3 ROM_SCK 字库串行时钟
// PB5 橙色 4 ROM_CS 字库片选
// PB6 蓝色 5 LEDA 背光源
// GND 黑色 6 VSS 电源地
// VCC 红色 7 VDD 接3.3v电源
// PB7 紫色 8 SCL 串行时钟SCL
// PC13 褐色 9 RST 复位。低电平复位,复位完成后,回到高电平,液晶模块开始工作
// PC15 灰色 10 CS 片选,低电平片选
// PA0 白色 11 SDA 串行时钟SDA
// PA1 黄色 12 RS 寄存器选择信号RS
*******************************************************************************/
//-----------------LCD端口定义----------------
// 可用PB0,PB1,PB2,PB5,PB6,PB7,PC13,PC15,PA0,PA1
#define Rom_INPBout(0) // PB11对应字库IC接口“Rom_IN”(也即:字库IC的SI,串行数据输入)
#define Rom_OUTPBin(1) // PB10对应字库IC接口“Rom_OUT”(也即:字库IC的SO ,串行数据输出)
#define Rom_SCKPBout(2) // PB2对应字库IC接口“Rom_SCK”(也即:字库IC的SCK,串行时钟)
#define Rom_CSPBout(5) // PB1对应字库IC接口“Rom_CS”(也即:字库IC的CS#,片选)
#defineLCD_LED PBout(6) //背光源
#defineLCD_SCK PBout(7) //串行时钟
#defineLCD_RST PCout(13) //液晶屏复位
#defineLCD_CS PCout(15) //片选端口
#defineLCD_SDA PAout(0) //串行数据
#defineLCD_RS PAout(1) //数据/命令
//画笔颜色
#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 LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
#define DEEP_GREEN 0x0600 //定义深绿色
#define ORANGE 0xfc08 //定义橙色
#define PINK 0xf3f3 //定义粉红色
#define PURPLE 0xa1d6//定义紫色
void waitkey(void); //按键
void transfer_data_lcd(u8 data1); //写数据
void transfer_command_lcd(u8 data1); //写指令
void LCD_Init(void); //初始化
void LCD_DisplayOn(void);//开显示
void LCD_DisplayOff(void);//关显示
void LCD_Clear(u16 Color); //清屏 竖屏
void LCD_Clear1(u16 Color); //清屏 横屏
void LCD_SetCursor(u16 Xpos, u16 Ypos);//设置光标
void LCD_DrawPoint(u16 x,u16 y);//画点
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color);//快速画点
u16 LCD_ReadPoint(u16 x,u16 y); //读点
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r); //画圆
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);//画线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2); //画矩形
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color); //填充单色
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color);//填充指定颜色
void LCD_ShowChar(u16 x,u16 y,u8 turn,u8 num,u8 size,u8 mode);//显示一个字符
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size); //显示一个数字
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);//显示 数字
void LCD_ShowString(u16 x,u16 y,u8 turn,u16 width,u16 height,u8 size,u8 *p);//显示一个字符串,12/16字体
void LCD_Str(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);
void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue);
u16 LCD_ReadReg(u16 LCD_Reg);
void LCD_WriteRAM_Prepare(void);
void LCD_WriteRAM(u16 RGB_Code);
void LCD_Scan_Dir(u8 dir);//设置屏扫描方向
void LCD_Display_Dir(u8 dir);//设置屏幕显示方向
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height);//设置窗口
//字库函数
void mono_data_out(u16 mono_data,u16 font_color,u16 back_color);
void send_command_to_ROM( u16 datu );
static u8 get_data_from_ROM(void);
void get_and_write_32x32(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_16x32(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_24x24(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_12x24(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_16x16(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_8x16(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_12x12(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_6x12(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void get_and_write_5x8(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color);
void disp_GB2312_32x32_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color);
void disp_GB2312_24x24_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color);
void disp_GB2312_16x16_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color);
void disp_GB2312_12x12_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color);
void disp_GB2312_5x8_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color);lcd.c
#include "lcd.h"
#include "key.h"
#include "stdlib.h"
#include "lcdfont.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
void waitkey(void) {
delay_ms(9000);
delay_ms(9000);
delay_ms(9000);
}
//LCD的画笔颜色和背景色
u16 POINT_COLOR=0x001F; //画笔颜色
u16 BACK_COLOR=0xFFFF; //背景色
//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;
//写指令到LCD模块
void transfer_command_lcd(u8 data1) {
u8 i;
LCD_CS=0;
LCD_RS=0;
for(i=0;i<8;i++) {
LCD_SCK=0;
if(data1&0x80) LCD_SDA=1;
else LCD_SDA=0;
LCD_SCK=1;
data1<<=1;
}
LCD_CS=1;
}
//写数据到LCD模块
void transfer_data_lcd(u8 data1) {
u8 i;
LCD_CS=0;
LCD_RS=1;
for(i=0;i<8;i++) {
LCD_SCK=0;
if(data1&0x80) LCD_SDA=1;
else LCD_SDA=0;
LCD_SCK=1;
data1<<=1;
}
LCD_CS=1;
}
//连写2个字节(即16位)数据到LCD模块
void transfer_data_16(u16 data2) {
transfer_data_lcd(data2>>8);
transfer_data_lcd(data2);
}
//写寄存器
//LCD_Reg:寄存器编号
//LCD_RegValue:要写入的值
void LCD_WriteReg(u16 LCD_Reg,u16 LCD_RegValue) {
transfer_command_lcd(LCD_Reg);
transfer_data_lcd(LCD_RegValue);
}
//开始写GRAM
void LCD_WriteRAM_Prepare(void) {
transfer_command_lcd(0x2c);
}
//LCD写GRAM
//RGB_Code:颜色值
void LCD_WriteRAM(u16 RGB_Code) {
transfer_data_lcd(RGB_Code);//写十六位GRAM
}
//初始化
void LCD_Init(void) {
// 可用PB0,PB1,PB2,PB5,PB6,PB7,PC13,PC1,PA0,PA1
////////////////////////////////////////////////////////////////////
/******************************************************************************
//本程序适用于STM32F103C8驱动晶联讯电子JLX280-020-PC(带字库)
//
// STM32F103C8T6 连线 液晶管脚 名称
//-----------------------------------------------------------------------------
// PB0 黄色 1 ROM_IN 字库串行数据输入
// PB1 白色 2 ROM_OUT 字库串行数据输出
// PB2 绿色 3 ROM_SCK 字库串行时钟
// PB5 橙色 4 ROM_CS 字库片选
// PB6 蓝色 5 LEDA 背光源
// GND 黑色 6 VSS 电源地
// VCC 红色 7 VDD 接3.3v电源
// PB7 紫色 8 A0(RS) 串行时钟SCL
// PC13 褐色 9 RST 复位。低电平复位,复位完成后,回到高电平,液晶模块开始工作
// PC15 灰色 10 CS 片选,低电平片选
// PA0 白色 11 D7 串行时钟SDA
// PA1 黄色 12 D6 寄存器选择信号RS
*******************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); //使能PA,B,C端口时钟 (ENABLE开启)
// GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_0|GPIO_Pin_1);
// GPIOB
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOC 4,5
GPIO_SetBits(GPIOB,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); //PC4,PC5 输出高
// GPIOC
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_1|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_13|GPIO_Pin_1|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_1);
//----------- Start Initial Sequence ---------//
LCD_RST=0;
delay_ms(200);
LCD_RST=1;
delay_ms(200);
//开始初始化:
//------------------------------display and color format setting--------------------------------//
transfer_command_lcd(0x36); //行扫描顺序及RGB,列扫描顺序,横放/竖放
transfer_data_lcd(0x00);
transfer_data_lcd(0x48);
transfer_command_lcd(0xB6); //显示功能设置:列/行 显示顺序
transfer_data_lcd(0x0A);
transfer_data_lcd(0x82); //改变SOURCE线的方向:0xa2:左到右,0x82:右到左
transfer_command_lcd(0x3a); //256K 16bit/pixel
transfer_data_lcd(0x05);
//--------------------------------ST7789V Frame rate setting----------------------------------//
transfer_command_lcd(0xb2);
transfer_data_lcd(0x0c);
transfer_data_lcd(0x0c);
transfer_data_lcd(0x00);
transfer_data_lcd(0x33);
transfer_data_lcd(0x33);
transfer_command_lcd(0xb7);
transfer_data_lcd(0x35);
//---------------------------------ST7789V Power setting--------------------------------------//
transfer_command_lcd(0xbb);
transfer_data_lcd(0x28);
transfer_command_lcd(0xc0);
transfer_data_lcd(0x2c);
transfer_command_lcd(0xc2);
transfer_data_lcd(0x01);
transfer_command_lcd(0xc3);
transfer_data_lcd(0x10);
transfer_command_lcd(0xc4);
transfer_data_lcd(0x20);
transfer_command_lcd(0xc6);
transfer_data_lcd(0x0f);
transfer_command_lcd(0xd0);
transfer_data_lcd(0xa4);
transfer_data_lcd(0xa1);
//--------------------------------ST7789V gamma setting---------------------------------------//
transfer_command_lcd(0xe0);
transfer_data_lcd(0xd0);
transfer_data_lcd(0x00);
transfer_data_lcd(0x02);
transfer_data_lcd(0x07);
transfer_data_lcd(0x0a);
transfer_data_lcd(0x28);
transfer_data_lcd(0x32);
transfer_data_lcd(0x44);
transfer_data_lcd(0x42);
transfer_data_lcd(0x06);
transfer_data_lcd(0x0e);
transfer_data_lcd(0x12);
transfer_data_lcd(0x14);
transfer_data_lcd(0x17);
transfer_command_lcd(0Xe1); //设置GAMMA值,由玻璃及IC原厂设置
transfer_data_lcd(0xd0);
transfer_data_lcd(0x00);
transfer_data_lcd(0x02);
transfer_data_lcd(0x07);
transfer_data_lcd(0x0a);
transfer_data_lcd(0x28);
transfer_data_lcd(0x31);
transfer_data_lcd(0x54);
transfer_data_lcd(0x47);
transfer_data_lcd(0x0e);
transfer_data_lcd(0x1c);
transfer_data_lcd(0x17);
transfer_data_lcd(0x1b);
transfer_data_lcd(0x1e);
transfer_command_lcd(0x11); //退出睡眠
delay_ms(50); //这个很重要
transfer_command_lcd(0x29); //打开显示:display ON.
transfer_command_lcd(0x2c); // 写数据开始
LCD_Clear(BLACK);
}
//定义窗口坐标:开始坐标(XS,YS)以及窗口大小(x_total,y_total)
void lcd_address(u16 XS,u16 YS,u16 x_total,u16 y_total) {
u16 XE,YE;
XE=XS+x_total-1;
YE=YS+y_total-1;
transfer_command_lcd(0x2a); // 设置X开始及结束的地址
transfer_data_16(XS); // X开始地址(16位)
transfer_data_16(XE); // X结束地址(16位)
transfer_command_lcd(0x2b); // 设置Y开始及结束的地址
transfer_data_16(YS); // Y开始地址(16位)
transfer_data_16(YE); // Y结束地址(16位)
transfer_command_lcd(0x2c); // 写数据开始
}
//清屏函数 竖屏
//color:要清屏的填充色
void LCD_Clear(u16 color) {
u32 index=0;
u32 totalpoint=240;
totalpoint*=320; //得到总点数
lcd_address(0,0,240,320);
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(index=0;index<totalpoint;index++)transfer_data_16(color);
}
//清屏函数 横屏
//color:要清屏的填充色
void LCD_Clear1(u16 color) {
u32 index=0;
u32 totalpoint=240;
totalpoint*=320; //得到总点数
lcd_address(0,0,320,240);
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(index=0;index<totalpoint;index++)transfer_data_16(color);
}
//LCD开启显示
void LCD_DisplayOn(void) {
transfer_command_lcd(0x29);
}
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos) {
transfer_command_lcd(0x2a);
transfer_data_lcd(Xpos>>8);
transfer_data_lcd(Xpos&0XFF);
transfer_command_lcd(0x2b);
transfer_data_lcd(Ypos>>8);
transfer_data_lcd(Ypos&0XFF);
LCD_WriteReg(0x2a, Xpos);
LCD_WriteReg(0x2b, Ypos);
transfer_command_lcd(0x2c);
}
//画点
//x,y:坐标
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u16 x,u16 y) {
LCD_SetCursor(x,y); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
transfer_data_lcd(POINT_COLOR);
}
//快速画点
//x,y:坐标
//color:颜色
void LCD_Fast_DrawPoint(u16 x, u16 y, u16 color) {
transfer_command_lcd(0x2a);
transfer_data_lcd(x>>8);
transfer_data_lcd(x&0XFF);
transfer_command_lcd(0x2b);
transfer_data_lcd(y>>8);
transfer_data_lcd(y&0XFF);
transfer_command_lcd(0x2c);
transfer_data_16(color); //写数据
}
//在指定位置显示一个字符
//x,y:起始坐标
//num:要显示的字符:" "--->"~"
//size:字体大小 12/16/24/32
//mode:叠加方式(1)还是非叠加方式(0)
void LCD_ShowChar(u16 x,u16 y,u8 turn,u8 num,u8 size,u8 mode) {
u8 temp,t1,t;
u16 y0=y;
u8 csize=(size/8+((size%8)?1:0))*(size/2); //得到字体一个字符对应点阵集所占的字节数
//设置窗口
num=num-' ';//得到偏移后的值
if(turn == 1) {
lcddev.width=240;
lcddev.height=320;
} else {
lcddev.width=320;
lcddev.height=240;
}
for(t=0;t<csize;t++) {
if(size==12)temp=asc2_1206[num][t]; //调用1206字体
else if(size==16)temp=asc2_1608[num][t]; //调用1608字体
else if(size==24)temp=asc2_2412[num][t]; //调用2412字体
else if(size==32)temp=asc2_3216[num][t]; //调用3216字体
else return; //没有的字库
for(t1=0;t1<8;t1++) {
if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
else if(mode==1)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
temp<<=1;
y++;
if(x>=lcddev.width)return; //超区域了
if((y-y0)==size) {
y=y0;
x++;
if(x>=lcddev.width)return; //超区域了
break;
}
}
}
}
//在指定位置显示一个中文汉字
//x,y:起始坐标
//num:要显示的字符:" "--->"~"
//size:字体大小 16/24/32
//mode:叠加方式(1)还是非叠加方式(0)
void LCD_ShowChinese(u16 x,u16 y,u8 *num,u8 size,u8 mode) {
u8 temp,t1,t;
u16 y0=y;
u8 csize=(size/8+((size%8)?1:0))*size; //得到字体一个字符对应点阵集所占的字节数
int index = -1;
if(size == 16) {
for(t=0; t<sizeof(ch_16_16)/sizeof(ch_16_16[0]); t++) {
if((num[0] == ch_16_16[t].index[0]) && (num[1] == ch_16_16[t].index[1])) {
index = t;
break;
}
}
} else if(size == 24) {
for(t=0; t<sizeof(ch_24_24)/sizeof(ch_24_24[0]); t++) {
if((num[0] == ch_24_24[t].index[0]) && (num[1] == ch_24_24[t].index[1])) {
index = t;
break;
}
}
} else if(size == 32) {
for(t=0; t<sizeof(ch_32_32)/sizeof(ch_32_32[0]); t++) {
if((num[0] == ch_32_32[t].index[0]) && (num[1] == ch_32_32[t].index[1])) {
index = t;
break;
}
}
} else {
return;
}
if(index == -1) return;
for(t=0;t<csize;t++) {
if(size == 16) temp=ch_16_16[index].word[t];
else if(size == 24) temp=ch_24_24[index].word[t];
else if(size == 32) temp=ch_32_32[index].word[t];
for(t1=0;t1<8;t1++) {
if(temp&0x80)LCD_Fast_DrawPoint(x,y,POINT_COLOR);
else if(mode==1)LCD_Fast_DrawPoint(x,y,BACK_COLOR);
temp<<=1;
y++;
if(y>=lcddev.height)return; //超区域了
if((y-y0)==size) {
y=y0;
x++;
if(x>=lcddev.width)return; //超区域了
break;
}
}
}
}
//显示字符串
//x,y:起点坐标
//width,height:区域大小
//size:字体大小
//*p:字符串起始地址
void LCD_ShowString(u16 x,u16 y,u8 turn,u16 width,u16 height,u8 size,u8 *p) {
u8 x0=x;
width+=x;
height+=y;
while((*p!=127)&&(*p>=' ')) {
if(turn == 1) {
lcddev.width=240;
lcddev.height=320;
} else {
lcddev.width=320;
lcddev.height=240;
}
if(x>=width){x=x0;y+=size;}
if(y>=height)break;//退出
if(*p >127) {
LCD_ShowChinese(x,y,p,size,0);
x += size;
p += 2;
} else {
LCD_ShowChar(x,y,turn,*p,size,0);
x += size >> 1;
p++;
}
}
};
//将单色的8位的数据(代表8个像素点)转换成彩色的数据传输给液晶屏
void mono_data_out(u16 mono_data,u16 font_color,u16 back_color) {
u16 i;
for(i=0;i<8;i++) {
if(mono_data&0x80) {
transfer_data_16(font_color); //当数据是1时,显示字体颜色
} else {
transfer_data_16(back_color); //当数据是0时,显示底色
}
mono_data<<=1;
}
}
/****送指令到晶联讯字库IC***/
void send_command_to_ROM( u16 datu ) {
u16 i;
for(i=0;i<8;i++ ) {
if(datu&0x80)
Rom_IN = 1;
else
Rom_IN = 0;
datu = datu<<1;
Rom_SCK=0;
Rom_SCK=1;
// delay_ms(1);
}
}
/****从晶联讯字库IC中取汉字或字符数据(1个字节)***/
static u8 get_data_from_ROM(void) {
u16 i;
u16 ret_data=0;
Rom_SCK=1;
for(i=0;i<8;i++) {
Rom_OUT=1;
Rom_SCK=0;
ret_data=ret_data<<1;
if( Rom_OUT )
ret_data=ret_data+1;
else
ret_data=ret_data+0;
Rom_SCK=1;
// delay_ms(1);
}
return(ret_data);
}
//从指定地址读出32x32点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_32x32(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<32;j++) {
lcd_address(y,x+j,32,32);
for(i=0;i<4;i++) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出16x32点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_16x32(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<32;j++) {
lcd_address(y,x+j,32,16);
for(i=0; i<2; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出24x24点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_24x24(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<24;j++) {
lcd_address(y,x+j,24,24);
for(i=0; i<3; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出12x24点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_12x24(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<24;j++) {
lcd_address(y,x+j,24,12);
for(i=0; i<2; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出16x16点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_16x16(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<16;j++) {
lcd_address(y,x+j,16,16);
for(i=0; i<2; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出8x16点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_8x16(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<16;j++) {
lcd_address(y,x+j,16,8);
for(i=0; i<1; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出12x12点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_12x12(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<12;j++) {
lcd_address(y,x+j,12,12);
for(i=0; i<2; i++ ) {
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出6x12点阵字符的数据写到液晶屏指定(y,x)座标中
void get_and_write_6x12(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<12;j++)
{
lcd_address(y,x+j,12,6);
for(i=0; i<1; i++ )
{
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
}
Rom_CS=1;
}
//从指定地址读出数据写到液晶屏指定(y,x)座标中
void get_and_write_5x8(u32 fontaddr,u16 x,u16 y,u16 font_color,u16 back_color) {
u16 j,disp_data;
Rom_CS = 0;
//Rom_SCK=0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontaddr&0xff0000)>>16); //地址的高8位,共24位
send_command_to_ROM((fontaddr&0xff00)>>8); //地址的中8位,共24位
send_command_to_ROM(fontaddr&0xff); //地址的低8位,共24位
for(j=0;j<8;j++) {
lcd_address(y,x+j,8,5);
disp_data=get_data_from_ROM();
mono_data_out(disp_data,font_color,back_color); //这一句相当于写了一行8个像素点的数据。
}
Rom_CS=1;
}
/***********/
u32 fontaddr;
//显示一串32x32点阵的汉字或16x32点阵的ASCII码
void disp_GB2312_32x32_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color) {
u16 i= 0;
while((text[i]>0x00)) {
if( ((text[i]>=0xb0) && (text[i]<=0xf7) ) && (text[i+1]>=0xa1) ) {
fontaddr = (text[i]- 0xb0)*94;
fontaddr += (text[i+1]-0xa1)+846;
fontaddr = (u32)(fontaddr*128);
fontaddr = (u32)(fontaddr+0Xedf00);
get_and_write_32x32(fontaddr,y,x,font_color,back_color);
i+=2;
x+=32;
} else if(( (text[i]>=0xa1) && (text[i]<=0xa9) ) && (text[i+1]>=0xa1) ) {
fontaddr = (text[i]- 0xa1)*94;
fontaddr += (text[i+1]-0xa1);
fontaddr = (u32)(fontaddr*128);
fontaddr = (u32)(fontaddr+0Xedf00);
get_and_write_32x32(fontaddr,y,x,font_color,back_color);
i+=2;
x+=32;
} else if( (text[i]>=0x20) && (text[i]<=0x7e) ) {
fontaddr = (text[i]- 0x20);
fontaddr = (u32)(fontaddr*64);
fontaddr = (u32)(fontaddr+0x1e5a50);
get_and_write_16x32(fontaddr,y,x,font_color,back_color);
i+=1;
x+=16;
} else {
i++;
}
}
}
//显示一串24x24点阵的汉字或12x24点阵的ASCII码
void disp_GB2312_24x24_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color) {
u16 i= 0;
while((text[i]>0x00)) {
if( ((text[i]>=0xb0) && (text[i]<=0xf7) ) && (text[i+1]>=0xa1) ) {
fontaddr = (text[i]- 0xb0)*94;
fontaddr += (text[i+1]-0xa1)+846;
fontaddr = (u32)(fontaddr*72);
fontaddr = (u32)(fontaddr+0X068190);
get_and_write_24x24(fontaddr,y,x,font_color,back_color);
i+=2;
x+=24;
} else if(( (text[i]>=0xa1) && (text[i]<=0xa9) ) && (text[i+1]>=0xa1) ) {
fontaddr = (text[i]- 0xa1)*94;
fontaddr += (text[i+1]-0xa1);
fontaddr = (u32)(fontaddr*72);
fontaddr = (u32)(fontaddr+0X068190);
get_and_write_24x24(fontaddr,y,x,font_color,back_color);
i+=2;
x+=24;
} else if( (text[i]>=0x20) && (text[i]<=0x7e) ) {
fontaddr = (text[i]- 0x20);
fontaddr = (u32)(fontaddr*48);
fontaddr = (u32)(fontaddr+0x1dff00);
get_and_write_12x24(fontaddr,y,x,font_color,back_color);
i+=1;
x+=12;
} else {
i++;
}
}
}
//=====从字库读数据,显示16*16点阵的汉字或8*16点阵的数字========
void disp_GB2312_16x16_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color) {
u16 i= 0;
while((text[i]>0x00)) {
if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1)) {
fontaddr = (text[i]- 0xb0)*94;
fontaddr += (text[i+1]-0xa1)+846;
fontaddr = (u32)(fontaddr*32);
fontaddr = (u32)(fontaddr+0x2c9d0);
get_and_write_16x16(fontaddr,y,x,font_color,back_color);
i+=2;
x+=16;
} else if(((text[i]>=0xa1) &&(text[i]<=0xa9))&&(text[i+1]>=0xa1)) {
fontaddr = (text[i]- 0xa1)*94;
fontaddr += (text[i+1]-0xa1);
fontaddr = (u32)(fontaddr*32);
fontaddr = (u32)(fontaddr+0x2c9d0);
get_and_write_16x16(fontaddr,y,x,font_color,back_color);
i+=2;
x+=16;
} else if((text[i]>=0x20) &&(text[i]<=0x7e)) {
fontaddr = (text[i]- 0x20);
fontaddr = (u32)(fontaddr*16);
fontaddr = (u32)(fontaddr+0x1dd780);
get_and_write_8x16(fontaddr,y,x,font_color,back_color);
i+=1;
x+=8;
} else {
i++;
}
}
}
//=====从字库读数据,显示12*12点阵的汉字或6*12点阵的数字
void disp_GB2312_12x12_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color) {
u16 i= 0;
while((text[i]>0x00)) {
if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1)) {
fontaddr = (text[i]- 0xb0)*94;
fontaddr += (text[i+1]-0xa1)+846;
fontaddr = (u32)(fontaddr*24);
fontaddr = (u32)(fontaddr+0x00);
get_and_write_12x12(fontaddr,y,x,font_color,back_color);
i+=2;
x+=12;
} else if(((text[i]>=0xa1) &&(text[i]<=0xa9))&&(text[i+1]>=0xa1)) {
fontaddr = (text[i]- 0xa1)*94;
fontaddr += (text[i+1]-0xa1);
fontaddr = (u32)(fontaddr*24);
fontaddr = (u32)(fontaddr+0x00);
get_and_write_12x12(fontaddr,y,x,font_color,back_color);
i+=2;
x+=12;
} else if((text[i]>=0x20) &&(text[i]<=0x7e)) {
fontaddr = (text[i]- 0x20);
fontaddr = (u32)(fontaddr*12);
fontaddr = (u32)(fontaddr+0x1dbe00);
get_and_write_6x12(fontaddr,y,x,font_color,back_color);
i+=1;
x+=6;
} else {
i++;
}
}
}
//=====从字库读数据,显示5*8点阵的字
void disp_GB2312_5x8_string(u16 y,u16 x,u8 *text,u16 font_color,u16 back_color) {
u16 i= 0;
while((text[i]>0x00)) {
if((text[i]>=0x20) &&(text[i]<=0x7e)) {
fontaddr = (text[i]- 0x20);
fontaddr = (u32)(fontaddr*8);
fontaddr = (u32)(fontaddr+0x1ddf80);
get_and_write_5x8(fontaddr,y,x,font_color,back_color);
i+=1;
x+=6;
} else {
i++;
}
}
}在主程序中,显示字符串的例子
int main(void) {
delay_init(); // 延时函数初始化
LCD_Init(); // 初始化显示屏
uart_init(115200); // 初始化串口,波特率为115200
// 内存数据访问控制
transfer_command_lcd(0x36);
transfer_data_lcd(0x00);
transfer_data_lcd(0x48);
// 清屏
LCD_Clear(BLACK);
// 显示字符
disp_GB2312_16x16_string(48, 208, "测试Test", GREEN, BLACK);
}
}
我要赚赏金
