登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 第七章:LCD1602

[复制链接]
发表于 2017-2-9 21:16:59 | 显示全部楼层 |阅读模式
学习笔记
学习科目: C51
学习安排: 详见:http://bbs.hpuedd.com/forum.php?mod=viewthread&tid=837&fromuid=385
开始时间: 2017-02-09
结束时间: 2017-02-11
本帖最后由 夜色星空 于 2017-2-9 21:33 编辑
如图

1-1.PNG 1-2.PNG

其物理链路与引脚的说明


关于使能引脚,其作用就是让LCD读取当前线上的状态

就像串口需要波特率来使数据收发方可以接收或发送所期望的数据一样

使能引脚的作用是,通知LCD,这就是我想要表达给你的数据

也就是说,在使能引脚拉高前(拉高时使能LCD)

我们应先将其余的引脚电平配置好

然后随手拉高使能引脚,持续一段时间,通知LCD接收数据

然后再拉低,准备下一帧的数据


那么这里就有一个问题,LCD如何知道那个是要显示的内容,哪个是设置显示状态的指令

那么此时就有了数据与指令之分

也就是P20(RS)引脚

当它为高时,就相当于告诉LCD这次的传输是数据

反之,当其为低时则是数据


然后再看P21脚读写操作

一般读操作用的不多(有些开发板甚至直接就把此引脚接在了GND)

在这里我只说一下读忙


读忙顾名思义,就是问LCD现在忙不忙

你发出了指令给LCD之前,要先询问LCD现在有空没

(有空LCD才会搭理你

LCD给你的回应在DB7脚上

当LCD不忙时,LCD会将DB7拉低

我们只需要检测DB7的电平是否为0就可以

然后我们就可以进行数据(指令)传输了

(PS:有些书上说不需要读忙,只需适当延时,笔者亲测是可以的,但是浪费CPU资源



数据传输很简单,遵循ASCII嘛的标准,将P0看成一个八位的寄存器

然后给他赋值


P0=0XFF;

P0='a';

等等


然而指令传 输就不同了

遵循下面的指令表

1-3.PNG

你想怎样显示,在哪显示

只需要按照指令表上的指令

发送给LCD就行了(有兴趣的可以一个一个试一试)

然而,在这里说一个比较坑的事情

数据指针

先说1602的命名

16个字符,2行

就是这么通俗

那么,我想在第1行,第一个字符的地方写字

就使用命令

P0=0X80+0

0X80可以记为控制光标指令

+0则意为在第一个字符处写数据

同理,在第二个字符处写数据

对应指令为

P0=0X80+1

直到

P0=0X80+15(0X0F)

此时,按理说再加一就应该跳转到第二行了

但是则不然

第二行开头的地址为

0X80+0X40

那么0X80+16(0X10)在哪?

如图

1-4.PNG

它也可以存放数据,但是真正显示的只有

0X80-0X80+15

0X80+0X40-0X80+0X40+15

这两段

剩下的要想显示可以使用移屏指令

1-5.PNG


放上一个例程(仅供参考)

[mw_shl_code=c,true]#include <stc12c5a60s2.h>
#include <intrins.h>
#define unchar unsigned char
#define unint unsigned int
sbit LCD_EN=P1^2;
sbit LCD_RW=P2^1;
sbit LCD_RS=P2^0;
sbit pwm=P1^3;
unchar code LCD_NUM[16]="Guess  Who am I ";
void LCD_DELAY()
{
        unsigned char i;

        _nop_();
        _nop_();
        _nop_();
        i = 10;
        while (--i);
}


void LCD_CHECK()
{
        unchar state;
        LCD_EN=0;
        LCD_RS=0;
        LCD_RW=1;
        P0=0XFF;
        do
        {
                LCD_EN=1;
                state=P0;
                LCD_EN=0;
        }while(state&0X80);
}

void LCD_WRITE(unchar rs,unchar buf)
{
        LCD_CHECK();
        LCD_RW=0;
        if(rs=='C')LCD_RS=0;
        else if(rs=='D')LCD_RS=1;
        P0=buf;
        LCD_DELAY();
        LCD_EN=1;
        LCD_DELAY();
        LCD_EN=0;
}

void EN_LCD()
{
        LCD_EN=0;
        LCD_WRITE('C',0X38);
        LCD_WRITE('C',0X0F);
        LCD_WRITE('C',0X06);
        LCD_WRITE('C',0X01);
}

void LCD_SHOW()
{
        unchar a;
        LCD_WRITE('C',0X80);
        for(a=0;a<16;a++)
        {
                LCD_WRITE('D',LCD_NUM[a]);
                if(a==5)LCD_WRITE('C',0X80+0X40);
        }
}
void main()
{
        EN_LCD();
        LCD_SHOW();
        while(1);
}

[/mw_shl_code]



再丢两个HEX,结贴

单字节版

http://bbs.hpuedd.com/forum.php?mod=viewthread&tid=981&extra=page%3D1

字符串版

http://bbs.hpuedd.com/forum.php?mod=viewthread&tid=1004&extra=page%3D1

(如有问题,请联系笔者)

(至此,不牵涉时序的算是说完了)

小结:
剩余
1.PWM调波(笔者一直在调38KHZ载波,有谁调成了,欢迎分享经验)
2.单线(DS18B20,//一体化接收头)
3.双线(IIC)EEPROM
//4.NRF24L01,SPI
(说不完了,加注释,以后用空再写,PS:笔者最近在忙着搞事情




该会员没有填写今日想说内容.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表