51单片机嵌入式开发:9、 STC89C52RC 操作LCD1602技巧

STC89C52RC 操作LCD1602技巧

  • 1 代码工程
  • 2 LCD1602使用
    • 2.1 LCD1602字库
    • 2.2 巧妙使用sprintf
    • 2.3 光标显示
    • 2.4 写固定长度的字符
    • 2.5 所以引入固定长度写入方式:
  • 3 LCD1602操作总结


在这里插入图片描述

1 代码工程

承接上文,在原有工程基础上,新建关于lcd1602的c和h文件,并在includes.h中引用,并添加头文件:

#include<intrins.h> //汇编指令
#include<stdio.h> 	//标准输入输出

整体工程如下:

在这里插入图片描述

各个文件代码如下:

//main.c文件

#include "includes.h"



/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void delay_us(unsigned int us)//delay us
{
	while(us--)
	{
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}
}

/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void delay_ms(unsigned int Ms)//delay us
{
	while(--Ms)
	{
		delay_us(1000);
	}
}

/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
	EA=0;
	//初始化定时器0
	sys_timer0_init();
	//初始化定时器1
	sys_timer1_init();
	//初始化定时器2
	sys_timer2_init();
	
	sys_wdog_init();
	
	//外部中断初始化
	sys_exit_init();
	
	LCD_init();
	
	//8个指示灯的操作
	sys_led();
	sys_led_test();
	sys_led_test1();
	
	sys_ledtube_on1();
	sys_ledtube_on2();
	
	//主循环中添加其他需要一直工作的程序
	sys_keynum_ledon(sys_key_single());
	sys_keynum_ledon(sys_key_board());
	
	EA=1;
	
	P1=0x55;       //P1口初始值,预设指示灯状态,测试引脚
	
	sys_lcd1602_test1();
	sys_lcd1602_test2();
	sys_lcd1602_test3();
	while (1)
	{
		clr_wdg();
	}
}

//c51_gpio.c文件

#include "includes.h"


void sys_led(void)
{
	P1 = 0xFF;		//P1口全部为高电平,对应的LED灯全灭掉,ff换算成二进制是 1111 1111
	P1 = 0x00;		//P1口全部为低电平,对应的LED灯全亮起,ff换算成二进制是 0000 0000
	

}


/********************************************************
函数名称:sys_led_test
函数功能:IO口高低电平测试
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_led_test(void)
{	
	bit tmp = 0;//中间变量用于获取io口状态
	//控制4个引脚输出
	P10 = 1;
	P11 = 0;
	P12 = 0;
	P13 = 1;
	
	//用另外四个IO口获取状态并测试(指示灯显示)
	tmp = P10;
	P14 = tmp;
	
	tmp = P11;
	P15 = tmp;
	
	tmp = P12;
	P16 = tmp;
	
	tmp = P13;
	P17 = tmp;
	
	
}

/********************************************************
函数名称:sys_led_test
函数功能:led流水灯
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_led_test1(void)
{
//	delay(30000);//延时程序
	P1<<=1;      //左移一位 该语句等效于 P1=P1<<1
	P1|=0x01;    //最后一位补1,该语句等效于 P1=P1|0x01 符号"|"表示"或"
	if(P1==0xFF) //检测是否移到最左端?"=="表示检测符号2端的值是否相等
	{ 
//		delay(30000);
		P1=0xfe; //重新赋值
	}
}

//c51_ledtube.c文件

#include "includes.h"

// 显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态
unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,\
		                  	 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F



/********************************************************
函数名称:sys_ledtube_on1
函数功能:点亮一个数码管全为亮起来
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_ledtube_on1(void)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=0xFF;//取显示数据,段码
	P2=0;  	//取位码
}

/********************************************************
函数名称:sys_ledtube_on2
函数功能:显示一组数据
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
static unsigned char ledtube_cnt = 0;
void sys_ledtube_on2(void)
{
	ledtube_cnt++;
	if(ledtube_cnt>7)
	{
		ledtube_cnt = 0;
	}
	P0 = 0x00;				//防止切换数码管瞬间有虚影出现
	P2 = 0x00;
	P0 = EL[ledtube_cnt];	//取显示数据,段码
	P2 = ledtube_cnt;  		//取位码
	
	//根据人眼适应虚影缓冲时间为50ms左右
	//我们调整delay在500以下可以看到明显的看起来是一串数据一起显示
	delay(100); 			
}


/********************************************************
函数名称:sys_keynum_ledon
函数功能:显示按键数值
入口参数:按键数值
出口参数:
修    改:
内    容:
********************************************************/
void sys_keynum_ledon(unsigned char num)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=EL[num];//取显示数据,段码
	P2=0;  	//取位码
}

