历史上的今天
返回首页

历史上的今天

今天是:2024年09月09日(星期一)

正在发生

2020年09月09日 | AVR单片机教程——LCD1602

2020-09-09 来源:eefocus

显示屏

开发板套件里有两块屏幕,大的是LCD(液晶显示),小的是OLED(有机发光二极管)。正与你所想的相反,短小精悍的比较贵,而本讲的主题——LCD1602——功能较少,使用起来也简单很多。


这块屏幕的显示是以字符为单位的。每个字符都是8像素高,5像素宽。1602这个名字,来源于显示字符的数量,共2行,每行16个字符。出售1602的商家提供了一份文档:提取码8c1u。

硬件

一个典型的1602显示屏有16个引脚(还有些模块是用串行总线驱动的):

名称功能连接
VSS电源地GND
VDD正电源VCC(5V)
VO对比度调整左侧的电位器,其左端接GND,右端接VCC
RS数据/指令选择PB0
R/W读/写选择PB1
E使能PB2
D0~D7双向并行数据线74HC595的输出,通过exout_write输出
A背光LED正极NPN三极管的发射极,其集电极接VCC,基极接BAK
K背光LED负极GND

很复杂吧?好在开发板已经处理好了这些,我们只需要关注2组线:RS、R/W、E这3根控制线,通过DDRB和PORTB来操控,和D0~D7这8跟数据线,通过exout_write来以字节为单位输出(在这第一期的最后一篇中,我终于成功地将“尽量减少接线”的原则在第一期中贯彻到底了)。其他的还有对比度CON接口,可以不外接,还有背光BAK接口,可以接5V或3.3V以开启背光。当然,如果你是非主流,你可以把CON接到DAC上,把BAK接到PWM上。


此外,还需要把扩展输出的最高位(标注Ext Out 7)接到一个单片机引脚上。关于为什么会有这种诡异的接法,这是设计时的失误(也可能是不得已吧,毕竟单片机的32个IO已经占满了),参见:一个低电平引发的思考。


协议

1602与单片机之间是通过并行总线通信的。AVR单片机硬件上不支持并行总线,需要通过软件模拟时序来实现。


写操作的时序如下:

进行一个写操作,需要先让RS根据写的类型设置电平,R/W输出低电平,D0~D7输出要发送的数据,然后在E的上升沿数据被对方读取,并保持R/W与D0~D7电平不变,直到E的下降沿之后。两次E的上升沿之间至少需要400us时间间隔。


1602共有8条指令,都是一字节长度的。从高位到低位,每一条指令都由若干个0、一个1和有效指令组成,使得没有两条指令会有相同的二进制表示。这种编码方式成为前缀码,UTF-8也用了类似的编码。

前导0个数功能
0设置DDRAM(显示存储器)地址
1设置CGRAM(字符发生存储器)地址
2设置总线宽度、字符行数、字符大小
3设置滚动对象(光标或画面)、滚动方向
4设置画面、光标、闪烁的开关
5设置AC(地址计数器)是否变化与变化方向
6将AC清零
7清屏

1602插上开发板后只有第一行有黑色背景。我们先把它设置为2行输出,这是最简单的有视觉效果的指令。


#include

#include


inline void short_delay()

{

    asm("nop");

    asm("nop");

    asm("nop");

    asm("nop");

}


int main()

{

    DDRB |= 0b111; // PB2:0 for LCD control: E, R/W, RS

    exout_init();  // Ext Out 7:0 for LCD instructions/data

#define LCD_CONTROL(x) (PORTB = (PORTB & ~0b111) | (x))

    LCD_CONTROL(0b000);

    short_delay();

    LCD_CONTROL(0b100);

    short_delay();

    exout_write(0b00111000); // 8-bit, 2 lines, 5x7 font

    short_delay();

    LCD_CONTROL(0b000);

}

在这段代码中,asm("nop")是一句汇编语句nop,代表这个CPU周期内不执行操作,可以用来短时间而精确地延时。在控制信号与数据信号之间加入短暂的延时,使时序符合1602的要求。


其他指令见数据手册,这份数据手册本身就是很好的教程。需要提醒的是,显示屏内的控制器执行指令需要一定时间,程序在发送下一指令之前,应通过RS为低电平的读取操作来获取其状态,并等待直到状态为空闲。


软件

开发板的库不仅包装了这些硬件操作,还添加了对字符串的支持,包括对b、t、n和r等不可打印字符的处理。


下面我们用1602显示屏来完成一个小项目,在之前用按键控制蜂鸣器的基础上,加入LCD显示与背光动态效果。


#include

#include

#include

#include

#include

#include


int main()

{

    lcd_init(PIN_3);

    lcd_set_status(true, false, false);

    button_init(PIN_6, PIN_7);

    wave_mode(WAVE_0, WAVE_MODE_PWM);

    wave_mode(WAVE_1, WAVE_MODE_TONE);

    char display[6] = {[0] = 'r', [5] = ''};        // 1. 为什么要开6字节字符数组?

    char* notes = display + 1;                         // 2. display数组是如何使用的?

    uint8_t brightness;                                // 3. 这一行有什么问题?

    uint16_t frequency[] = {262, 330, 392, 523};

    uint16_t buzzer = 0, tone;

    while (1)

    {

        memset(notes, ' ', 4);                         // 4. memset是什么函数?

        tone = 0;

        for (uint8_t i = 0; i != 4; ++i)

            if (button_down(i))

            {

                notes[i] = 0xFF;                       // 5. 0xFF是什么字符?

                brightness = 255;

                tone = frequency[i];                   // 6. 如果有多个按键按下,蜂鸣器会响什么音?

            }

        lcd_print_string(display);

        pwm_set(WAVE_0, brightness * brightness >> 8); // 7. 为什么第二个参数不直接写brightness?

        if (tone != buzzer)                            // 8. 为什么必须引入buzzer变量并在这里作判断?

        {

            buzzer = tone;

            tone_set(WAVE_1, buzzer);

        }

        if (brightness)

            brightness -= 5;

        delay(10);

    }

}


