STM32/51单片机实训day6——Proteus8.6版本+ STM32F103驱动LCD12864显示Keil5程序设计

news2024/12/23 19:52:36

内  容:实现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功能仿真


1 LCD12864介绍

        液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。12864字符型液晶是一种专门用来显示字母、数字、符号等点阵型液晶模块,能够同时显示16*2即32个字符。

1.1 引脚功能介绍

        1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线,VCC(15脚)和地线GND(16脚)。各引脚功能如表1。

1.2 RAM 地址映射

        液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,1602的内部显示地址如图1。

图1 LCD1602内部显示地址

1.3 读写操作时序

        通过时序图来操作液晶。时序图可以参考图1-3或是12864芯片手册。由图1-2和图1-3可知,若要传送数据或命令到12864,需要向12864液晶写入数据。所以需要用到写时序。

        其中,RW设置为低电平RW=0,RS依据传命令和数据的不同分别设置为0和1,将需要传输的数据赋值给DB0-DB7,EN设置为高电平。

\bullet延时Tpm(查看芯片手册)

\bulletEN设置为低电平

图1- 3 12864写时序

但是需要注意的是,每次在进行读写操作时,要判断上次数据是否已经传送完成即是否“忙”。判断是否“忙”只需要判断DB7位是否为零,若为零表示空闲,不需要等待。为1表示“忙”,需要等待。由于无法单独读取DB7位,只能将DB0~DB7全部读取出来。读取时序如图1-4所示。

图1-4 12864读时序 

读操作过程与写过程类似,如下:

DB0~DB7的初始化设置为0或是1RW设置为高即读状态

RS设置为低,读命令

EN使能位设置为高,开始读取数据

判断DB7是否为高

EN设置为高,结束读取

​​​​​​​2 电路设计

        本实训项目采用型号为LM016L的LCD显示器件。原理图设计如图4。其中,LM016L中的引脚D0、D1、D2、D3、D4、D4、D5、D6、D7、RS、RW、E分别于STM32中的PB1-PB11引脚相连。

3 代码实现

3.1 LCD12864初始化

        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);
} 

​​​​​​​3.2 写操作函数

        写操作函数分为写命令写数据函数。在写命令和写数据时,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

3.3 部分关键源代码

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  

4 Proteus功能仿真

        将编译好的工程文件下载到Proteus电路中进行仿真,点击运行按钮可查看仿真效果,在本任务中,效果如下:

        程序运行后,LCD显示数字,字母,汉字,图片等信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/124362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全国产龙芯2K0500多功能SoC处理器及其解决方案

龙芯2K0500片内集成单个64位龙架构(LoongArch)LA264处理器核、32KB一级指令缓存、32KB一级数据缓存、512KB二级缓存、32位DDR2/3-1066控制器、2DGPU图形核心、DVO显示接口、两路PCIe2.0、两路SATA2.0、四路USB2.0、一路USB3.0、两路GMAC、PCI总线、彩色黑白打印接口、HDA及其他…

有备无患!DBS高性价比方案助力富途证券备份上云

“某中心受病毒攻击&#xff0c;导致服务中断&#xff0c;线上业务被迫暂停” “某公司员工误操作删库&#xff0c;核心业务数据部分丢失&#xff0c;无法完全找回” “由于服务器断线&#xff0c;某医院信息系统瘫痪近4小时&#xff0c;期间病人无法使用医保卡挂号和结算” …

Talk预告 | 微软高级研究员杨征元:统一的视觉语言模型

本期为TechBeat人工智能社区第467期线上Talk&#xff01; 北京时间12月29日(周四)20:00&#xff0c;微软高级研究员——杨征元的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “统一的视觉语言模型”&#xff0c;届时将从一个统一的角度概述视觉语…

深度循环神经网络

在深度循环神经网络中&#xff0c;隐状态的信息被传递到当前层的下一时间步和下一层的当前时间步。 有许多不同风格的深度循环神经网络&#xff0c; 如长短期记忆网络、门控循环单元、或经典循环神经网络。 这些模型在深度学习框架的高级API中都有涵盖。 总体而言&#xff0c…

第三方库react-redux基础使用 容器UI组件使用 数据管理优化

其实redux并不是React特有的技术 redux是一家独立公司 做出来 适配与目前几大前端主流框架的状态管理工具。 其实 最初 redux也希望码友们用它来管理vue的状态数据 但后面 React官方发现 很多人喜欢在React项目中使用redux 于是 React公司专门做了react-redux这个第三方的库 帮…

【计组】数据通路和流水线设计--《深入浅出计算机组成原理》(三)

课程链接&#xff1a;深入浅出计算机组成原理_组成原理_计算机基础-极客时间 目录 一、建立数据通路 &#xff08;一&#xff09;组合逻辑电路 1、指令周期 2、数据通路 3、CPU所需硬件电路 &#xff08;二&#xff09;时序逻辑电路 1、时序逻辑电路可以解决的问题 二…

Python爬虫进行正则数据解析实战