//c51_key.c文件

#include "includes.h"

bit key1=0;   //定义按键位置
bit key2=0;
bit key3=0;
bit key4=0;


/********************************************************
函数名称:sys_key_single
函数功能:按键检测,带有消抖策略
入口参数:
出口参数:按键数值
修    改:
内    容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
	key1=P30;   //定义按键位置
	key2=P31;
	key3=P32;
	key4=P33;

	if(!key1)  //按下相应的按键,数码管显示相应的码值
	{
		delay(1000);
		if(!key1)
		{
			key1_history = 1;
			return 1;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key2)
	{
		delay(1000);
		if(!key2)
		{
			key1_history = 2;
			return 2;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key3)
	{
		delay(1000);
		if(!key3)
		{
			key1_history = 3;
			return 3;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key4)
	{
		delay(1000);
		if(!key4)
		{
			key1_history = 4;
			return 4;
		}
		else
		{
			return key1_history;
		}
	}
	else
	{
		return key1_history;
	}
	
}

unsigned char sys_key_board(void)
{
	unsigned char key = 0x00;
	unsigned char num = 0x00;
	key=keyscan();  //调用键盘扫描
	if(key == 0xFF)
	{
		num = key1_history;
	}
	else
	{
		switch(key)
		{
			case 0xee:num = 0x0;break;//0按下相应的键显示相对应的码值
			case 0xde:num = 0x1;break;//1 按下相应的键显示相对应的码值 
			case 0xbe:num = 0x2;break;//2
			case 0x7e:num = 0x3;break;//3
			case 0xed:num = 0x4;break;//4
			case 0xdd:num = 0x5;break;//5
			case 0xbd:num = 0x6;break;//6
			case 0x7d:num = 0x7;break;//7
			case 0xeb:num = 0x8;break;//8
			case 0xdb:num = 0x9;break;//9
			case 0xbb:num = 0xA;break;//a
			case 0x7b:num = 0xB;break;//b
			case 0xe7:num = 0xC;break;//c
			case 0xd7:num = 0xD;break;//d
			case 0xb7:num = 0xE;break;//e
			case 0x77:num = 0xF;break;//f
			default:num = key1_history; break;
		}
		
		key1_history = num;
	}
	return num;
}


/*------------------------------------------------
              键盘扫描程序
------------------------------------------------*/
unsigned char keyscan(void)  //键盘扫描函数,使用行列反转扫描法
{
	unsigned char cord_h,cord_l;//行列值中间变量
	P3=0x0f;            //行线输出全为0
	cord_h=P3&0x0f;     //读入列线值
	if(cord_h!=0x0f)    //先检测有无按键按下
	{
		delay(100);        //去抖
		if(cord_h!=0x0f)
		{
			cord_h=P3&0x0f;  //读入列线值
			P3=cord_h|0xf0;  //输出当前列线值
			cord_l=P3&0xf0;  //读入行线值
			return(cord_h+cord_l);//键盘最后组合码值
		}
	}
	return(0xff);     //返回该值
}

//c51_timer.c文件

#include "includes.h"




/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer0_init(void)
{
	TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
	TH0=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
	TL0=0x00;
	//EA=1;            //总中断打开 等最后一个中断打开
	//ET0=1;           //定时器中断打开
	TR0=1;           //定时器开关打开
}

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer1_init(void)
{
	TMOD |= 0x20;	  //使用模式2,	     
	TH1=0x05;	      //给定初值,这里使用定时器最大值从5开始计数一直到255溢出
	TL1=0x00;
	//EA=1;            //总中断打开
	//ET1=1;           //定时器中断打开
	TR1=1;           //定时器开关打开
}


