本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
LCD1602液晶是一种字符型液晶,它可以显示两行字符,每行可以显示16个字符。本实例采用深圳锦昌电子公司的JCM1602C液晶,这种液晶是HD44780的兼容电路,管脚和指令系统与HD44780完全一致。具体的使用手册可到该公司网站下载。也可以采用其他兼容HD44780的其他液晶,控制方式和程序一样。
HD44780系列兼容液晶管脚如下图所示:
一、电路实现
在本实例中,LCD1602的电路原理图如下;
二、控制流程
a)端口初始化:设置单片机与LCD1602相连接的各个端口的输入输出状态以及电平状态。
b)液晶(LCD)初始化:设置液晶显示字符前需要进行的操作,依次为:清屏、显示模式设置、显示开关控制、光标设置。主要目的是首先清除液晶屏上原来保存的数据,使液晶屏显示内容为空,然后设置液晶显示模式,接着选择是否打开液晶显示(当然要打开显示了)以及设定光标是否显示和闪烁,最后要设置每当显示一个字符后字符地址指针加一还是减一(也就是下一个字符要显示在这个字符的左边还是右边)。
c)液晶显示字符,可以指定位置显示,也可以连续显示多个字符。
三、程序代码
lcd1602.h头文件的内容
- /*
- LCD1602.h 文件
- 引脚连接
- mcu lcd
- GND VSS
- Vcc Vcc
- 偏压信号,接可调电阻 VEE
- PG0 RS
- PG1 R/W
- PG2 E
- PB0 D0
- PB1 D1
- PB2 D2
- PB3 D3
- PB4 D4
- PB5 D5
- PB6 D6
- PB7 D7
- Vcc VCC
- GND 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文件的内容
-
- /*
- LCD1602.c 文件
- */
- #include <AVR/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=0
- DDRB = 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
- }
- }
复制代码
主程序文件
- //头文件包含
- #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)
- {
-
- }
- }
复制代码 |