学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,但是在公司经过了十多天实习,才真正有了模块化的编程思想,这里将我编写的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################*/
(图片有点大,在网页可能无法全部显示,可以右键保存到电脑查看)
希望大家给予指正!!!
原文:http://blog.csdn.net/yagnruinihao/article/details/18559309