/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer2_init(void)
{
  RCAP2H = 0/256;//
  RCAP2L = 0/256;
  //ET2=1;                     //打开定时器中断
  //EA=1;                      //打开总中断
  TR2=1;                     //打开定时器开关
}




void sys_wdog_init(void)
{ 
	//WDT_CONTR = 0x35;
}

void clr_wdg(void)
{
	//WDT_CONTR = 0x35;
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
	TH0=0x00;		  //重新赋值
	TL0=0x00;

	//sys_led_test1(); //流水灯操作
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3
{

	//sys_led_test1(); //流水灯操作
	
}	




/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer2_isr(void) interrupt 5//定时器2中断
{
    TF2=0;
    //sys_led_test1(); //流水灯操作
}

//c51_exit.c文件

#include "includes.h"




void sys_exit_init(void)
{
	
	EX0=1;         //外部中断0开
	//IT0=0;         //电平触发
	IT0=1;         //边沿触发
	
	EX1=1;         //外部中断1开
	//IT1=0;         //电平触发
	IT1=1;         //边沿触发,IT1=0表示电平触发
}


/*------------------------------------------------
                 外部中断程序
------------------------------------------------*/
void Exit0_isr(void) interrupt 0
{
	//在此处可以添加去抖动程序,防止按键抖动造成错误
	//P1=~P1;         
}

/*------------------------------------------------
                 外部中断程序
------------------------------------------------*/
void Exit1_isr(void) interrupt 2
{
	//在此处可以添加去抖动程序,防止按键抖动造成错误
	//P1=~P1;
}

//c51_lcd1602.c文件

#include "includes.h"

#include <string.h>

/******************************************************************/
/*                   写入命令函数                                 */
/******************************************************************/
void LCD_write_com(unsigned char com) 
{  
	RS_CLR; 
	RW_CLR; 
	EN_SET; 
	P0 = com; 
	delay_us(5); 
	EN_CLR;
}

/******************************************************************/
/*                   写入数据函数                                 */
/******************************************************************/
void LCD_write_Data(unsigned char Data) 
{ 
	RS_SET; 
	RW_CLR; 
	EN_SET; 
	P0 = Data; 
	delay_us(5); 
	EN_CLR;
}
/******************************************************************/
/*                   清屏函数                                     */
/******************************************************************/
void LCD_clear(void) 
{ 
	LCD_write_com(0x01); 
	delay_ms(5);
}

/******************************************************************/
/*                   初始化函数                                   */
/******************************************************************/
void LCD_init(void) 
{
	LCD_write_com(0x38);    /*显示模式设置*/ 
	delay_ms(5); 
	LCD_write_com(0x38); 
	delay_ms(5); 
	LCD_write_com(0x38); 
	delay_ms(5); 
	LCD_write_com(0x38);  
	LCD_write_com(0x08);    /*显示关闭*/ 
	LCD_write_com(0x01);    /*显示清屏*/ 
	LCD_write_com(0x06);    /*显示光标移动设置*/ 
	delay_ms(5); 
	LCD_write_com(0x0C);    /*显示开及光标设置*/
}
 
/******************************************************************/
/*                   写入字符串函数                                */
/*      X:第几列 Y:第几行  *s字符串为空时跳出                      */
/******************************************************************/
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
	{     
		LCD_write_com(0x80 + x);     
	}
	else 
	{     
		LCD_write_com(0xC0 + x);     
	}        
	while (*s) 
	{     
		LCD_write_Data( *s);     
		s ++;     
	}
}

 
/******************************************************************/
/*                   写入字符串函数                                */
/*      X:第几列 Y:第几行  *s字符串为空时跳出                      */
/******************************************************************/
void LCD_write_strl(unsigned char x,unsigned char y,unsigned char *s,unsigned length) 
{     
	unsigned char cnt = 0;
	if (y == 0) 
	{     
		LCD_write_com(0x80 + x);     
	}
	else 
	{     
		LCD_write_com(0xC0 + x);     
	}
       
	while(length--)
	{     
		LCD_write_Data( *s);     
		s ++;
		cnt++;
		
	}
	
	while(cnt<5)
	{
		
		LCD_write_Data(' ');
		cnt++;
	}
}

