文章目录
一、仿真电路
二、测试程序
2.1 主程序
#include <reg52.h>
#include <LCD1602.h>
unsigned char TempBuffer[10];
void IntToStr(unsigned int t, unsigned char* str, unsigned char n)
{
unsigned char a[5];
char i, j;
//取得整数值到数组
a[0] = (t / 10000) % 10;
a[1] = (t / 1000) % 10;
a[2] = (t / 100) % 10;
a[3] = (t / 10) % 10;
a[4] = (t / 1) % 10;
// 转成ASCII码
for (i = 0; i < 5; i++)
{
a[i] = a[i] + '0';
}
for (i = 0; a[i] == '0' && i <= 3; i++);
// 填充空格
for (j = 5 - n; j < i; j++)
{
*str = ' ';
str++;
}
for (; i < 5; i++)
{
*str = a[i];
str++;
}
// 加入行尾符
*str = '\0';
}
void Delay1ms(unsigned int count)
{
unsigned int i, j;
for (i = 0; i < count; i++)
for (j = 0; j < 120; j++);
}
main()
{
unsigned int Count = 0;
LCD_Initial();
GotoXY(0, 0);
Print("The 1602LCD Test");
GotoXY(0, 1);
Print("GO: ");
while (1)
{
IntToStr(Count++, &TempBuffer[0], 5);
GotoXY(3, 1);
Print(&TempBuffer[0]);
Delay1ms(100);
}
}
2.2 LCD1602驱动程序
#include <intrins.h>
/********* 端口定义 ***********/
sbit LcdRs = P2 ^ 0;
sbit LcdRw = P2 ^ 1;
sbit LcdEn = P2 ^ 2;
sfr DBPort = 0x80; // P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
/********* 内部等待 ***********/
unsigned char LCD_Wait(void)
{
LcdRs = 0;
LcdRw = 1;
_nop_();
LcdEn = 1;
_nop_();
// while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,
// 可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80
// 实际硬件时打开此语句
LcdEn = 0;
return DBPort;
}
/********* 写LCD ***********/
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn = 0;
LcdRs = style;
LcdRw = 0;
_nop_();
DBPort = input;
_nop_();//注意顺序
LcdEn = 1;
_nop_();//注意顺序
LcdEn = 0;
_nop_();
LCD_Wait();
}
/********* 设置模式 ***********/
#define LCD_SHOW 0x04 // 显示开
#define LCD_HIDE 0x00 // 显示关
#define LCD_CURSOR 0x02 // 显示光标
#define LCD_NO_CURSOR 0x00 // 无光标
#define LCD_FLASH 0x01 // 光标闪动
#define LCD_NO_FLASH 0x00 // 光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08 | DisplayMode);
}
/********* 输入设置 ***********/
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 // default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04 | InputMode);
}
/********* 初始化 ***********/
void LCD_Initial()
{
LcdEn = 0;
LCD_Write(LCD_COMMAND, 0x38); // 8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND, 0x38);
LCD_SetDisplay(LCD_SHOW | LCD_NO_CURSOR); // 开启显示, 无光标
LCD_Write(LCD_COMMAND, LCD_CLEAR_SCREEN); // 清屏
LCD_SetInput(LCD_AC_UP | LCD_NO_MOVE); // AC递增, 画面不动
}
void GotoXY(unsigned char x, unsigned char y)
{
if(y == 0)
LCD_Write(LCD_COMMAND, 0x80 | x);
if(y == 1)
LCD_Write(LCD_COMMAND, 0x80 | (x - 0x40));
}
void Print(unsigned char *str)
{
while(*str != '\0')
{
LCD_Write(LCD_DATA, *str);
str++;
}
}