hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 306|回复: 1

自学AVR单片机二十六(LCD1602液晶显示)

[复制链接]

573

主题

756

帖子

1969

积分

大司空

Rank: 5Rank: 5

积分
1969
发表于 2024-5-1 09:09:06 | 显示全部楼层 |阅读模式
LCD1602液晶是一种字符型液晶,它可以显示两行字符,每行可以显示16个字符。本实例采用深圳锦昌电子公司的JCM1602C液晶,这种液晶是HD44780的兼容电路,管脚和指令系统与HD44780完全一致。具体的使用手册可到该公司网站下载。也可以采用其他兼容HD44780的其他液晶,控制方式和程序一样。
    HD44780系列兼容液晶管脚如下图所示:

一、电路实现
在本实例中,LCD1602的电路原理图如下;


二、控制流程

a)端口初始化:设置单片机与LCD1602相连接的各个端口的输入输出状态以及电平状态。

b)
液晶(LCD)初始化:设置液晶显示字符前需要进行的操作,依次为:清屏、显示模式设置、显示开关控制、光标设置。主要目的是首先清除液晶屏上原来保存的数据,使液晶屏显示内容为空,然后设置液晶显示模式,接着选择是否打开液晶显示(当然要打开显示了)以及设定光标是否显示和闪烁,最后要设置每当显示一个字符后字符地址指针加一还是减一(也就是下一个字符要显示在这个字符的左边还是右边)。



c)
液晶显示字符,可以指定位置显示,也可以连续显示多个字符。


三、程序代码
lcd1602.h头文件的内容
  1. /*LCD1602.h 文件引脚连接mcu lcdGND VSSVcc Vcc偏压信号,接可调电阻 VEEPG0 RSPG1 R/WPG2 EPB0 D0PB1 D1PB2 D2PB3 D3PB4 D4PB5 D5PB6 D6 PB7 D7Vcc VCCGND GND*///端口位定义#define RS PG0 //数据/命令控制端 0命令,1数据#define RW PG1 //读/写选择控制端 0写,1读#define E PG2 //使能端 下降沿读,高电平写//函数声明void LCDPort_Init(void); //液晶端口初始化void LCD_Init(void); //LCD初始化void Write_Com(unsigned char LCD_Com); //LCD写指令void Write_Data_Byte(unsigned char LCD_Data); //LCD写字节数据void Write_Place_xy(unsigned char x,unsigned char y); //指定当前写字符的位置void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data); //在指定的(x,y)位置上写入字符串数据void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data);//在指定的(x,y)位置上写入字符数据void Check_Busy(void); //读写检测函数,每次对液晶操作前都要进行读写检测void Delayus(unsigned int lus); //us延时函数void Delayms(unsigned int lms); //ms延时函数
复制代码