/******************************************************************/
/*                   写入字节函数                                  */
/*      X:第几列 Y:第几行  Data字符                               */
/******************************************************************/
void LCD_write_char(unsigned char x,unsigned char y,unsigned char Data) 
{     
	if (y == 0) 
	{     
		LCD_write_com(0x80 + x);     
	}    
	else 
	{     
		LCD_write_com(0xC0 + x);     
	}        
	LCD_write_Data( Data);  
}

void sys_lcd1602_test1(void)
{
	LCD_clear();
	
	LCD_write_char(1,0,'E');
	LCD_write_str(2,0,"mail:");
	LCD_write_str(1,1,"xxxshow@163.com");

}


void sys_lcd1602_test2(void)
{
	char Test2[16]="";
	int i=8;
	float j=3.5;
	delay_ms(100);
	
	//LCD_clear();
	
	sprintf(Test2,"N:%d,float:%.2f ",i,j);
	LCD_write_str(1,1,Test2);
	delay_ms(100);
	j = 3.61;
	sprintf(Test2,"%.2f",j);
	LCD_write_str(12,1,Test2);

}


void sys_lcd1602_test3(void)
{
	unsigned char Test2[5]="";
	
	LCD_clear();
	
	sprintf(Test2,"A:");
	LCD_write_str(0,0,Test2);
	sprintf(Test2,"B:");
	LCD_write_str(8,0,Test2);
	sprintf(Test2,"C:");
	LCD_write_str(0,1,Test2);
	sprintf(Test2,"D:");
	LCD_write_str(8,1,Test2);
	delay_ms(100);

	
	sprintf(Test2,"12345");
	LCD_write_strl(2,0,Test2,strlen(Test2));
	
	sprintf(Test2,"54321");
	LCD_write_strl(10,0,Test2,strlen(Test2));
	
	sprintf(Test2,"QWERT");
	LCD_write_strl(2,1,Test2,strlen(Test2));
	
	sprintf(Test2,"TREWQ");
	LCD_write_strl(10,1,Test2,strlen(Test2));
	
	delay_ms(100);
	
	sprintf(Test2,"111");
	LCD_write_strl(2,0,Test2,strlen(Test2));
	
	sprintf(Test2,"55");
	LCD_write_strl(10,0,Test2,strlen(Test2));
	
	sprintf(Test2,"QW");
	LCD_write_strl(2,1,Test2,strlen(Test2));
	
	sprintf(Test2,"T");
	LCD_write_strl(10,1,Test2,strlen(Test2));
	
	
	delay_ms(100);
}

//includes.h文件

#ifndef __INCLUDES_H__
#define __INCLUDES_H__

//#include<reg52.h> 

#include<intrins.h> //汇编指令
#include<stdio.h> 	//标准输入输出

//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"

//应用层头文件
#include "c51_gpio.h"
#include "c51_ledtube.h"
#include "c51_key.h"
#include "c51_timer.h"
#include "c51_exit.h"
#include "c51_lcd1602.h"


extern void delay(unsigned int cnt);
extern void delay_us(unsigned int us);//delay us;
extern void delay_ms(unsigned int Ms);//delay Ms;


#endif

//c51_ledtube.h文件

#ifndef __C51_LEDTUBE_H__
#define __C51_LEDTUBE_H__


extern unsigned char const EL[];

extern void sys_ledtube_on1(void);
extern void sys_ledtube_on2(void);

extern void sys_keynum_ledon(unsigned char num);


#endif

//c51_gpio.h文件

#ifndef __C51_GPIO_H__
#define __C51_GPIO_H__

extern void sys_led(void);
extern void sys_led_test(void);
extern void sys_led_test1(void);

#endif

//c51_key.h文件

#ifndef __C51_KEY_H__
#define __C51_KEY_H__


