单片机控制LCD1602液晶屏模块化编程

学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,但是在公司经过了十多天实习,才真正有了模块化的编程思想,这里将我编写的51单片机控制1602液晶屏的程序共享一下,一是希望没有模块化编程思想的后来者看看,二是希望前辈们给予斧正 。

(补充:以下代码只需要修改.h文件中含有 “选择” 字样的部分,就可以达到复用的效果)

       (因为里面用到的宏比较多一点,建议大家利用 source insight工具建一个工程然后查看)

/*################lcd1602.h start ################*/

#ifndef	 __LCD1602_H__
#define  __LCD1602_H__

#include <reg52.h>

#define LCD1602_DATA_PORT	P0	/*根据硬件连接选择*/

sbit LCD1602_RW_BIT		= P2^5;	/*根据硬件连接选择*/
sbit LCD1602_RS_BIT		= P2^6;	//根据硬件连接选择*/
sbit LCD1602_ENABLE_BIT = P2^7;	/*根据硬件连接选择*/

/*
	RS			RS
	0			0	---->write command to lcd1602  
	0			1	---->read  lcd1602‘s  status
	1			0	---->write data to lcd1602
	1			1       ---->read  lcd1602‘s data 
		
*/

//LCD1602_RS_BIT select
#define LCD1602_RS_BIT_SELECT_DATA		1
#define LCD1602_RS_BIT_SELECT_COMMAND	0

//LCD1602_RW_BIT selcect
#define LCD1602_RW_BIT_SELECT_READ		1
#define LCD1602_RW_BIT_SELECT_WRITE		0


#define LCD1602_ENABLE_BIT_ENABLE		1
#define LCD1602_ENABLE_BIT_DISABLE		0



#define LCD1602_DISPLAY_DEFAULT_MODE	0x38//display : 16(Column) x 2(Row)	, 5 x 7 lattice,8bit data
#define LCD1602_CLEARALL_OPERATION		0x01



/*
	0	0	0	0	1	D	C	B	
						|	|	|------cursor blink  : 1-->enable ; 0-->disalbe
						|	|----------cursor display: 1-->enable ; 0-->disable
						|-------------lcd1602 dispaly: 1-->enable ; 0-->disalbe 
	
*/
#define	LCD1602_CURSOR_AND_DISPLAY_BASE	0x08 /*注意:这里采用“基值	| 光标显示控制 | 光标闪烁控制 | 屏幕显示控制”的方式*/

#define LCD1602_DISPALY_ENABLE			0x04
#define LCD1602_DISPALY_DISABLE			0x00

#define LCD1602_CURSOR_DISPLAY_ENABLE	0x02
#define LCD1602_CURSOR_DISPLAY_DISABLE	0x00

#define LCD1602_CURSOR_BLINK_ENABLE		0x01
#define LCD1602_CURSOR_BLINK_DISABLE	0x00

#define LCD1602_CURSOR_AND_DISPALY_DEFAULT 	LCD1602_CURSOR_AND_DISPLAY_BASE		 | 						LCD1602_CURSOR_BLINK_ENABLE		 | 						LCD1602_CURSOR_DISPLAY_ENABLE            | 						LCD1602_DISPALY_ENABLE
		/*默认 :屏幕显示 + 光标显示 + 闪烁*/




/*
	0	0	0	0	0	1	N	S
							|	|-----  S=1:屏幕移动 ; S=0:屏幕不移动
							|---------  N=1:读或者写一个字符后地址指针加1,且光标加1
										N=0:度或者写一个字符后地址指针减1,且光标减1


							当S=1时 :
								若N=1,整屏幕左移
								  N=0,整屏幕右移 

								以达到光标不移动,而整个屏幕移动的效果
*/									 
#define LCD1602_CURSOR_AND_POINT_BASE	0x04 /*注意:这里采用“基值	| 屏幕移动控制 | 指针控制”的方式*/

#define LCD1602_POINT_INC				0x02
#define LCD1602_POINT_DEC				0X00

#define LCD1602_SCREEN_MOVE_ENABLE		0x01
#define LCD1602_SCREEN_MOVE_DISABLE		0x00