在这AVR单片机教程第一期最后一讲中,我在代码中留了8个问题。如果你能全部答上来,说明你对C语言已经有一些了解,熟悉了单片机开发中的部分细节,并具备初步的工程素养了。

推荐阅读

史海拾趣

GETEDZ ( HVGT)公司的发展小趣事
电路设计要便于维护和检修,方便在设备出现故障时能够迅速定位并解决问题。
CDIL[Continental Device India Pvt. Ltd.]公司的发展小趣事

近年来,CDIL积极响应政府政策,利用生产挂钩激励计划(PLI)和电子元件和半导体制造促进计划(SPECS),计划将其产能从目前的5亿片基础上提高1亿片。同时,公司还计划在未来几年内建立两条新的ATMP生产线,以进一步提升产能和技术水平。此外,CDIL还在碳化硅(SiC)等新技术领域进行了深入研发,以满足电动汽车、电源管理设备等新兴市场的需求。

功得(CONQUER)公司的发展小趣事

为了保持在行业中的领先地位,功得公司不断加大技术研发投入。他们与多所高校和科研机构建立合作关系,共同开展前沿技术研究。在这些合作中,功得公司取得了一系列技术突破,推出了一系列具有行业领先水平的新产品。这些技术成果不仅提升了公司的核心竞争力,也为整个电子行业的发展做出了贡献。

亿佰特(EBYTE)公司的发展小趣事

亿佰特始终坚持以质量为核心的发展理念。公司建立了严格的质量控制体系,从原材料采购到生产制造,再到产品检验,每一个环节都严格把关。通过精细化的管理,亿佰特确保了产品的优良品质。同时,公司还注重售后服务,为客户提供全方位的支持。正是凭借卓越的品质和优质的服务,亿佰特赢得了客户的信赖和市场的认可。

Condor公司的发展小趣事

亿佰特(EBYTE)公司自2012年成立以来,一直致力于物联网通信技术的研发。公司团队凭借对无线通信技术的深入理解,不断突破技术瓶颈,成功研发出多款具有创新性的产品。这些产品不仅具备高性能和稳定性,而且能够广泛应用于智能家居、工业控制等领域。亿佰特通过持续的技术创新,逐步在电子行业中树立了领先地位。

固得沃克(GOODWORK)公司的发展小趣事

为了进一步提升品牌影响力和市场占有率,固得沃克积极寻求与行业内知名企业的战略合作。例如,公司与锐单商城达成战略合作,共同推动电子元器件的在线销售和服务。这一合作不仅拓宽了公司的销售渠道,还提升了公司的品牌知名度和美誉度。通过不断参与行业交流和合作,固得沃克在电子行业中的影响力日益增强,为公司的长远发展奠定了坚实基础。

问答坊 | AI 解惑

PCB固定件,有谁见过

有谁见过这种PCB的固定件的不,我在两个不同的功放上看到过。所以觉得应该是有成品卖的,但在网上没搜到。…

查看全部问答>

请教如何将voconnection vorecordset VOString三个类的做成动态链接库DLL

三个类的.cpp和.h在附件中 请教如何将voconnection vorecordset VOString三个类的做成动态链接库DLL? 谢谢…

查看全部问答>

摄像头图像黑边

   请问一下,我的摄像头像出来的图像左右2边有黑边。左边稍细,右边粗点。我是用的6410的开发板,摄像头数据是从saa7113输入的。问过开发板的技术支持,说有可能是行场不同步造成的,叫我们改下相关参数。我看了下saa7113的驱动,在头文 ...…

查看全部问答>

谁知道spn?

spn是什么意思,我说的是与手机上网络有关的SPN?…

查看全部问答>

求助

我要做个很简单的东西 用个小数字键盘输入0000~9999这几个数字 中间用.隔开,之后保存成TXT文件 然后可以通过USB把这些数据与电脑传输 各位大哥有啥好建议 即将学校毕业 想做这个东西 …

查看全部问答>

WINCE中串口类的问题?

按照《EVC高级编程及其应用开发》的实例写了一个串口。 程序中有这样一句: private:         CCESeries m_ceSeries; //定义串口类 编译时就出现错误,显示: error C2146: syntax error : missing \';\' before identifi ...…

查看全部问答>

关于DC12V转DC1000V解决方案?

关于DC12V转DC1000V解决方案? 大家有没有什么方案呢? 1000V输出功率很低,不超过2w,12V蓄电池供电,不知道能不能实现…

查看全部问答>

【EEWORLD大学堂TI教室】精品课程课件下载

把课件PPT整理了一下,分享分享。 …

查看全部问答>

求设计电源原理图

题目1:直流电稳压电源     自主完成一个直流稳压电源的设计。 技术指标要求如下: 1.   输入交流电压为,50Hz,220V; 2.   输出直流电压为+5V和-5V。 3.   输出直流电流0~300mA ...…

查看全部问答>

「ADI模拟大学堂」为电路正确供电(2013.6.8)

replyreload += \',\' + 1484089;「ADI模拟大学堂」为电路正确供电 (每日一份资料) 「ADI模拟大学堂」开始每天更新一份资料,资料更新目录在后面,希望大家支持。希望能获得大家的回帖,我也不用做回复可见。希望大家喜欢ADI的资料,个人很是喜 ...…

查看全部问答>