extern bit key1;   //定义按键位置
extern bit key2;
extern bit key3;
extern bit key4;


extern unsigned char sys_key_single(void);

extern unsigned char sys_key_board(void);
extern unsigned char keyscan(void);  //键盘扫描函数,使用行列反转扫描法

#endif

//c51_timer.h文件

#ifndef __C51_TIMER_H__
#define __C51_TIMER_H__





extern void sys_timer0_init(void);
extern void Timer0_isr(void);
extern void sys_timer1_init(void);
extern void Timer1_isr(void);
extern void sys_timer2_init(void);
extern void Timer2_isr(void);

extern void sys_wdog_init(void);
extern void clr_wdg(void);

#endif

//c51_exit.h文件

#ifndef __C51_EXIT_H__
#define __C51_EXIT_H__

extern void sys_exit_init(void);
extern void Exit0_isr(void);
extern void Exit1_isr(void);



#endif

//c51_lcd1602.h文件

#ifndef __C51_LCD1602_H__
#define __C51_LCD1602_H__



#include "STC89C5xRC_RDP.h"


//定义宏定义

sbit RS = P2^4;   //定义端口 
sbit RW = P2^5;
sbit EN = P2^6;

#define RS_CLR RS=0 
#define RS_SET RS=1
#define RW_CLR RW=0 
#define RW_SET RW=1 
#define EN_CLR EN=0
#define EN_SET EN=1


extern void LCD_write_com(unsigned char com) ;
extern void LCD_write_Data(unsigned char Data) ;
extern void LCD_clear(void) ;
extern void LCD_init(void) ;
extern void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) ;
extern void LCD_write_strl(unsigned char x,unsigned char y,unsigned char *s,unsigned length) ;


extern void LCD_write_char(unsigned char x,unsigned char y,unsigned char Data) ;
extern void sys_lcd1602_test1(void);
extern void sys_lcd1602_test2(void);
extern void sys_lcd1602_test3(void);


#endif

2 LCD1602使用

2.1 LCD1602字库

表所示是字符库的内容、字符码和字形的对应关系。例如“A”的字符码 为 41(HEX),“B”的字符码这 42(HEX)。列项是高四位,横向是低四位。根据表中可知,前125个字符为ASCII码表中的字符。剩余的其他字符我们不经常使用。
在使用125个ASCII码时,直接写入字符即可。

在这里插入图片描述

2.2 巧妙使用sprintf

sprintf 是一个格式化字符串的函数,它可以将格式化的数据输出到一个字符串中。它的用法类似于其他编程语言中的 printf 函数。
以下是 sprintf 的基本用法:
c
复制

int sprintf(char *str, const char *format, ...);

• str 是一个字符数组(字符串),用于接收格式化后的输出结果。
• format 是一个格式化字符串,用于指定输出的格式。
• … 是可变参数,用于提供要格式化的数据。根据 format 中的格式说明符,将可变参数的值格式化并插入到输出字符串中。
下面是一个简单的示例,演示了 sprintf 的用法:
c
复制

#include <stdio.h>

int main() {
    char str[100];
    int num = 10;
    float f = 3.14;

    sprintf(str, "Number: %d, Float: %.2f", num, f);
    printf("Formatted string: %s\n", str);

    return 0;
}

输出结果:
复制

Formatted string: Number: 10, Float: 3.14

在上面的示例中,我们将整数 num 和浮点数 f 格式化并插入到字符串 str 中,使用 %d 和 %.2f 分别表示整数和带两位小数的浮点数。
sprintf 还支持其他格式说明符,例如 %s 表示字符串,%c 表示字符, %x 表示十六进制数等。你可以根据需要使用适当的格式说明符进行格式化。请注意,在使用 sprintf 时要确保目标字符串 str 能够容纳足够的空间,以避免溢出。

2.3 光标显示

在使用光标闪烁显示时,我们将

	LCD_write_com(0x0C);    /*显示开及光标设置*/
改为

	LCD_write_com(0x0);    /*显示开及光标设置*/