#define LCD1602_CURSOR_AND_POINT_DEFAULT	LCD1602_CURSOR_AND_POINT_BASE	| 						LCD1602_POINT_INC		| 						LCD1602_SCREEN_MOVE_DISABLE
			/*默认 : 指针和地址加一 + 屏幕不移动*/


#define LCD1602_ROW0	0
#define LCD1602_ROW1	1

#define LCD1602_ROW0_ADDRESS_START	0X80
#define LCD1602_ROW1_ADDRESS_START	0Xc0

#define LCD1602_ROW_OR_COLUMN_OVERLOW		-1


extern unsigned char lcd1602ReadStatus(void);

extern void lcd1602WriteCommand(unsigned char opcode);
extern void lcd1602WriteData(unsigned char dat);
extern char lcd1602AddressWriteData(unsigned char x_position ,unsigned char y_position,unsigned char dat);

extern void lcd1602ClearAll(void);

extern void lcd1602Init(void);

	

#endif /*__LCD1602_H__*/



/*################lcd1602.h end################*/

/*################ lcd1602.c start################*/

#include "lcd1602.h"

/******************************************************************
FuncationName	:lcd1602Delay3ms
Author			:yangrui
Date			:20140119_16_13
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:crystal frequecy   12.000MHZ  	
/******************************************************************/
static void lcd1602Delay3ms(void)   
{
	unsigned char i, j;

	i = 36;
	j = 1;
	do
	{
		while (--j);
	} while (--i);
}

/******************************************************************
FuncationName	:lcd1602ReadStatus
Author			:yangrui
Date			:20140120_13_18
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:read LCD1602‘s  status
/******************************************************************/
unsigned char lcd1602ReadStatus(void)
{
	unsigned char temp ;
	
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_DISABLE ;

	LCD1602_RW_BIT = LCD1602_RW_BIT_SELECT_READ ;		/*read*/
	LCD1602_RS_BIT = LCD1602_RS_BIT_SELECT_COMMAND ;	/*read lcd1602‘s status*/
	lcd1602Delay3ms();

	LCD1602_DATA_PORT = 0xff;
	lcd1602Delay3ms();

	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_ENABLE ;
	lcd1602Delay3ms();	

	temp = LCD1602_DATA_PORT;


	return temp;
}

/******************************************************************
FuncationName	:lcd1602CheckBusy
Author			:yangrui
Date			:20140120_10_50
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:check bus busy or free, if busy ,wait!	
/******************************************************************/
static void lcd1602CheckBusy(void)
{	
	do{
		;
	}while(lcd1602ReadStatus()&0x80);/*when LCD1602_DATA_PORT[7] ==1,LCD1602 busy*/


	lcd1602Delay3ms();
	lcd1602Delay3ms();
	lcd1602Delay3ms();
	
}

/******************************************************************
FuncationName	:lcd1602WriteCommand
Author			:yangrui
Date			:20140119_15_30
Input			:opcode(command code)
Output			:N/A
Return 			:N/A
Note			:写指令操作,
				 注意:写地址操作也是本函数完成的,而不是lcd1602WriteData()完成
/******************************************************************/
void lcd1602WriteCommand(unsigned char opcode)
{
	lcd1602CheckBusy();
	
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_DISABLE ;
	
	LCD1602_RW_BIT = LCD1602_RW_BIT_SELECT_WRITE ;		/*write*/
	LCD1602_RS_BIT = LCD1602_RS_BIT_SELECT_COMMAND ;	/*command*/
	LCD1602_DATA_PORT = opcode ;
	lcd1602Delay3ms();
	
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_ENABLE ;
	lcd1602Delay3ms();
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_DISABLE ;
	
	
}

