使用51单片机控制lcd1602字体显示

部分效果图:

准备工作:

51单片机(BST)+1602显示屏

基础知识:

注:X表示可以是0,也可以是1;

DL 1,

N 1,

F 0,

代码一: 要求显示字母‘a’

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}
main(){
	
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
	// 写入字符a
	Write_DATA('a');
	while(1);
}

效果结果图:

代码优化一下:

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	
// 初始化代码
	LCDinit();
	// 写入字符a
	Write_DATA('a');
	while(1);
}

例2: 从C7的位置显示字符“W”

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	
  //初始化代码
	LCDinit();
	// 指令显示从C7位置开始写字母
	Write_CMD(0xC7);
	// 写入字符W
	Write_DATA('W');
	while(1);
}

例子三,输出“I Love China !”

#include <reg52.h>

sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态

void Write_CMD(unsigned char x){
	int i = 1000;
	// 设置进入命令状态
	RS = 0;
	// 写操作
	RW = 0;
	// 0x01 清屏  0x38 设置 ......等指令内容
	P0 = x;
  // 打开指令读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭指令读写操作控制允许
	E = 0;
}
void Write_DATA(unsigned char x) {
	int i = 1000;
	// 设置进入数据状态
	RS = 1;
	// 写操作
	RW = 0;
	// 数据内容
	P0 = x;
  // 打开数据读写操作控制允许
	E = 1;
	// 等待1秒
	while(i--);
	// 关闭数据读写操作控制允许
	E = 0;
}

// 初始化代码
void LCDinit(void){
  // 清屏
	Write_CMD(0x01);
  // 设置16X2显示,5X7点阵,8位数据接口;
	Write_CMD(0x38);
  // 开显示,显示光标,光标闪烁;
	Write_CMD(0x0f);
	// 地址加1,当写入数据的时候光标右移:
	Write_CMD(0x06);
}

main(){
	int i;
	char a[] = {"I Love China !"};
  //初始化代码
	LCDinit();
  for(i = 0; i < 14; i++){
	  // 指令显示从C1位置开始写字母
		Write_CMD(0xC1 + i);
		// 写入字符
		Write_DATA(a[i]);
	}
	while(1);
}

附官方提供的示例代码:


/**********************BST-V51实验开发板例程************************
*  平台:BST-V51 + Keil U3 + STC89C52
*  名称:LCD1602模块实验
*  公司:深圳市XXXX科技有限公司        
*  日期:2013-11
*  晶振:11.0592MHZ
*  说明:免费开源,不提供源代码分析.
******************************************************************/
//实验目的:
/*-----------------------------------------------
  名称:LCD1602
  内容:通过标准程序静态显示字符
  引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include<string.h>

#define uchar unsigned char

sbit RS = P1^0;   //定义端口 
sbit RW = P1^1;
sbit EN = P2^5;
sbit DU = P2^0;
sbit WE = P2^1;

#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

#define DataPort P0

/*协议定义*/
bit startBit = 0;  				//串口接收开始标志位
bit newLineReceived = 0; 		//串口一帧协议包接收完成
unsigned char inputString[50];  //接收数据协议
/*------------------------------------------------
                 串口初始化函数
------------------------------------------------*/
void init_com(void)
{
	TMOD|=0x20;		   //设T0为方式1,GATE=1;
	SCON=0x50;
	TH1=0xFD;
	TL1=0xFD;
	TR1=1;			   //开启定时器
	//TI=1;
	EA=1;			   //开启总中断
	ES=1;			   //串口中断打开
}