注意事项,不能写满16个字符,因为,LCD1602最宽是16个字符,光标配置成自动加1的方式,无法在屏幕上显示出来光标,但是一般也不用光标进行显示;

2.4 写固定长度的字符

因为,LCD1602写入相同的位置可以覆盖历史,但是如果上一次数据与本次数据占用屏幕上的位置不同,就会导致上一次的显示无法覆盖,结果就会显示混乱的情况。

第一次显示:

void sys_lcd1602_test1(void)
{
	LCD_clear();
	
	LCD_write_char(1,0,'E');
	LCD_write_str(2,0,"mail:");
	LCD_write_str(1,1,"xxxshow@163.com");

}

第二次显示:

void sys_lcd1602_test2(void)
{
	char Test2[16]="";
	int i=8;
	float j=3.5;
	delay_ms(100);
	
	//LCD_clear();
	
	sprintf(Test2,"N:%d,%.2f",i,j);
	LCD_write_str(1,1,Test2);
}

显示结果

在这里插入图片描述

2.5 所以引入固定长度写入方式:

(1)注意代码陷阱:

/******************************************************************/
/*                   写入字符串函数                                */
/*      X:第几列 Y:第几行  *s字符串为空时跳出                      */
/******************************************************************/
void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) 
{     
	if (y == 0) 
	{     
		LCD_write_com(0x80 + x);     
	}
	else 
	{     
		LCD_write_com(0xC0 + x);     
	}        
	while (*s) //注意:会打印出来最后一个空字符,导致后边的数据有问题分块的时候,注意此处。
	{     
		LCD_write_Data( *s);     
		s ++;     
	}
}

(2)固定长度写入方式代码:

/******************************************************************/
/*                   写入字符串函数                                */
/*      X:第几列 Y:第几行  *s字符串为空时跳出                      */
/******************************************************************/
void LCD_write_strl(unsigned char x,unsigned char y,unsigned char *s,unsigned length) 
{     
	unsigned char cnt = 0;
	if (y == 0) 
	{     
		LCD_write_com(0x80 + x);     
	}
	else 
	{     
		LCD_write_com(0xC0 + x);     
	}
       
	while(length--)
	{     
		LCD_write_Data( *s);     
		s ++;
		cnt++;
		
	}
	
	while(cnt<5)
	{
		
		LCD_write_Data(' ');
		cnt++;
	}
}

使用情况:

void sys_lcd1602_test3(void)
{
	unsigned char Test2[5]="";
	
	LCD_clear();
	
	sprintf(Test2,"A:");
	LCD_write_str(0,0,Test2);
	sprintf(Test2,"B:");
	LCD_write_str(8,0,Test2);
	sprintf(Test2,"C:");
	LCD_write_str(0,1,Test2);
	sprintf(Test2,"D:");
	LCD_write_str(8,1,Test2);
	delay_ms(100);

	
	sprintf(Test2,"12345");
	LCD_write_strl(2,0,Test2,strlen(Test2));
	
	sprintf(Test2,"54321");
	LCD_write_strl(10,0,Test2,strlen(Test2));
	
	sprintf(Test2,"QWERT");
	LCD_write_strl(2,1,Test2,strlen(Test2));
	
	sprintf(Test2,"TREWQ");
	LCD_write_strl(10,1,Test2,strlen(Test2));
	
	delay_ms(100);
	
	sprintf(Test2,"111");
	LCD_write_strl(2,0,Test2,strlen(Test2));
	
	sprintf(Test2,"55");
	LCD_write_strl(10,0,Test2,strlen(Test2));
	
	sprintf(Test2,"QW");
	LCD_write_strl(2,1,Test2,strlen(Test2));
	
	sprintf(Test2,"T");
	LCD_write_strl(10,1,Test2,strlen(Test2));
	
	
	delay_ms(100);
}

最终显示结果如下,空白处不会被覆盖。

在这里插入图片描述

3 LCD1602操作总结

这些是 LCD1602 操作的一些常见技巧。具体的操作步骤和函数会因你使用的具体驱动程序、编程语言和平台而有所不同。因此,在使用 LCD1602 时,请参考相关文档或教程,了解你所使用的具体库和函数的使用方法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端项目本地的node_modules直接上传到服务器上无法直接使用(node-sasa模块报错)