/******************************************************************
FuncationName	:lcd1602WriteData
Author			:yangrui
Date			:20140119_17_30
Input			:dat(ready data Tx to lcd1602)
Output			:N/A
Return 			:N/A
Note			:写数据操作	
/******************************************************************/
void lcd1602WriteData(unsigned char dat)
{
	lcd1602CheckBusy();
	
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_DISABLE ;
	
	LCD1602_RW_BIT = LCD1602_RW_BIT_SELECT_WRITE ;		/*write*/
	LCD1602_RS_BIT = LCD1602_RS_BIT_SELECT_DATA;		/*data*/
	LCD1602_DATA_PORT = dat;
	lcd1602Delay3ms();
	
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_ENABLE ;
	lcd1602Delay3ms();
	LCD1602_ENABLE_BIT = LCD1602_ENABLE_BIT_DISABLE ;
}

/******************************************************************
FuncationName	:lcd1602ClearAll
Author			:yangrui
Date			:20140119_17_30
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:clear all  display	
/******************************************************************/
void lcd1602ClearAll(void)
{
	lcd1602WriteCommand(LCD1602_CLEARALL_OPERATION);
}

/******************************************************************
FuncationName	:lcd1602Init
Author			:yangrui
Date			:20140119_17_30
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:LCD1602 initialize
/******************************************************************/
void lcd1602Init()
{	
	lcd1602ClearAll();
	lcd1602WriteCommand(LCD1602_DISPLAY_DEFAULT_MODE);/*display : 16(Column) x 2(Row)	, 5 x 7 lattice,8bit data*/
	lcd1602WriteCommand(LCD1602_CURSOR_AND_DISPALY_DEFAULT);/*默认 :屏幕显示 + 光标显示 + 闪烁*/
	lcd1602WriteCommand(LCD1602_CURSOR_AND_POINT_DEFAULT);	/*默认 :指针和地址加一 + 屏幕不移动*/
}


/******************************************************************
FuncationName	:lcd1602AddressWriteData
Author			:yangrui
Date			:201401120_11_15
Input			:x_position 、y_position 、 dat
Output			:N/A
Return 			:N/A
Note			:默认16x2,5x7点阵显示,屏幕不移动,指针加1,情况下的地址数据写操作
				 x_position 有效范围:0~15
				 y_position 有效范围:0~1
/******************************************************************/
char  lcd1602AddressWriteData(unsigned char x_position ,unsigned char y_position,unsigned char dat)
{
	if(	x_position<0 || x_position>15 ||			   	y_position<0 || y_position>1 ||		        	  ((y_position!=LCD1602_ROW0) && (y_position!=LCD1602_ROW1))
	   )
	{
		return LCD1602_ROW_OR_COLUMN_OVERLOW;
	}

	if(y_position == 0)
	{
		lcd1602WriteCommand(LCD1602_ROW0_ADDRESS_START + x_position);
		lcd1602WriteData(dat);
	}
	else if(y_position == 1)
	{
		lcd1602WriteCommand(LCD1602_ROW1_ADDRESS_START +x_position);
		lcd1602WriteData(dat);
	}


	return 0;
}

/*################ lcd1602.c end################*/


/*################main.c end################*/

#include <reg52.h>
#include "lcd1602.h"

unsigned char author[] = "Author:YangRui" ;
unsigned char qq[] = "QQ:279729201" ;
unsigned char smile[] = "^_^" ;

void main(void)
{
	int i;
	
	lcd1602Init();

	//Row 0
	for(i=0; i<sizeof(author)-1 ; i++)
	{
		lcd1602WriteData(author[i]);
	}
	lcd1602AddressWriteData(sizeof(author), LCD1602_ROW0, ‘!‘);

	//Row 1
	lcd1602WriteCommand(0xc0);
	for(i=0; i<sizeof(qq)-1 ; i++)
	{
		lcd1602WriteData(qq[i]);
	}
	lcd1602WriteCommand(0xc0+sizeof(qq));
	for(i=0; i<sizeof(smile)-1 ; i++)
	{
		lcd1602WriteData(smile[i]);
	}

	while(1)
	{
		;
	}



}


/*################main.c end################*/

(图片有点大,在网页可能无法全部显示,可以右键保存到电脑查看)

单片机控制LCD1602液晶屏模块化编程


希望大家给予指正!!!

单片机控制LCD1602液晶屏模块化编程

上一篇:Mysql到HBase数据迁移-Sqoop工具方法


下一篇:mongoDB第五讲