51驱动LCD12864
LCD12864与LCD1602最大的区别在于LCD12864可以显示汉字,同时也可以拿来画图;当然,作为图形显示不推荐lcd12864,推荐NOKIA5110
12864引脚基本和1602的引脚吻合,大部分的模块多出来两个引脚,一个是RST复位引脚,另一个是PSB通讯模式选择引脚,具体描述见下图
12864指令基本和1602相同,读写时序也应当是先读取忙标志后进行写入,命令列表如下
一般来说,基本指令集用来显示汉字足够了,在开始配置12864之前先要让模块退出复位,然后选择PSB选择相应的通讯模式,接着还要写入相应的模式命令,确定是8位MPU通讯还是4位MPU通讯
对于12864指令集的详细描述代码中会有
#ifndef __LCD12864_H_
#define __LCD12864_H_ #include "common.h"
#include "delay.h"
# include <intrins.h> //12864基本指令集
/***************************************************************************/
#define LCD12864_SHOW_CLEAR 0X01 #define LCD12864_POINT_ZERO 0X02 #define LCD12864_ENTRY_MODE 0X04
//BIT1 指针自动+1 1 指针自动-1 0
//BIT0 屏幕跟随指针移动 1 屏幕不移动 0 #define LCD12864_DISPLAY_STATUS 0X08
//BIT0 1游标闪烁˸ 0游标不闪烁
//BIT1 1游标显示 0游标不显示
//BIT2 1开显示 0关显示 #define LCD12864_CURSOR_MODE 0X10
//BIT3 显示跟随移动 1 显示不跟随移动 0
//BIT2 游标右移 1 游标左移0 #define LCD12864_FUN_SET 0X20
//BIT4 1八位并口 0 四位通讯接口
//BIT2 1扩充指令集 0基础指令集 #define LCD12864_CGRAM_SET 0X40//CGRAM(绘图)基础地址
//BIT0-BIT5 CGRAM地址 #define LCD12864_DDRAM_SET 0X80//设定LCD地址
//BIT0-BIT5 DDRAM地址(显示字符)
/***********************************************************************************************/ void Lcd12864Init(void); void Lcd12864SetPos(u8 x,u8 y); void Lcd12864ShowStr(u8 x,u8 y,u8* buffer);//不能进行中英文混合显示 #endif
#include "lcd12864.h" sbit LCD12864_RS_PIN = p07;
sbit LCD12864_RW_PIN = p06;
sbit LCD12864_EN_PIN = p05;
sbit LCD12864_PSB_PIN = p04;
sbit LCD12864_RST_PIN = p03; #define LCD12864_DATA P2 #define LCD_RS_CMD LCD12864_RS_PIN = 0
#define LCD_RS_DAT LCD12864_RS_PIN = 1 #define LCD_RW_WRITE LCD12864_RW_PIN = 0
#define LCD_RW_READ LCD12864_RW_PIN = 1 #define LCD_EN_HIGH LCD12864_EN_PIN = 1
#define LCD_EN_LOW LCD12864_EN_PIN = 0 #define LCD_PSB_COM LCD12864_PSB_PIN = 0
#define LCD_PSB_LPT LCD12864_PSB_PIN = 1 #define LCD_RST_LOW LCD12864_RST_PIN = 0
#define LCD_RST_HIGH LCD12864_RST_PIN = 1 static void delay(unsigned int m)
{
unsigned int i,j;
for(i=0;i<m;i++)
for(j=0;j<10;j++);
} static bit Lcd12864ReadStatus(void)
{
bit result;
LCD_RS_CMD;
LCD_RW_READ;
LCD_EN_HIGH;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(LCD12864_DATA&0x80);
LCD_EN_LOW;
return result;
} static void Lcd12864WriteCommand(u8 command)
{
while(Lcd12864ReadStatus());
LCD_RS_CMD;
LCD_RW_WRITE;
LCD_EN_LOW;
_nop_();
_nop_();
LCD12864_DATA = command;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN_HIGH;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN_LOW;
} static void Lcd12864WriteData(u8 dat)
{
while(Lcd12864ReadStatus());
LCD_RS_DAT;
LCD_RW_WRITE;
LCD_EN_LOW;
_nop_();
_nop_();
LCD12864_DATA = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN_HIGH;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN_LOW;
} // 1 lpt 0 com
static void Lcd12864SelMode(u8 mode)
{
delay(40);
if(mode)
{
LCD_PSB_LPT;
}
else
{
LCD_PSB_COM;
}
delay(1);
}
static void Lcd12864Rst(void)
{
LCD_RST_LOW;
delay(1);
LCD_RST_HIGH;
delay(10);
}
void Lcd12864Init(void)
{
Lcd12864SelMode(1);
Lcd12864Rst();
Lcd12864WriteCommand(0x30); //
delay(100);
Lcd12864WriteCommand(0x30); //八位并口,基础指令集
delay(37);
Lcd12864WriteCommand(0x08); //关闭显示和游标
delay(100);
Lcd12864WriteCommand(0x10); //游标不跟随
delay(100);
Lcd12864WriteCommand(0x0C); //开显示
delay(100);
Lcd12864WriteCommand(0x01); //清屏
delay(10);
Lcd12864WriteCommand(0x06); //AC自动+ 屏幕不移动
delay(100);
} void Lcd12864SetPos(u8 x,u8 y)
{
u8 pos = 0;
switch(y)
{
case 1:
pos = 0x80;
break;
case 2:
pos = 0x90;
break;
case 3:
pos = 0x88;
break;
case 4:
pos = 0x98;
break;
}
if(x>=8)x = 8;
pos += x;
Lcd12864WriteCommand(pos);
} void Lcd12864ShowStr(u8 x,u8 y,u8* buffer)
{
u8 i = 0;
Lcd12864SetPos(x,y);
for(i = 0; i < 16-2*x;i++)
{
if(*(buffer+i) == '\0')break;
else
{
Lcd12864WriteData(*(buffer+i));
}
}
}
需要注意的是,12864每次写入的时候不能中英文同时混合写入,这样会造成乱码,因为就编码来讲,一个汉字空间,是可以容纳两个ascii码字符的,所以当一个英文字母和一个汉字在一起的时候,英文字符八位编码,汉字16位编码,LCD控制器将英文的八位编码和汉字的前八位编码当成一个汉字来显示,当然就会出错了
当然,这也就是说,显示汉字的时候一定要保证汉字的第一个字符一定得是当前地址写入的第一个字符,不能是第二个,而汉字的第一个编码一般都是大于0x80的,所以遇到大于0x80数据的时候进行判断是不是当前地址写入的第一个字符,不是则重新设置地址,就能防止汉字乱码出现了
另外,51编译器keil需要选择ansci编码,选择其他编码,汉字是会变成乱码的,这纯粹是编码格式问题,嗯,最好的办法是将汉字编码变成数组依次写入,这样就能避免编辑器造成的编码问题了
51驱动LCD12864的更多相关文章
- 自制单片机之十五……可串行驱动LCD12864的应用
在网上搜了一下,ST7920控制器的LCD产品可以提供8位,4位并行和串行接口可选,并行的控制接口的LCD较多,前面的贴子也介绍过,我们在这儿不说了,这儿我们讲的是串口控制LCD12864. 买了块S ...
- 51驱动LCD1602
1602 采用标准的 16 脚接口,其中: 第 1 脚:VSS 为地电源 第 2 脚:VDD 接 5V 正电源 第 3 脚:V0 为液晶显示器对比度调整端,接正电源时对比度最弱,接地 电源时对比度最高 ...
- FPGA nios通过驱动LCD12864实现菜单界面和uart串口通信
因为csdn无法插入视频,无法展示我这个实现的效果,这里我截了一些图,应该基本上也能明白了: 基本功能就是如图片所示,里面采用了菜单结构(这里编程需要一定得c语言编程技巧与数据结构知识),gpa是什么 ...
- 自制单片机之五……LCD12864的驱动
LCD12864的驱动LCD12864在市面上主要分为两种,一种是采用st7920控制器的,它一般带有中文字库字模,价格略高一点.另一种是采用KS0108控制器,它只是点阵模式,不带字库.很可惜,我的 ...
- [51单片机] nRF24L01 无线模块 测试 按键-灯-远程控制
哈哈,穷吊死一个,自己做的一个超简单的板还没有电源提供,只得借助我的大开发板啦.其实这2个模块是完全可以分开的,无线嘛,你懂得!进入正题,这个实验的功能就是一个发送模块(大的那个板)连接4个按键,通过 ...
- Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建
1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...
- Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建
1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...
- LCD12864 液晶显示-汉字及自定义显示(串口)
在网上找了许久,发现FPGA用串口驱动LCD12864程序很少,基本上没有.刚开始窃喜,中间郁闷,最后还是高兴,为什么这样说呢!头一回在没有参考程序的情况下,完全是照时序图写(自信),中间调试过程遇到 ...
- 关于STM32驱动DS1302实时时钟的一点思考
之前用51驱动过DS1302,没用多久就输出了正确的时间.当时以为这块芯片其实没啥,很简单.但是现在用STM32做项目,用到同样的芯片,以为这有何难,只要把那个程序拿过来复制黏贴改一下IO设置不就行了 ...
随机推荐
- margin
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Win7下用easyBCD引导安装Ubuntu15.04
1 准备工作 easyBCD中添加一个启动项 修改启动项配置文件 注意两点:C盘设备号,镜像名称 title Install Ubuntu root (hd0,) kernel (hd0,)/vmli ...
- Windows API 之 ReadProcessMemory
ReadProcessMemory: BOOL WINAPI ReadProcessMemory( _In_ HANDLE hProcess, _In_ LPCVOID lpBaseAddress, ...
- LNMPA by lin
CentOS系统下执行:wget -c http://soft.vpser.net/lnmp/lnmp1.1-full.tar.gz && tar zxf lnmp1.1-full.t ...
- Windows 2003】利用域&&组策略自动部署软件
Windows 2003]利用域&&组策略自动部署软件 转自 http://hi.baidu.com/qu6zhi/item/4c0fa100dc768613cc34ead0 ==== ...
- Installation error: INSTALL_FAILED_UID_CHANGED 的解决办法
出现此问题的原因大多是apk冲突造成,解决的办法如下: 1. Settings -> Applications, 卸载出现问题的apk,重新安装即可. 2. 如果apk无法卸载,则将apk相关 ...
- elisp
cons cell? 构建内存对象! 通过寄存器的基地址car和偏移地址cdr来--寻址内存对象,我是这样理解的. http://wiki.dourok.info/doku.php/%E5%B7%A5 ...
- 面向对象重写(override)与重载(overload)区别
一.重写(override) override是重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重写(重新实现)父类中的方法. 重写(覆盖)的规则: 1.重写方法的参数列表必须完 ...
- CentOS 修改DNS,固定IP等操作(网络)
1.修改DNS 修改对应网卡的DNS的配置文件 vi /etc/resolv.conf 内容格式(西工大) nameserver 114.114.114.114 nameserver 202.117. ...
- Java关键字transient和volatile小结(转)
Java关键字transient和volatile小结(转) transient和volatile两个关键字一个用于对象序列化,一个用于线程同步,都是Java中比较高阶的话题,简单总结一下. tran ...