LCD1602

嗯,寒假期间已经给它写了一个库(C/C++)用来适配树莓派,后来又改写成(Python)版

LCD1602_Driver_For_Raspberry_Pi_CPP

LCD1602_Driver_For_Raspberry_Pi_Python

对它的工作原理已经有了一定的了解,

所以本次实验就比较轻松!

但是

实际并非如此,Proteus 使用过程中好几次闪退(目前还不知道什么原因)

首先规划一下针脚接线

如图连接电路

一、字符输出

RP1是一个上拉电阻(不加上拉电阻LCD1602无法工作!)

/* Main.c file generated by New Project wizard
 *
 * Created:   周五 3月 1 2019
 * Processor: 80C51
 * Compiler:  Keil for 8051
 */

#include <reg51.h>

#define SETMODE 0x38	//16*2显示,5*8点阵,8位数据接口
#define DISOPEN 0x0C	//显示开,显示光标,光标不闪烁
#define DISMODE 0x06	//读写字符后地址加1,屏显不移动
#define SETADDR 0x80	//设置数据地址指针初始值
#define CLEAR	0x01	//清屏,数据指针清零
#define RET	0x02	//回车,数据指针清零
#define LSHIFT	0x18	//屏幕左移
#define	RSHIFT	0x1C	//屏幕右移

#define COM_SLEEP	2000		//指令延时
#define DATA_SLEEP	1000		//数据延时

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
sbit rs = P2^0;
sbit rw = P2^1;
sbit en = P2^2;

void delay(int t)
{
    while(t--);
}
void Write_Com(uint8_t com)
{
    en = 0;
    rs = 0;
    rw = 0;
    P0 = com;
    en = 1;
    delay(COM_SLEEP);
    en = 0;
}

void Write_Data(uint8_t dat)
{
    en = 0;
    rs = 1;
    rw = 0;
    P0 = dat;
    en = 1;
    delay(DATA_SLEEP);
    en = 0;
}

void Init()
{
	Write_Com(SETMODE);     //模式设置
	Write_Com(DISOPEN);     //显示设置
	Write_Com(DISMODE);     //显示模式
    Write_Com(CLEAR);           //清屏
}

void Write_String(uint8_t x,uint8_t y,const char *s)
{
    if(y == 1)
		Write_Com(0x80 + x - 1);		//在第一行 x 列写
	else
		Write_Com(0xC0 + x - 1);		//在第二行 x 列写
	while(*s)
	{
		Write_Data(*s);
		s++;
    }

}

void Clear()
{
    Write_Com(CLEAR);
}

void main(void)
{ 
    Init();
    while(1)
    {
        Write_String(1, 1, "Hello World!");
    }
}

二、字符移动

这里发现一个问题!

/* Main.c file generated by New Project wizard
 *
 * Created:   周五 3月 1 2019
 * Processor: 80C51
 * Compiler:  Keil for 8051
 */

#include <reg51.h>
#include <string.h>
#define SETMODE 0x38	//16*2显示,5*8点阵,8位数据接口
#define DISOPEN 0x0C	//显示开,显示光标,光标不闪烁
#define DISMODE 0x06	//读写字符后地址加1,屏显不移动
#define SETADDR 0x80	//设置数据地址指针初始值
#define CLEAR	0x01	//清屏,数据指针清零
#define RET	    0x02	//回车,数据指针清零
#define LSHIFT	0x18	//屏幕左移
#define	RSHIFT	0x1C	//屏幕右移

#define COM_SLEEP	2000		//指令延时
#define DATA_SLEEP	1000		//数据延时

typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
sbit rs = P2^0;
sbit rw = P2^1;
sbit en = P2^2;

void delay(int t)
{
    while(t--);
}
void Write_Com(uint8_t com)
{
    en = 0;
    rs = 0;
    rw = 0;
    P0 = com;
    en = 1;
    delay(COM_SLEEP);
    en = 0;
}

void Write_Data(uint8_t dat)
{
    en = 0;
    rs = 1;
    rw = 0;
    P0 = dat;
    en = 1;
    delay(DATA_SLEEP);
    en = 0;
}

void Init()
{
	Write_Com(SETMODE);     //模式设置
	Write_Com(DISOPEN);     //显示设置
	Write_Com(DISMODE);     //显示模式
    Write_Com(CLEAR);       //清屏
}

void Write_String(uint8_t x,uint8_t y,const char *s)
{
    if(y == 1)
		Write_Com(0x80 + x - 1);		//在第一行 x 列写
	else
		Write_Com(0xC0 + x - 1);		//在第二行 x 列写
	while(*s)
	{
		Write_Data(*s);
		s++;
    }

}
void Shift(uint8_t dire, uint32_t ms, uint8_t len)
{
    uint8_t i;
	if( dire )
	{
		for(i = 0; i < len; i++)
		{
			Write_Com(LSHIFT);
			delay(ms);
		}
	}
	else
	{
		for(i = 0; i < len; i++)
		{
			Write_Com(RSHIFT);
			delay(ms);
		}
	}
}
void Clear()
{
    Write_Com(CLEAR);
}

void main(void)
{ 
    char buf[] = "People's Republic of China";
    Init();
    Write_String(1, 1, buf);
    while(1)
    {
        Shift(1, 60000, strlen(buf)); //左移,整体一秒(1000ms)移一下,移动总长度为字符串 buf 长度
    }
}

 

用户自定义字符就不演示了(软件闪退太频繁了)