跑 jekins任务的服务器不能连接外网下载依赖包&#xff0c;就将本地下载的 node_modules直接上传到服务器上&#xff0c;但是运行时node-sass模块报错了ERROR in Missing binding /root/component/node_modules/node-sass/vendor/linux-x64-48/binding.node >> 报错信息类…

深度学习设计模式之代理模式

文章目录 前言一、介绍二、详细分析1.核心组成2.实现步骤3.代码示例4.优缺点优点缺点 5.使用场景 总结 前言 代理模式是结构型设计模式&#xff0c;主要是为其他对象提供一种代理以控制对这个对象的访问。 一、介绍 代理模式&#xff08;Proxy Pattern&#xff09;是一种常用…

快速在springboot项目中应用EasyExcel

一、介绍 EasyExcel 是阿里巴巴开源的简化Excel文件读取和写入的开源库。主要的特点如下&#xff1a; 简单易用的API&#xff1a;EasyExcel提供简单API&#xff0c;隐藏处理Excel文件的底层细节。注解支持&#xff1a;支持使用注解将Java对象映射到Excel列&#xff0c;便于Ja…

《梦醒蝶飞:释放Excel函数与公式的力量》11.3 ISTEXT函数

第11章&#xff1a;信息函数 第三节 11.3 ISTEXT函数 11.3.1 简介 ISTEXT函数是Excel中的一个信息函数&#xff0c;用于检查指定单元格中的内容是否为文本。如果单元格内容是文本&#xff0c;则返回TRUE&#xff1b;否则返回FALSE。ISTEXT函数在数据验证、条件格式化和逻辑判…

【UE5.1】Chaos物理系统基础——06 子弹破坏石块

前言 在前面我们已经完成了场系统的制作&#xff08;【UE5.1】Chaos物理系统基础——02 场系统的应用_ue5&#xff09;以及子弹的制作&#xff08;【UE5.1 角色练习】16-枪械射击——瞄准&#xff09;&#xff0c;现在我们准备实现的效果是&#xff0c;角色发射子弹来破坏石柱。…

如何利用扩散实现结构功能动态调控?

如何利用扩散实现结构功能动态调控&#xff1f; 利用扩散机制在生物打印结构内部创建特定空间梯度的方法&#xff0c;主要分为两个方面&#xff1a; 1. 形成形态发生素梯度 形态发生素的作用&#xff1a;形态发生素是能够诱导细胞响应的信号分子&#xff0c;常用于生物打印结…

探索GitHub上的两个革命性开源项目

在数字世界中&#xff0c;总有一些项目能够以其创新性和实用性脱颖而出&#xff0c;吸引全球开发者的目光。今天&#xff0c;我们将深入探索GitHub上的两个令人惊叹的开源项目&#xff1a;Comic Translate和GPTPDF&#xff0c;它们不仅改变了我们处理信息的方式&#xff0c;还极…

Debezium日常分享系列之:Debezium 3.0.0.Alpha1 Released

Debezium日常分享系列之&#xff1a;Debezium 3.0.0.Alpha1 Released 一、重大改变Java 和 Maven 要求已更改 二、新的特征和提高MongoDB 三、更多内容 Debezium 3 的第一个预发布版本 3.0.0.Alpha1。这个版本虽然比正常的预版本要小&#xff0c;但高度关注几个关键点&#xff…

docker中mysql设置lower_case_table_names配置的坑

前沿 今天在使用flowable流程框架的时候&#xff0c;遇到一个问题。需要配置MySQL数据库以实现表名大小写不敏感。本以为这是一个简单的任务&#xff0c;却耗费了我两个多小时的时间。 docker容器中修改配置&#xff0c;重启不成功 我们前提是容器中的mysql中已经有很多数据…

Web安全:SQL注入

一、SQL注入三要素 1、用户可以对输入的参数值进行修改。 2、后端不对用户输入的参数值进行严格过滤。 3、用户修改后的参数值可以被带入后端中成功执行&#xff0c;并返回一定结果。 二、SQL注入原理 简单来说&#xff0c;用户输入的值会被插入到SQL语句中&#xff0c;然后…

