LCD1602液晶显示模块的单片机驱动深入详解之软件篇(AVR)

2019-12-31来源: eefocus关键字:LCD1602  液晶显示模块  单片机驱动

LCD1602液晶显示模块的驱动虽然比七段数码管之类的显示要复杂一些,但实际上也并不是很难,最主要的还是初始化,为什么这么说呢?我们在调试一块新液晶屏的时候,都会先初始化看看有没有光标在闪,没有光标前是一番努力(PROTEUS上也是这么做的),光标出来之后就相对很容易了,因为光标出来了,至少说明硬件连接是没有问题的,模块也已经成功接收到了指令,后面就是啃数据手册、改程序、烧录程序观察显示的循环了。

那初始化的流程是怎么样的呢?我们还是看看HD44780的数据手册吧,如下图所示:

可以看到,初始化的主要步骤如下:

(1)上电:这特么也算是一个步骤么?是的!如果你用的是其它液晶模块,比如LCD12864,会发现有一个复位引脚,LCD1602是没有复位引脚的,HD44780本身已经有内部复位逻辑。上电后复位其实会做很多事情的,主要如下:

    a。 清除屏幕数据

    b。设置8位并行通讯方式,1行显示,5X8点阵显示

    c.显示关,关标关,光标闪烁关

    d.地址自动加1,没有屏移

从复位所做的事情来看,初始化该做的都已经做了,要看到光标只需要两条指令:打开显示,再开启光标显示即可。但是为了充分保证初始化的成功率(有可能LCD1602由于外部电气特性条件没达到而没有成功初始化),一般还是会用指令显式重新进行初始化(况且有些时候默认的初始化可能还达不到我们的要求),后面的几条语句其实就是重复上电后做的那些事,我们看看

(2)功能设置(Function Set ):其实就是b点

(3)显示打开/关闭(Display On/Off Control):其实就是c.1(打开显示)

(4)进入模式设置(Entry Mode set):其实就是d

(5)前面就是初始化,后面就是写显示数据了

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

下面是Atmega AVR驱动LCD1602液晶显示模块代码,第一行显示“LCD1602 DEMO”,第二行显示“--CNBLOGS--”,这里没有读状态指令的使用,实际使用时,在写指令或数据时加一些延时即可

注意:分了三个文件,main.c是入口,lcd1602.h与lcd1602.c是具体的一些读写函数

/*******************************************************************************
* 文件名: main.c
* 功能描述: LCD1602显示屏驱动
*******************************************************************************/

#include
#include
#include "lcd1602.h"
/******************************************************************************* 
* 函数名称: void port_init(void)
* 功能描述: LCD1602显示屏的IO口类型设置 
*******************************************************************************/ 
void port_init(void)
{
    //以下为LCD1602相关接口引脚,客户可根据需要进行引脚更改

    DDRA |= BIT(6)|BIT(7); //PA6->RS,PA7->RW

    PORTA |= (BIT(6));
    PORTA |=(BIT(7));
    DDRC =0XFF; //PC->(D0-D7)
    PORTC=0X00; 
    DDRG |= BIT(2); //PG2->E
    PORTG |= BIT(2);
    //以下与LCD接口无关,不同的平台可无需要关注
    DDRB |= BIT(1);
    PORTB |= BIT(0); 
    DDRD =0X00;
    PORTD=0X00; 
    DDRE =0X00;
    PORTE=0X00; 
    DDRF =0X00;
    PORTF=0X00; 
}
/******************************************************************************* 
* 函数名称: void init_devices(void)
* 功能描述: 单片机系统初始化设置(不同的平台有不同的设置,此函数可不关注)

*******************************************************************************/ 
void init_devices(void)
{
    //stop errant interrupts until set up
    CLI(); //disable all interrupts
    XDIV = 0x00; //xtal divider
    XMCRA = 0x00; //external memory
    port_init();

    MCUCR = 0x00;
    EICRA = 0x00; //extended ext ints
    EICRB = 0x00; //extended ext ints
    EIMSK = 0x00;
    TIMSK = 0x00; //timer interrupt sources
    ETIMSK = 0x00; //extended timer interrupt sources
    SEI(); //re-enable interrupts
    //all peripherals are now initialized
}

//这里是入口
void main(void)
{
    int i=0;
    init_devices();//初始化系统
    LCD_init(); //LCD初始化
    LCD_write_str(0, 0, "--Lcd1602--Demo-");
    LCD_write_str(0, 1, "-----CNBLOGS-----");
    while(1){}
}

 

