内 容:实现LCD显示
学 时:4学时
知识点:LCD12864芯片介绍,读写操作时序,电路设计
重点: 读写操作时序
难点:读写操作时序
时间:2022年12月26日 9:00~11:50
总结:
1 了解LCD12864芯片配置
2 使用proteus设计LCD显示电路
3 编程实现LCD显示
2022年12月26日 13:30~16:20下午进行中期答辩
1 LCD12864介绍
1.1 引脚功能介绍
1.2 RAM 地址映射
1.3 读写操作时序
2 电路设计
3 代码实现
3.1 LCD12864初始化
3.2 写操作函数
3.3 部分关键源代码
4 Proteus功能仿真
液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。12864字符型液晶是一种专门用来显示字母、数字、符号等的点阵型液晶模块,能够同时显示16*2即32个字符。
1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线,VCC(15脚)和地线GND(16脚)。各引脚功能如表1。
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,1602的内部显示地址如图1。
图1 LCD1602内部显示地址
通过时序图来操作液晶。时序图可以参考图1-3或是12864芯片手册。由图1-2和图1-3可知,若要传送数据或命令到12864,需要向12864液晶写入数据。所以需要用到写时序。
其中,RW设置为低电平RW=0,RS依据传命令和数据的不同分别设置为0和1,将需要传输的数据赋值给DB0-DB7,EN设置为高电平。
延时Tpm(查看芯片手册)
EN设置为低电平
图1- 3 12864写时序
但是需要注意的是,每次在进行读写操作时,要判断上次数据是否已经传送完成即是否“忙”。判断是否“忙”只需要判断DB7位是否为零,若为零表示空闲,不需要等待。为1表示“忙”,需要等待。由于无法单独读取DB7位,只能将DB0~DB7全部读取出来。读取时序如图1-4所示。
图1-4 12864读时序
读操作过程与写过程类似,如下:
DB0~DB7的初始化设置为0或是1RW设置为高即读状态;
RS设置为低,读命令;
EN使能位设置为高,开始读取数据;
判断DB7是否为高;
EN设置为高,结束读取。
本实训项目采用型号为12864的LCD显示器件。原理图设计如图4。其中,12864中的引脚D0、D1、D2、D3、D4、D4、D5、D6、D7、RS、RW、E分别于STM32中的PB1-PB11引脚相连。
下图为12864 LCD液晶屏的连接原理图:
LCD1602使用GPIOB进行数据传输,故需要调用时钟使能函数对GPIOB的端口时钟进行使能,只有使能端口后相关参数的配置才能生效。GPIO_InitTypeDef结构体包含了GPIO所需配置的所有参数,因此配置GPIO主要是调用GPIO_InitTypeDef对其内部的元素进行配置。
void LCD_Init(void) //LCD初始化
{
LCD_GPIO_Config();
LCD_FUNCTION_Config();
LCD12864_RES_0;
delay_ms(10);
LCD12864_RES_1;
delay_ms(50);
LCD_CMD_DIS(ON);
LCD_INITIAL_COLUNM(INITIAL_COLUNM);
}
其中,LCD12864引脚配置函数代码如下:
void LCD_FUNCTION_Config(void)
{
GPIO_InitTypeDef LCD_Struct;
RCC_APB2PeriphClockCmd(LCD12864_Periph,ENABLE);
LCD_Struct.GPIO_Mode = GPIO_Mode_Out_PP;
LCD_Struct.GPIO_Speed = GPIO_Speed_50MHz;
LCD_Struct.GPIO_Pin = LCD12864_RES_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_E_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_RS_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_RW_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_CS1_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_CS2_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
}
写操作函数分为写命令和写数据函数。在写命令和写数据时,RS引脚输入值会有变化。 因LCD12864的DB0-DB7分别连到STM32的PC0-PC7,故使用ODR寄存器的1-8位一次性将数据写入。
//指令写入数据显示列
//parameter: 0-128
void LCD_CMD_Line(u8 Line)
{
Line %= 128;
if(Line<64)
{
LCD_DIS_SELECT(DIS_LEFT);
}
else
{
LCD_DIS_SELECT(DIS_RIGHT);
}
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
Line = CMD_LINE|Line;
LCD_GPIO_MASK(Line);
delay_us(2);
LCD12864_E_0;
}
//指令写入数据显示页
//parameter: 0-7
void LCD_CMD_PAGE(u8 Page)
{
Page%=8;
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
Page = CMD_PAGE|Page;
LCD_GPIO_MASK(Page);
delay_us(2);
LCD12864_E_0;
}
其中,宏定义如下:
#define LCD12864_GPIO GPIOC
#define LCD12864_Periph RCC_APB2Periph_GPIOC
#define LCD12864_E_GPIO GPIO_Pin_8
#define LCD12864_RW_GPIO GPIO_Pin_9
#define LCD12864_RS_GPIO GPIO_Pin_10
#define LCD12864_CS2_GPIO GPIO_Pin_11
#define LCD12864_CS1_GPIO GPIO_Pin_12
#define LCD12864_RES_GPIO GPIO_Pin_13
#define LCD12864_DATA_GPIO GPIO_Pin_0|GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6|GPIO_Pin_7
#define LCD12864_RES_0 GPIO_ResetBits(LCD12864_GPIO,LCD12864_RES_GPIO)
#define LCD12864_RES_1 GPIO_SetBits(LCD12864_GPIO,LCD12864_RES_GPIO)
#define LCD12864_E_0 GPIO_ResetBits(LCD12864_GPIO,LCD12864_E_GPIO)
#define LCD12864_E_1 GPIO_SetBits(LCD12864_GPIO,LCD12864_E_GPIO)
#define LCD12864_RW_W GPIO_ResetBits(LCD12864_GPIO,LCD12864_RW_GPIO)
#define LCD12864_RW_R GPIO_SetBits(LCD12864_GPIO,LCD12864_RW_GPIO)
#define LCD12864_RS_CMD GPIO_ResetBits(LCD12864_GPIO,LCD12864_RS_GPIO)
#define LCD12864_RS_DATA GPIO_SetBits(LCD12864_GPIO,LCD12864_RS_GPIO)
#define LCD12864_CS1_ON GPIO_ResetBits(LCD12864_GPIO,LCD12864_CS1_GPIO)
#define LCD12864_CS1_OFF GPIO_SetBits(LCD12864_GPIO,LCD12864_CS1_GPIO)
#define LCD12864_CS2_ON GPIO_ResetBits(LCD12864_GPIO,LCD12864_CS2_GPIO)
#define LCD12864_CS2_OFF GPIO_SetBits(LCD12864_GPIO,LCD12864_CS2_GPIO)
//开启或关闭
#define ON 1
#define OFF 0
//LCD命令
#define CMD_DIS_ON 0X3F
#define CMD_DIS_OFF 0X3E
#define CMD_BUSY 0X80
#define CMD_COLUNM 0XC0
#define CMD_LINE 0X40
#define CMD_PAGE 0XB8
//显示屏幕选择
#define DIS_NONE 0
#define DIS_LEFT 1
#define DIS_RIGHT 2
#define DIS_ALL 3
//尺寸
#define SMALL 1
#define MIDDLE 2
#define LONG 3
//方向选择
#define UP 1
#define DOWN 2
lcd.c
#include "lcd.h"
#include "delay.h"
static u8 INITIAL_COLUNM=0;
void LCD_FUNCTION_Config(void)
{
GPIO_InitTypeDef LCD_Struct;
RCC_APB2PeriphClockCmd(LCD12864_Periph,ENABLE);
LCD_Struct.GPIO_Mode = GPIO_Mode_Out_PP;
LCD_Struct.GPIO_Speed = GPIO_Speed_50MHz;
LCD_Struct.GPIO_Pin = LCD12864_RES_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_E_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_RS_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_RW_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_CS1_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
LCD_Struct.GPIO_Pin = LCD12864_CS2_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
}
void LCD_GPIO_Config(void)
{
GPIO_InitTypeDef LCD_Struct;
RCC_APB2PeriphClockCmd(LCD12864_Periph,ENABLE);
LCD_Struct.GPIO_Mode = GPIO_Mode_Out_OD;
LCD_Struct.GPIO_Speed = GPIO_Speed_50MHz;
LCD_Struct.GPIO_Pin = LCD12864_DATA_GPIO;
GPIO_Init(LCD12864_GPIO,&LCD_Struct);
}
void LCD_Init(void) //lcd初始化
{
LCD_GPIO_Config();
LCD_FUNCTION_Config();
LCD12864_RES_0;
delay_ms(10);
LCD12864_RES_1;
delay_ms(50);
LCD_CMD_DIS(ON);
LCD_INITIAL_COLUNM(INITIAL_COLUNM);
}
void LCD_GPIO_MASK(u8 data) //数据掩码包装
{
u16 mask;
mask = GPIO_ReadOutputData(LCD12864_GPIO) & 0XFF00 ;
mask = mask | data ;
GPIO_Write(LCD12864_GPIO,mask);
}
void LCD_CMD_BUSY(void) //忙检测
{
LCD12864_RS_CMD;
LCD12864_RW_R;
LCD12864_E_1;
LCD_GPIO_MASK(0xFF);
while(1)
{
LCD12864_E_0;
delay_us(2);
LCD12864_E_1;
if(!(GPIO_ReadInputData(LCD12864_GPIO)&CMD_BUSY))
break;
}
LCD12864_E_0;
}
//parameter: ON/OFF
void LCD_CMD_DIS(u8 Switch)
{
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
if(Switch)
LCD_GPIO_MASK(CMD_DIS_ON);
else
LCD_GPIO_MASK(CMD_DIS_OFF);
delay_us(2);
LCD12864_E_0;
}
void LCD_DIS_SELECT(u8 select) //0全灭 1左屏 2右屏 3全屏
{
select%=4;
switch(select)
{
case DIS_RIGHT:
LCD12864_CS2_ON;
LCD12864_CS1_OFF;
break;
case DIS_LEFT:
LCD12864_CS2_OFF;
LCD12864_CS1_ON;
break;
case DIS_ALL:
LCD12864_CS2_ON;
LCD12864_CS1_ON;
break;
case DIS_NONE:
LCD12864_CS2_OFF;
LCD12864_CS1_OFF;
break;
}
}
//指令起始行
//parameter: 0-63
void LCD_INITIAL_COLUNM(u8 Colunm)
{
Colunm%=64;
Colunm = 64 - Colunm;
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
Colunm = CMD_COLUNM|Colunm;
LCD_GPIO_MASK(Colunm);
delay_us(2);
LCD12864_E_0;
}
//指令写入数据显示列
//parameter: 0-128
void LCD_CMD_Line(u8 Line)
{
Line %= 128;
if(Line<64)
{
LCD_DIS_SELECT(DIS_LEFT);
}
else
{
LCD_DIS_SELECT(DIS_RIGHT);
}
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
Line = CMD_LINE|Line;
LCD_GPIO_MASK(Line);
delay_us(2);
LCD12864_E_0;
}
//指令写入数据显示页
//parameter: 0-7
void LCD_CMD_PAGE(u8 Page)
{
Page%=8;
LCD_CMD_BUSY();
LCD12864_RS_CMD;
LCD12864_RW_W;
LCD12864_E_1;
Page = CMD_PAGE|Page;
LCD_GPIO_MASK(Page);
delay_us(2);
LCD12864_E_0;
}
//写入数据0-7行
void LCD_CMD_COLUNM(u8 Colunm)
{
Colunm%=8;
Colunm=Colunm-INITIAL_COLUNM/8;
LCD_CMD_PAGE(Colunm);
}
//计算数据长度
u8 LCD_NUMS_SIZE(int num)
{
u8 size=0;
if(num==0)
{
size=1;
}else
{
while(num)
{
size++;
num=num/10;
}
}
return size;
}
int LCD_POW(u8 mi) //计算10的次方
{
int di=1;
while(mi--)
{
di=di*10;
}
return di;
}
void LCD_DATA_WRIRE(u8 data) //写一位数据
{
LCD_CMD_BUSY();
LCD12864_RS_DATA;
LCD12864_RW_W;
LCD12864_E_1;
LCD_GPIO_MASK(data);
delay_us(2);
LCD12864_E_0;
}
//显示一个字符 支持小、中尺寸 反侧显示
//parameter: 行0-7 列0-127 data数据 size尺寸SMALL MIDDLE
void LCD_DIS_Char(u8 row,u8 col,u8* data,int size)
{
u8 length=0;
u8 line;
u8 i;
row%=8;
col%=128;
LCD_CMD_Line(col);
line=col-1;
if(size==SMALL)
{
LCD_CMD_COLUNM(row);
while(data[length])
{
for(i=0;i<6;i++)
{
line+=1;
if(line==64)
{
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row);
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row);
}
LCD_DATA_WRIRE(CHAR_SMALL[data[length]-32][i]);
}
length++;
}
}else if(size==MIDDLE)
{
while(data[length])
{
LCD_CMD_COLUNM(row);
for(i=0;i<16;i++)
{
line+=1;
if(i==8)
{
if(line<8)
line=128-(8-line);
else
line-=8;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+1);
}
else if(line==64)
{
LCD_CMD_Line(line);
if(i<8)
{
LCD_CMD_COLUNM(row);
}else if(i>=8)
{
LCD_CMD_COLUNM(row+1);
}
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
if(i<8)
{
LCD_CMD_COLUNM(row);
}else if(i>=8)
{
LCD_CMD_COLUNM(row+1);
}
}
LCD_DATA_WRIRE(CHAR_MIDDLE[data[length]-32][i]);
}
length++;
}
}
}
//写数字 支持小、中尺寸 数字可支持小数 小数位数只包括2位 反侧显示
//parameter: 行0-7 列0-127 data数据 size尺寸SMALL MIDDLE
void LCD_DIS_Number(u8 row,u8 col,float num,int size)
{
u8 line;
u8 length;
u8 i;
u8 flag=0;
float number=0;
row%=8;
col%=128;
length=LCD_NUMS_SIZE((int)num);
LCD_CMD_Line(col);
line=col-1;
if(num-(int)num>0)
{
flag=1;
number=num;
}
if(size==SMALL)
{
LCD_CMD_COLUNM(row);//1行
while(length--)//6位
{
for(i=0;i<6;i++)
{
line+=1;
if(line==64)
{
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row);
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
}
if(flag==2)
{
LCD_DATA_WRIRE(CHAR_SMALL[14][i]);
}else
LCD_DATA_WRIRE(CHAR_SMALL[(int)num/LCD_POW(length)+16][i]);
}
if(flag==2)
{
flag=0;
continue;
}
num=(int)num%LCD_POW(length);
if(flag==1&&length==0)
{
flag=2;
length=3;
num=(int)((number- (int)number)*100);
}
}
}else if(size==MIDDLE)//中尺寸
{
while(length--)
{
LCD_CMD_COLUNM(row);
for(i=0;i<16;i++)
{
line+=1;
if(i==8)
{
if(line<8)
line=128-(8-line);
else
line-=8;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+1);
}
else if(line==64)
{
LCD_CMD_Line(line);
if(i<8)
{
LCD_CMD_COLUNM(row);
}else if(i>=8)
{
LCD_CMD_COLUNM(row+1);
}
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
if(i<8)
{
LCD_CMD_COLUNM(row);
}else if(i>=8)
{
LCD_CMD_COLUNM(row+1);
}
}
if(flag==2)
{
LCD_DATA_WRIRE(CHAR_MIDDLE[14][i]);
}else
LCD_DATA_WRIRE(CHAR_MIDDLE[(int)num/LCD_POW(length)+16][i]);
}
if(flag==2)
{
flag=0;
continue;
}
num=(int)num%LCD_POW(length);
if(flag==1&&length==0)
{
flag=2;
length=3;
num=(int)((number-(int)number)*100);
}
}
}else if(size==LONG)//大尺寸
{
while(length--)
{
LCD_CMD_COLUNM(row);
for(i=0;i<36;i++)
{
line+=1;
if(i==12)
{
if(line<12)
line=128-(12-line);
else
line-=12;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+1);
}else if(i==24)
{
if(line<12)
line=128-(12-line);
else
line-=12;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+2);
}
else if(line==64)
{
LCD_CMD_Line(line);
if(i<12)
{
LCD_CMD_COLUNM(row);
}else if(i>=12&&i<24)
{
LCD_CMD_COLUNM(row+1);
}else if(i>=24)
{
LCD_CMD_COLUNM(row+2);
}
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
if(i<12)
{
LCD_CMD_COLUNM(row);
}else if(i>=12&&i<24)
{
LCD_CMD_COLUNM(row+1);
}else if(i>=24)
{
LCD_CMD_COLUNM(row+2);
}
}
if(flag==2)
{
LCD_DATA_WRIRE(NUMBER_LONG[10][i]);
}else
LCD_DATA_WRIRE(NUMBER_LONG[(int)num/LCD_POW(length)][i]);
}
if(flag==2)
{
flag=0;
continue;
}
num=(int)num%LCD_POW(length);
if(flag==1&&length==0)
{
flag=2;
length=3;
num=(int)((number-(int)number)*100);
}
}
}
}
//写汉字 支持中、大尺寸 data为库
void LCD_DIS_WORD(u8 row,u8 col,u8* data,int size)
{
u8 length=0;
u8 i;
u8 line;
row%=8;
col%=128;
LCD_CMD_Line(col);
line=col-1;
if(size==MIDDLE)
{
while(data[length]!=0)
{
LCD_CMD_COLUNM(row);
for(i=0;i<20;i++)
{
line+=1;
if(i==10)
{
if(line<10)
line=128-(10-line);
else
line-=10;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+1);
}
else if(line==64)
{
LCD_CMD_Line(line);
if(i<10)
{
LCD_CMD_COLUNM(row);
}else if(i>=10)
{
LCD_CMD_COLUNM(row+1);
}
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
if(i<10)
{
LCD_CMD_COLUNM(row);
}else if(i>=10)
{
LCD_CMD_COLUNM(row+1);
}
}
LCD_DATA_WRIRE(WORD_MIDDLE[data[length]-1][i]);
}
length++;
}
}else if(size==LONG)
{
while(data[length]!=0)
{
LCD_CMD_COLUNM(row);
for(i=0;i<32;i++)
{
line+=1;
if(i==16)
{
if(line<16)
line=128-(16-line);
else
line-=16;
LCD_CMD_Line(line);
LCD_CMD_COLUNM(row+1);
}
else if(line==64)
{
LCD_CMD_Line(line);
if(i<16)
{
LCD_CMD_COLUNM(row);
}else if(i>=16)
{
LCD_CMD_COLUNM(row+1);
}
}else if(line==128)
{
line=0;
LCD_CMD_Line(line);
if(i<16)
{
LCD_CMD_COLUNM(row);
}else if(i>=16)
{
LCD_CMD_COLUNM(row+1);
}
}
LCD_DATA_WRIRE(WORD_LONG[data[length]-1][i]);
}
length++;
}
}
}
//图片显示 尺寸64*128
void LCD_DIS_PICTURE(void)
{
u8 row;
u8 col;
for(row=0;row<8;row++)
{
LCD_CMD_Line(0);
LCD_CMD_COLUNM(row);
for(col=0;col<128;col++)
{
if(col==64){
LCD_CMD_Line(64);
LCD_CMD_COLUNM(row);
}
if(col<64)
{
LCD_DATA_WRIRE(BMP_TEST[row*2][col]);
}else if(col>=64)
{
LCD_DATA_WRIRE(BMP_TEST[row*2+1][col-64]);
}
}
}
}
//清除屏幕单独一行
void LCD_CLEAR_COL(u8 row)
{
u8 j;
LCD_DIS_SELECT(DIS_ALL);
LCD_CMD_COLUNM(row);
for(j=0;j<128;j++)
{
LCD_DATA_WRIRE(0xFF);
}
}
//清除全屏
void LCD_CLEAR_ALL(void)
{
u8 i;
u8 j;
LCD_DIS_SELECT(DIS_ALL);
for(i=0;i<8;i++)
{
LCD_CMD_COLUNM(i);
for(j=0;j<128;j++)
{
LCD_DATA_WRIRE(0xFF);
}
}
}
lcd.h
#ifndef __LCD_H
#define __LCD_H
#include "stm32f10x.h"
#include "word.h"
#define LCD12864_GPIO GPIOC
#define LCD12864_Periph RCC_APB2Periph_GPIOC
#define LCD12864_E_GPIO GPIO_Pin_8
#define LCD12864_RW_GPIO GPIO_Pin_9
#define LCD12864_RS_GPIO GPIO_Pin_10
#define LCD12864_CS2_GPIO GPIO_Pin_11
#define LCD12864_CS1_GPIO GPIO_Pin_12
#define LCD12864_RES_GPIO GPIO_Pin_13
#define LCD12864_DATA_GPIO GPIO_Pin_0|GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6|GPIO_Pin_7
#define LCD12864_RES_0 GPIO_ResetBits(LCD12864_GPIO,LCD12864_RES_GPIO)
#define LCD12864_RES_1 GPIO_SetBits(LCD12864_GPIO,LCD12864_RES_GPIO)
#define LCD12864_E_0 GPIO_ResetBits(LCD12864_GPIO,LCD12864_E_GPIO)
#define LCD12864_E_1 GPIO_SetBits(LCD12864_GPIO,LCD12864_E_GPIO)
#define LCD12864_RW_W GPIO_ResetBits(LCD12864_GPIO,LCD12864_RW_GPIO)
#define LCD12864_RW_R GPIO_SetBits(LCD12864_GPIO,LCD12864_RW_GPIO)
#define LCD12864_RS_CMD GPIO_ResetBits(LCD12864_GPIO,LCD12864_RS_GPIO)
#define LCD12864_RS_DATA GPIO_SetBits(LCD12864_GPIO,LCD12864_RS_GPIO)
#define LCD12864_CS1_ON GPIO_ResetBits(LCD12864_GPIO,LCD12864_CS1_GPIO)
#define LCD12864_CS1_OFF GPIO_SetBits(LCD12864_GPIO,LCD12864_CS1_GPIO)
#define LCD12864_CS2_ON GPIO_ResetBits(LCD12864_GPIO,LCD12864_CS2_GPIO)
#define LCD12864_CS2_OFF GPIO_SetBits(LCD12864_GPIO,LCD12864_CS2_GPIO)
//开启或关闭
#define ON 1
#define OFF 0
//LCD命令
#define CMD_DIS_ON 0X3F
#define CMD_DIS_OFF 0X3E
#define CMD_BUSY 0X80
#define CMD_COLUNM 0XC0
#define CMD_LINE 0X40
#define CMD_PAGE 0XB8
//显示屏幕选择
#define DIS_NONE 0
#define DIS_LEFT 1
#define DIS_RIGHT 2
#define DIS_ALL 3
//尺寸
#define SMALL 1
#define MIDDLE 2
#define LONG 3
//方向选择
#define UP 1
#define DOWN 2
//内部处理函数
void LCD_CMD_DIS(u8 Switch); //开关函数
void LCD_CMD_COLUNM(u8 Colunm);//指定初始行
void LCD_CMD_Line(u8 Line); //写入列
void LCD_CMD_COLUNM(u8 Colunm); //写入页
void LCD_INITIAL_COLUNM(u8 Colunm);//初始行
void LCD_DATA_WRIRE(u8 data); //写一位数据
void LCD_CMD_PAGE(u8 Page); //初始页
//外部调用函数
void LCD_Init(void); //初始化
void LCD_DIS_Char(u8 row,u8 col,u8* data,int size);//显示字符
void LCD_MODE_ROLL(u8 path,u8 step,u8 direction,u16 delay);//滚动模式
void LCD_DIS_Number(u8 row,u8 col,float num,int size);//显示数字
void LCD_CLEAR_COL(u8 row);//清零一行
void LCD_CLEAR_ALL(void);//清屏
void LCD_DIS_WORD(u8 row,u8 col,u8* data,int size);//写字
void LCD_DIS_PICTURE(void);//显示罗小黑图片
#endif
将编译好的工程文件下载到Proteus电路中进行仿真,点击运行按钮可查看仿真效果,在本任务中,效果如下:
程序运行后,LCD显示数字,字母,汉字,图片等信息。