void cmg88()//关数码管,点阵函数
{
	DU=1;  
	P0=0X00;
	DU=0;
}
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
	while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
	 DelayUs2x(245);
 }
}
/*------------------------------------------------
              判忙函数
------------------------------------------------*/
 bit LCD_Check_Busy(void) 
 { 
	 DataPort= 0xFF; 
	 RS_CLR; 
	 RW_SET; 
	 EN_CLR; 
	 _nop_(); 
	 EN_SET;
	 return (bit)(DataPort & 0x80);
 }
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
 void LCD_Write_Com(unsigned char com) 
 {  
	 while(LCD_Check_Busy()); //忙则等待
	 RS_CLR; 
	 RW_CLR; 
	 EN_SET; 		
	 DataPort= com; 
	 _nop_(); 
	 EN_CLR;
 }
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
 void LCD_Write_Data(unsigned char Data) 
 { 
	 while(LCD_Check_Busy()); //忙则等待
	 RS_SET; 
	 RW_CLR; 
	 EN_SET; 
	 DataPort= Data; 
	 _nop_();
	 EN_CLR;
 }

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
 void LCD_Clear(void) 
 { 
	 LCD_Write_Com(0x01); 
	 DelayMs(5);
 }
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
 void LCD_Write_String(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 ++;     
	 }
 }
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
 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 LCD_Init(void) 
{
   LCD_Write_Com(0x38);    /*显示模式设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38); 
   DelayMs(5); 
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/ 
   LCD_Write_Com(0x01);    /*显示清屏*/ 
   LCD_Write_Com(0x06);    /*显示光标移动设置*/ 
   DelayMs(5); 
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
   
/*------------------------------------------------
                    主函数
------------------------------------------------*/ 
void main(void) 
{ 
	uchar temp[17] = {0};
	cmg88();//关数码管,点阵函数
	LCD_Init(); 
	LCD_Clear();//清屏
	init_com();
	
	LCD_Write_Char(7,0,'o');
	LCD_Write_Char(8,0,'k');
	LCD_Write_String(1,1,"I Love TT");
	while (1) 
	{  
		//开始解析协议 $51,LCD1602,1,0123456789abcdef# 第一行	 $51,LCD1602,2,0123456789abcdef# 第二行
		while (newLineReceived)  //协议数据接收完毕一包
		{
			//判断是否是51的协议
			if(inputString[1] != '5' || inputString[2] != '1')
			{
			 	newLineReceived = 0;  
		   		memset(inputString, 0x00, sizeof(inputString)); 
				break; 
			}
			//判断是否是1602的协议数据
		 	if(inputString[4] != 'L' || inputString[5] != 'C' || inputString[6] != 'D'
			|| inputString[7] != '1'|| inputString[8] != '6'|| inputString[9] != '0'|| inputString[10] != '2')
			{
				newLineReceived = 0;  
	   			memset(inputString, 0x00, sizeof(inputString)); 
				break;	
			}
		
			//开始取数据  位置12 开始  $51,HS00ff3003#
			if(inputString[12] == '0') //清屏
			{
				LCD_Clear();//清屏	
			}
			if(inputString[12] == '1') //显示第一行
			{
				memcpy(temp, inputString+14, 16);
				LCD_Write_String(0, 0, temp);
			}		
			if(inputString[12] == '2') //显示第二行
			{
				memcpy(temp, inputString+14, 16);
				LCD_Write_String(0, 1, temp);
			}

		 	newLineReceived = 0;  
	   		memset(inputString, 0x00, sizeof(inputString)); 
			break;
		}
	
	}
}

/******************************************************************/
/* 串口中断程序*/
/******************************************************************/
void UART_SER () interrupt 4
{
	unsigned char n; 	//定义临时变量
	static int num = 0;

	if(RI) 		//判断是接收中断产生
	{
		RI = 0; 	//标志位清零
		n = SBUF; //读入缓冲区的值

		//control=n;
	    if(n == '$')
	    {
	      startBit = 1;
		  num = 0;
	    }
	    if(startBit == 1)
	    {
	       inputString[num] = n; 
		   num++;    
	    }  
	    if (startBit == 1 && n == '#') 
	    {
	       newLineReceived = 1; 
	       startBit = 0;
		   num = 0;
	    }
		
		if(num >= 50)
		{
			num = 0;
			startBit = 0;
			newLineReceived	= 0;
		}
	}

}

相关推荐

  1. 51单片机控制1602LCD字符滚动三

    2024-03-10 15:02:02       60 阅读
  2. 51单片机4线并发IO口控制1602LCD

    2024-03-10 15:02:02       60 阅读
  3. 51单片机控制1602LCD输出整数和浮点数

    2024-03-10 15:02:02       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-10 15:02:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-10 15:02:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-10 15:02:02       82 阅读
  4. Python语言-面向对象

    2024-03-10 15:02:02       91 阅读

热门阅读

  1. 软件设计模式:模板方法模式

    2024-03-10 15:02:02       41 阅读
  2. RabbitMQ如何实现消费端限流

    2024-03-10 15:02:02       42 阅读
  3. 小米汽车上市进入倒计时,已开启内部试驾

    2024-03-10 15:02:02       45 阅读
  4. ImportError: cannot import name ‘InterpolationMode‘

    2024-03-10 15:02:02       45 阅读
  5. Anaconda和PyCharm比较

    2024-03-10 15:02:02       44 阅读
  6. Linux/Ubuntu/Debian基本命令:光标移动命令

    2024-03-10 15:02:02       37 阅读