今天继续给大家介绍Python爬虫相关知识&#xff0c;本文主要内容是Python爬虫进行正则数据解析实战。 一、需求分析 今天&#xff0c;我们尝试使用re正则表达式来对爬取到的页面进行数据解析。需求如下&#xff1a; 针对网页&#xff1a;https://blog.csdn.net/weixin_402282…

第三十二章 数论——组合数详解(1)

第三十二章 数论——组合数的多种求法一、数学基础二、组合数——递推公式1、题目2、思路3、代码三、组合数——快速幂1、问题&#xff1a;2、分析一、数学基础 组合数来自于高中排列组合的知识&#xff1a; 我们从aaa个小球中随机一次性取出bbb个&#xff0c;所有的取法记作…

Numpy学习记录

numpy.ma.ravel 返回一个连续的扁平数组。 参考&#xff1a; numpy中的ravel()方法使用介绍https://blog.csdn.net/weixin_44025103/article/details/125062287 Python numpy.ravel函数方法的使用https://www.cjavapy.com/article/870/ numpy.meshgrid 二维坐标系中,X轴…

图片如何批量重命名?一步一步教会你

爱拍照的小伙伴应该都知道&#xff0c;无论是手机还是相机拍出来的照片&#xff0c;导入电脑后&#xff0c;它的默认名称都是一串长长的字符。不仅让桌面看起来杂乱无章&#xff0c;还会给我们在查找图片时带来诸多的不便。其实我们可以通过软件对这些图片进行批量重命名的&…

线性代数基础----矩阵

秩的理解: 举证的秩的理解: 特征值和特征向量 线性相关和线性无关 向量的拉伸和旋转: 特征值和特征向量: 特征值: 特征向量: 用来描述矩阵的信息 特征向量 和 特征值之间的关系 拳击:方向和力量 特征值和特征向量的物理意义: 表示相关的重要性 特征值和特征向量:进行提…

阳了在家没事干?教大家用python在家做一个万能看视频软件,绝对正经啦~

嗨害大家好鸭&#xff01;我是小熊猫~ 我前阵子不小心阳了&#xff0c;该说不说&#xff0c;真挺难受的 我在家真的就是纸巾热水不离手&#xff0c; 楼下水果店老板娘还说我年轻人身体怎么这么差… 哼我阳过之后我就锻炼去&#xff01;&#xff01;&#xff01; 效果展示 有…

如何删除掉设备和驱动器下百度网盘的图标

电脑安装百度网盘后&#xff0c;在设备和驱动器这里会有百度网盘的图标&#xff0c;如下图所示。 对有强迫症的人来说&#xff0c;这很难受&#xff0c;就一定要想办法删除掉该图标&#xff0c;那么具体怎么操作呢&#xff1f; 你如果在设备和驱动器下右击百度网盘&#xff0c…

12月小报|读小报,涨知识

本期知识小集的主要内容包括&#xff1a;• Flutter桥调用请注意结果反馈• Flutter await代码带来的潜在并发• Flutter FPS 高不代表一定流畅• Flutter新渲染引擎impeller尝鲜Flutter桥调用请注意结果反馈通过桥来拓展Flutter的能力&#xff0c;是非常通用的Flutter开发场景…

Weda创建视图表格

这边我们先创建一个数据集。 在更多操作里面分布这个数据集。 点击编辑&#xff0c;选择视图配置。 在下面这个界面&#xff0c;新建视图。 在操作里面&#xff0c;点击更多&#xff0c;发布这个视图。 我们点击编辑设置视图的第一行&#xff08;表列设置&#xff09;。 点击…

马上又是新的一年了 “跨年倒计时”送给大家

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;跨年倒计时 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入: 林在闪闪发光的…

pytorch 深度学习

第二章 回归问题 即使是最简单的线性回归,由于观测误差的存在,也不可能找到一个满足所有样本的函数。因此,我们退而求其次,寻找到一个满足大部分样本点的直线。那么如何衡量这个呢,我们可以求出所有样本点真实值和预测值的误差,满足总误差最小的就是最好的。 连续值…

年关在即,源站安全如何保障?|ScanV(云监测)重保哨兵值守

2022年&#xff0c;全球重大网络安全事件频发&#xff0c;大规模数据泄露、漏洞利用事件、勒索软件攻击等网络犯罪威胁持续上升。网络安全形势日趋严峻&#xff0c;对政府、党政机关、央企国企业务安全造成严重威胁。据知道创宇云防御2022年截至目前的数据统计&#xff0c;平均…

如何去掉任务栏的英伟达图标,并阻止英伟达服务自启动

进入服务&#xff0c;找到NVIDIA的两个服务项&#xff0c;右键属性&#xff0c;停止服务&#xff0c;英伟达图标自动消失。 再把启动方式改为手动&#xff0c;下次就不会开机自启。

WebGL

1、WebGL介绍 1.1 WebGL不足 效果较差&#xff1a;较于桌面开发API&#xff1a;Direct3D、OpenGL、UE、Unity。 开发成本&#xff1a;熟悉并掌握一定的数据知识&#xff0c;例如&#xff1a;线性代数。 硬件要求&#xff1a;开发及部署系统硬件要求较高&#xff0c;尤其GPU…