///////////////////////以下为lcd1602.c/////////////////////////////////

#include "lcd1602.h"

//us延时函数
void delay_us(uint n) //8*0.125=1us
{
    int i,j;
    for(j=0;j<8;j++)  {
        for (i=0;i    } 
}

//ms延时函数
void delay_ms(uint i)
{
    while(i--) { 
        uint j; 
        for(j=1;j<=1332;j++) {} 
    } 
}
//EN引脚产生一个高电平脉冲,控制LCD写时序
void LCD_en_write(void) 
{
    E_ON;//EN_SET;
    delay_us(3);
    E_OFF;//EN_CLR
    delay_us(3);//
}
//写指令函数
void Write_Instruction(uchar command)
{
    RS_OFF;//RS_CLR;
    RW_OFF;//RW_CLR
    E_ON;//EN_SET;
    PORTC=command;
    LCD_en_write();//写入指令数据
}

//写数据函数
void Write_Data(uchar Wdata)
{
    RS_ON;//RS_SET;
    RW_OFF;//RW_CLR;
    E_ON;//EN_SET;
    PORTC=Wdata;
    LCD_en_write();//写入数据

//清屏函数
void LCD_clear(void)
{
    Write_Instruction(0x01);
    delay_ms(20);
}

//字符显示初始地址设置
void LCD_SET_XY(uchar X,uchar Y)
{
    uchar address;
    if(Y==0) {
        address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80
    } else {
        address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0XC0
    }
    Write_Instruction(address);//写指令,设置显示初始地址
}

//在第X行Y列开始显示,指针*S所指向的字符串
void LCD_write_str(uchar X,uchar Y,uchar *s)
{
    LCD_SET_XY(X,Y);//设置初始字符显示地址
    while(*s) {//逐次写入显示字符,直到最后一个字符"/0"    
       Write_Data(*s);//写入当前字符并显示
        s++;//地址指针加1,指向下一个待写字符
    }
}

//在第X行Y列开始显示Wdata所对应的单个字符
void LCD_write_char(uchar X,uchar Y,uchar Wdata)
{
    LCD_SET_XY(X,Y);//写地址
    Write_Data(Wdata);//写入当前字符并显示
}
//显示屏初始化函数
void LCD_init(void) 
{ //注意:可以与上面的步骤对应起来
    delay_ms(5);//上电延时一段时间,使供电稳定
    Write_Instruction(0x3c); //Function Set
    Write_Instruction(0x01); //清屏,后面的指令无严格顺序
    Write_Instruction(0x06); //写字符,整屏显示不移动
    Write_Instruction(0x0f); //开显示,开光标, 开闪烁
}

 ////////////////////////////以下为lcd1602.h//////////////////////////////////////////////////////////

#ifndef _LCD1602_H
#define _LCD1602_H

#include "iom128v.h"
#include "macros.h"

#define uchar unsigned char
#define uint unsigned int

#define RS_ON PORTA |= BIT(6);//RS置1
#define RS_OFF PORTA &= ~BIT(6);//RS置0

#define RW_ON PORTA |= BIT(7);//RW置1
#define RW_OFF PORTA &= ~BIT(7);//RW置0

#define E_ON PORTG |= BIT(2);//E置1
#define E_OFF PORTG &= ~BIT(2);//E置0

void delay_us(uint n);
void delay_ms(uint i);
void Port_init(void);
void LCD_init(void);
void LCD_en_write(void);
void LCD_clear(void);
void Write_Instruction(uchar command);
void Write_Data(uchar Wdata);
void LCD_SET_XY(uchar X,uchar Y);
void LCD_write_str(uchar X,uchar Y,uchar *s);
void LCD_write_char(uchar X,uchar Y,uchar Wdata);

#endif

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

写博文时我手头上暂时没有LCD1602,所以用单片机驱动手头上的虚拟器件模块,在手机上看到的效果如下图所示,与实际LCD1602液晶显示屏效果是一样的:

 


关键字:LCD1602  液晶显示模块  单片机驱动 编辑:什么鱼 引用地址:http://news.nvwayi.com/mcu/ic484242.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:AVR单片机教程——旋转编码器
下一篇:LCD1602液晶显示模块的单片机驱动深入详解之硬件篇

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

LCD1602液晶显示模块深入详解之软件篇(AVR)
LCD1602液晶显示模块的驱动虽然比七段数码管之类的显示要复杂一些,但实际上也并不是很难,最主要的还是初始化,为什么这么说呢?我们在调试一块新液晶屏的时候,都会先初始化看看有没有光标在闪,没有光标前是一番努力(PROTEUS上也是这么做的),光标出来之后就相对很容易了。那初始化的流程是怎么样的呢?我们还是看看HD44780的数据手册吧,如下图所示:可以看到,初始化的主要步骤如下:(1)上电:这特么也算是一个步骤么?是的!如果你用的是其它液晶模块,比如LCD12864,会发现有一个复位引脚,LCD1602是没有复位引脚的,HD44780本身已经有内部复位逻辑。上电后复位其实会做很多事情的,主要如下:   
发表于 2020-07-25
LCD1602<font color='red'>液晶显示</font><font color='red'>模块</font>深入详解之软件篇(AVR)
stm32F4+lcd1602实现采集两路adc并显示
以STM32F403为控制核心,设计一种基于STM32的智能照明控制系统,使用光敏电阻作为光照信息来源,使用GP2D12作为人物信息来源,当光照强度改变时,光敏电阻的阻值改变,从而改变STM32的采样电压。当人物移动时,红外传感器的电压改变从而改变采样电压。当光照强度小于一定值,且感应到有人时,LED亮。通过光敏电阻和GP2D12传感器获取光照和红外信息,作为模拟量,传入STM32F4的采集端口。STM32F4进行模数转换后,在LCD1602上进行显示。采用了HAL库进行配置STM32F4,一直有个问题就是proteus仿真DS18B20和DHT11这种带有时序要求的传感器,同STM32通信时出现时序错误,有经验的师兄可以告知一下
发表于 2020-07-22
stm32F4+<font color='red'>lcd1602</font>实现采集两路adc并显示
Proteus仿真STM32实现--DS18B20和LCD1602显示
proteus仿真stm32103r6,实现18B20温度值在1602上显示,可测量正负温度。程序及仿真工程已上传附件,利用proteus仿真18b20温度为0和-0.1时返回值均为零,新手上路,请多指教。使用proteus8.8版本进行仿真。原理图时序原理图单片机部分程序如下:#include "stm32f10x.h"#include "bsp-lcd1602.h"#include "delay.h"#include "sys.h"#include "ds18b20.h"#include <stdio.h>
发表于 2020-07-21
Proteus仿真STM32实现--DS18B20和<font color='red'>LCD1602</font>显示
stm32温湿度-超声波-LCD1602结合项目
_Pin_6|GPIO_Pin_7|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;        GPIO_Init ( GPIOC, &GPIO_InitStruct);}/******************************************************************************** 函 数 名 :write_com* 函数功能 :LCD1602 写指令* 输 
发表于 2020-07-13
stm32温湿度-超声波-<font color='red'>LCD1602</font>结合项目
PIC单片机16F877+LCD1602+DS1302万年历
本万年历具有时间、日期、年、星期调节功能。并可通过LCD1602显示时间、日期、年月、星期、温度。
发表于 2020-07-13
PIC单片机16F877+<font color='red'>LCD1602</font>+DS1302万年历
ATmega16读取RTC和ADC显示在LCD1602,同时串口输出
介绍mikroPascal for AVR 写的ATmega16读取RTC和ADC显示在LCD1602,同时串口输出,并写入EEPROM的程序。附带仿真文件。mikro编译器分为c,basic,pascal三种,除了语法有所区别外,使用和功能基本一样。有8051,AVR,PIC,ARM等版本,界面和语法都一样。学会一种芯片花很少时间就可以转到另一种芯片。自带常用库,帮助文件中例子很多,基本不需要其他文档就可以开始学习了。仿真原理图如下单片机源程序如下:program RTC_Read;var seconds, minutes, hours, day, month, year : byte;   
发表于 2020-07-12
ATmega16读取RTC和ADC显示在<font color='red'>LCD1602</font>,同时串口输出
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD。com。cn, Inc。 All rights reserved
三亚赌博送彩金 博彩论坛送彩金 博彩论坛送彩金 百家乐送彩金 爱彩送彩金 彩票大赢家 那个棋牌游戏送彩金 滚球网站送彩金 网上百家乐送彩金 绑定手机送彩金的网站