Milvus 核心设计(1) ---- 数据一致性的等级及使用场景

目录 背景 Milvus的数据一致性 设置数据一致性等级 等级类型 PACELC定理 level 详细解释 Strong Bounded staleness Session Eventually 总结 背景 分布式上的可扩展性是个比较重要的concept。Chroma 核心之前写过了,他的最大优势在于轻量级且好用。Milvus相对Ch…

tkinter-TinUI-xml实战(11)多功能TinUIxml编辑器

引言 在TinUIXml简易编辑器中&#xff0c;我们通过TinUI搭建了一个简易的针对TinUIXml布局的编辑器&#xff0c;基本掌握了TinUIXml布局和TinUIXml的导入与导出。现在&#xff0c;就在此基础上&#xff0c;对编辑器进行升级。 本次升级的功能&#xff1a; 更合理的xml编辑与…

大众汽车入职SHL在线测评、英语口语、招聘笔试如何通过、考点分析|备考建议

大众汽车入职在线测验真题考点分析&#xff0c;通过技巧&#xff1f; 大众汽车集团&#xff08;中国&#xff09;在招聘过程中&#xff0c;认知能力测试是评估候选人是否适合某个职位的重要环节。候选人会收到带有线上测评链接的邮件&#xff0c;测评包括胜任力潜力测试(Compe…

多输入多输出 | Matlab实现Transformer多输入多输出预测

多输入多输出 | Matlab实现Transformer多输入多输出预测 目录 多输入多输出 | Matlab实现Transformer多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现Transformer多输入多输出预测&#xff08;完整源码和数据&#xff09; 1.da…

CSS选择器:基本选择器、复合选择器、伪类选择器、伪元素选择器

CSS选择器包含&#xff1a;基本选择器、复合选择器、伪类选择器、伪元素选择器。 选择器是选择标签的一种方式&#xff0c;例如 ID 选择器就是通过 ID 选择标签的&#xff0c;类选择器就是通过类名选择标签的。 在 CSS3 中有很多类型的选择器&#xff0c;如下是《W3school》提…

Android 使用 Debug.startMethodTracing 分析方法耗时

参考 Generate Trace Logs by Instrumenting Your App 官网提供了 trace 工具来分析方法耗时。 生成 trace 文件 package com.test.luodemo.trace;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.os.Debug; import android.uti…

昇思25天学习打卡营第13天|基于MindNLP+MusicGen生成自己的个性化音乐

关于MindNLP MindNLP是一个依赖昇思MindSpore向上生长的NLP&#xff08;自然语言处理&#xff09;框架&#xff0c;旨在利用MindSpore的优势特性&#xff0c;如函数式融合编程、动态图功能、数据处理引擎等&#xff0c;致力于提供高效、易用的NLP解决方案。通过全面拥抱Huggin…

[C++]——同步异步日志系统(4)

同步异步日志系统 一、日志等级模块设计二、日志消息类设计 一、日志等级模块设计 定义出日志系统所包含的所有日志等级分别为&#xff1a;&#xff08;7个等级&#xff09; UNKNOW0&#xff0c;未知等级的日志DRBUG &#xff0c;调试等级的日志INFO &#xff0c;提示等级的日…

企业人事管理系统

1.课设要求描述 【系统描述】软件从登录界面开始&#xff0c;验证用户名与密码后&#xff0c;根据登录用户名权限的不同&#xff0c;打开软件后展示不同的功能模块。软件主要功能模块是人事管理、部门管理、备忘录、员工生日提醒、数据库的维护等。 通过简单分析后&#xf…

STM32串口工作原理

STM32的串口是相当丰富的&#xff0c;功能也很强劲。最多可提供5 路串口&#xff0c;有分数波特率发生器、支持单线光通信和半双工单线通讯、支持LIN、智能卡协议和IrDA SIRENDEC 规范(仅串口3支持)、具有DMA等。 串口最基本的设置&#xff0c;就是波特率的设置。STM32的串口使…