lcd1602.c文件的内容
  1. /*LCD1602.c 文件*/#include <[url=http://www.mcuzx.net]AVR[/url]/io.h>#include <util/delay.h>#include "LCD1602.h"void LCDPort_Init(){      //LCD数据端口设置PORTB = 0X00;         //DDRB = 0XFF;           //配置端口PB全部为输出口,LCD数据端口//LCD控制端口设置PORTG &= ~((1 << RS) | (1 << RW) | (1 << E));         //DDRG |= (1 << RS) | (1 << RW) | (1 << E); }//LCD初始化void LCD_Init(){Write_Com(0X01);  //清屏Delayms(5);Write_Com(0X38);  //显示模式设置 16x2显示,5x7点阵,8位数据接口Delayms(5);//Write_Com(0X0f);  //显示开关控制,开显示,光标显示,光标闪烁Write_Com(0X0c);  //显示开关控制,开显示,光标不显示,光标不闪烁Delayms(5);Write_Com(0X06);  //光标设置,读或写一个字符后,地址指针加一,光标加一,整屏不移动Delayms(5);}//LCD写指令void Write_Com(unsigned char LCD_Com){Check_Busy();PORTG &= ~(1 << RS);     //RS=0,写命令PORTG &= ~(1 << RW);     //RW=0,写指令PORTG |= (1 << E);       //E=1,写操作Delayms(15);PORTB = LCD_Com;         //指令送数据端口PORTG &= ~(1 << E);     //E=0,停止写操作Delayms(15); }//LCD写字节数据void Write_Data_Byte(unsigned char LCD_Data){Check_Busy();PORTG |= (1 << RS);      //RS=1,写数据PORTG &= ~(1 << RW);    //RW=0,写指令PORTG |= (1 << E);      //E=1,写操作Delayms(15);  PORTB = LCD_Data;        // 数据送数据端口   PORTG &= ~(1 << E);    //E=0,停止写操作Delayms(15); }//指定当前写字符的位置  void Write_Place_xy(unsigned char x,unsigned char y) {unsigned char address;if(y == 0)                   //行位置{  address = 0x80 + x;      //列位置,}else{  address = 0x80 + 0x40 + x;  //}Write_Com(address);          //写地址}//在指定的(x,y)位置上写入字符串数据void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data) {Write_Place_xy(x,y);    //写地址while(*data){  Write_Data_Byte(*data);        //写字符串  data++;                //指针地址加1}}                                         //在指定的(x,y)位置上写入字符数据  x列位置,y行位置        void Write_Data_Char(unsigned char x,unsigned char y,unsigned char data){Write_Place_xy(x,y);           //Write_Data_Byte(data);          //}                                         //读写检测函数,每次对液晶操作前都要进行读写检测void Check_Busy(){     DDRB = 0X00;             //PB口置为输入口,准备读取数据PORTG &= ~(1 << RS);      //RS=0,读命令PORTG |= (1 << RW);    //RW=1,读指令PORTG |= (1 << E);      //E=1,使能while(0X80 & PINB);   //监测忙信号,直到忙信号为0,才能进行读写操作PORTG &= ~(1 << E);   //E=0DDRB = 0XFF;          //PB口置为输出口,准备向端口发送数据}//us级别的延时函数void Delayus(unsigned int lus){while(lus--){  _delay_loop_2(4);      //_delay_loop_2(1)是延时4个时钟周期,参数为4则延时16             //个时钟周期,本实验用16M晶体,则16个时钟周期为16/16=1us    }}//ms级别的延时函数void Delayms(unsigned int lms){while(lms--){  Delayus(1000);        //延时1ms    }}
复制代码


主程序文件
  1. //头文件包含#include <avr/io.h>        //io端口寄存器配置文件,必须包含#include <util/delay.h>       //GCC中的延时函数头文件#include "LCD1602.h"//全局变量声明unsigned char LCD_DispBuff1[]="Let's study AVR";unsigned char LCD_DispBuff2[]=" WWW.LT430.COM";int main(void)            {    unsigned char Disp_Number;   LCDPort_Init();   //端口初始化LCD_Init();    //LCD初始化//在任意位置处显示字符//Write_Com(0X80+0X05);   //发送字符显示位置指令。0x05可以换成00-0f,40-4f之间的任意值//Write_Data_Byte('a');        //发送要显示的字符/*//下面这段程序演示在LCD上显示两行字符Write_Com(0X80+0X00);                       //指定写数据的位置,从第一行第0列开始for(Disp_Number = 0;Disp_Number < 15;Disp_Number++){  Write_Data_Byte(LCD_DispBuff1[Disp_Number]);   //写入要显示的数据  _delay_ms(5);                            //一定要延时一会,因为液晶的速度比较慢}Write_Com(0X80+0X40);                       //指定写数据的位置,第二行第0列开始for(Disp_Number = 0;Disp_Number < 14;Disp_Number++){  Write_Data_Byte(LCD_DispBuff2[Disp_Number]);  //写入要显示的数据  _delay_ms(5);}*///下面这段程序演示在LCD上显示两行字符,字符从屏幕右边移动到屏幕左边/*Write_Com(0X80+0X10);                                //指定写数据的位置,第一行第17个字符开始for(Disp_Number = 0;Disp_Number < 15;Disp_Number++){  Write_Data_Byte(LCD_DispBuff1[Disp_Number]);         //写入要显示的数据  _delay_ms(5);}Write_Com(0X80+0X50);                                //指定写数据的位置,第二行第17个字符开始for(Disp_Number = 0;Disp_Number < 14;Disp_Number++){  Write_Data_Byte(LCD_DispBuff2[Disp_Number]);    //写入要显示的数据  _delay_ms(5);}for(Disp_Number = 0;Disp_Number < 16;Disp_Number++){  Write_Com(0X18);                 //发送数据移位指令,移动16位  _delay_ms(200);}*/Write_Data_String(1,0,"LCD1602 DEMO");      //在第一行第1列开始显示Write_Data_String(0,1,"Welcome to here!");   //在第二行第0列开始显示Write_Data_Char(14,0,'a');                   //在第一行,第14列显示一个字符while(1){  }}
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

0

主题

180

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-5-1 09:09:33 | 显示全部楼层
谢谢提供.................................
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-19 06:37 , Processed in 0.072308 second(s), 22 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

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