[VHDL代码]LCD1602驱动

合集下载

LCD1602驱动代码

LCD1602驱动代码
/* 设定显示位置 */
/* */
/*******************************************************************/
WLCOME TO
YUNLONGDZ BBS
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/* 延时子程序 */
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/*******************************************************************/
void lcd_init()
{
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
/* */
/* 闪动子程序 */
/* */
_nop_(); *******************************************************************/
/* */
delay(200); //延时
lcd_wcmd(0x0c); //开显示
delay(200); //延时
lcd_wcmd(0x08); //关闭显示
LCD_EN = 0;
return result;
}
/*******************************************************************/

51单片机任意2个IO口驱动LCD1602

51单片机任意2个IO口驱动LCD1602

51单片机任意2个IO口驱动LCD1602相信大家对1602显示屏已经十分熟悉,驱动方式有8线制(需要11根线)和4线制(需要7根线),这里为大家推荐一种只需要2根线就能驱动1602的方法。

之前在网上见到Arduino通过IIC驱动1602的实例,本人完全不懂Arduino程序,看了一下驱动电路,发现PCF8574这个关键芯片,它就相当于一个桥梁,将IIC总线转换为8位准双向口。

思路1、单片机通过IIC与PCF8574进行通信。

首先写好IIC通信程序,网上到处都是IIC通信程序,很容易找。

PCF8574 的器件地址为40h,由于硬件地址引脚A0-A2可寻址8 个器件,所以器件地址并不唯一,具体说明大家去查查PCF8574芯片手册.2、单片机4线制驱动1602网上也有很多相关程序,我就不再多说。

4线制驱动方式需要7个IO口(RS、RW、E和4条数据线),而PCF8574提供了8位准双向口,所以管脚还有剩余。

3、IIC通信程序和1602的4线制驱动程序相结合4、51单片机任意2个IO口驱动1602成功!!!。

(我只是个业余爱好者,要是各位觉得太低端那就见谅了)驱动电路图效果图实物图Proteus仿真程序#include <reg52。

h>#include 〈intrins。

h〉sbit SCL = P3^0;sbit SDA = P3^1;bit ack;unsigned char LCD_data;unsigned char code digit[ ]={”0123456789"}; //定义字符数组显示数字//*****************延时************************void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i〈n;i++)_nop_();}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i,j;for (i=0;i<n;i++)for (j=0;j<1140;j++);}void nop4(){_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期_nop_(); //等待一个机器周期}//***************************************void Start(){SDA=1;_nop_();SCL=1;nop4();SDA=0;nop4();SCL=0;_nop_();_nop_();}void Stop(){SDA=0;_nop_();SCL=0;nop4();//>4us后SCL跳变SCL=1;nop4();SDA=1;_nop_();_nop_();}//****************************************** void Write_A_Byte(unsigned char c){unsigned char BitCnt;for(BitCnt=0;BitCnt〈8;BitCnt++) //要传送的数据长度为8位{if((c<<BitCnt)&0x80) SDA=1; //判断发送位else SDA=0;_nop_();SCL=1; //置时钟线为高,通知被控器开始接收数据位 nop4();_nop_();SCL=0;}_nop_();_nop_();SDA=1; //8位发送完后释放数据线,准备接收应答位_nop_();_nop_();SCL=1;_nop_();_nop_();_nop_();if(SDA==1)ack=0;else ack=1; //判断是否接收到应答信号SCL=0;_nop_();_nop_();}bit Write_Random_Address_Byte(unsigned char add,unsigned char dat){Start(); //启动总线Write_A_Byte(add); //发送器件地址if(ack==0)return(0);Write_A_Byte(dat); //发送数据if(ack==0)return(0);Stop(); //结束总线return(1);}//********************液晶屏使能********************* void Enable_LCD_write(){LCD_data|=(1<<(3—1));//E=1;Write_Random_Address_Byte(0x40,LCD_data);delay_nus(2);LCD_data&=~(1〈<(3-1));//E=0;Write_Random_Address_Byte(0x40,LCD_data);}//*************写命令****************************void LCD_write_command(unsigned char command){delay_nus(16);LCD_data&=~(1<<(1—1));//RS=0;LCD_data&=~(1<〈(2-1));//RW=0;Write_Random_Address_Byte(0x40,LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=command & 0xf0; //写高四位Write_Random_Address_Byte(0x40,LCD_data);Enable_LCD_write();command=command〈〈4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=command&0xf0; //写低四位Write_Random_Address_Byte(0x40,LCD_data);Enable_LCD_write();}//*************写数据****************************void LCD_write_data(unsigned char value){delay_nus(16);LCD_data|=(1<〈(1-1));//RS=1;LCD_data&=~(1〈〈(2-1));//RW=0;Write_Random_Address_Byte(0x40,LCD_data);LCD_data&=0X0f; //清高四位LCD_data|=value&0xf0; //写高四位Write_Random_Address_Byte(0x40,LCD_data);Enable_LCD_write();value=value〈〈4; //低四位移到高四位LCD_data&=0x0f; //清高四位LCD_data|=value&0xf0; //写低四位Write_Random_Address_Byte(0x40,LCD_data);Enable_LCD_write();}//**********************设置显示位置*********************************void set_position(unsigned char x,unsigned char y){unsigned char position;if (y == 0)position = 0x80 + x;elseposition = 0xc0 + x;LCD_write_command(position);}//**********************显示字符串*****************************void display_string(unsigned char x,unsigned char y,unsigned char *s){set_position(x,y);while (*s){LCD_write_data(*s);s++;}}//*************液晶初始化****************************void LCD_init(void){LCD_write_command(0x28);delay_nus(40);LCD_write_command(0x28);delay_nus(40);Enable_LCD_write();delay_nus(40);LCD_write_command(0x28); //4位显示!!!!!!!!!!!!!!!!!!LCD_write_command(0x0c); //显示开LCD_write_command(0x01); //清屏delay_nms(2);}void main(void){LCD_init();display_string(4,0,"imxuheng"); //显示一段文字display_string(2,1,”Hello Today!”); //显示一段文字while(1);}程序还不够完美,自身工作与电学没什么关系,只是业余爱好鼓捣鼓捣,希望各位能够提出修改意见。

lcd1602四位数据线接法的驱动

lcd1602四位数据线接法的驱动

lcd1602四位数据线接法的驱动LCD1602四位数据线接法的驱动硬件及驱动 2009-04-14 13:56:22 阅读480 评论0 字号:大中小订阅IO端口不够用是就可以接成6线接法:RS、E、DB4、DB5、DB6、DB7 可以任意用6根独立的IO线;这样就可以节省了5根IO线;程序如下://////////////////////////////////////根据自己的接线修改sbit LCD_DB0=P0^4;sbit LCD_DB1=P0^5;sbit LCD_DB2=P0^6;sbit LCD_DB3=P0^7;sbit LCD_RS=P2^0;sbit LCD_RW=P2^1; //只读数据而不写时可以直接接地sbit LCD_E=P2^2;////////////////////////////////////******定义函数****************/#define uchar unsigned char#define uint unsigned intvoid LCD_write_command(uchar command); //写指令函数void LCD_init_first(void);void LCD_init(void); //初始化函数void LCD_write_data(uchar dat); //写数据函数void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数void LCD_pos(unsigned char x,unsigned char y );void delay_ms(unsigned int n) ;void delay_n10us(uint n);/////////////////////////////////////////////*-------------------------------------;首次初始化时要先运行此函数;/*************************************/void LCD_init_first(void){delay_ms(50);LCD_write_command(0x30);delay_ms(6);LCD_write_command(0x30);delay_ms(1);LCD_write_command(0x30);delay_ms(1);LCD_write_command(0x02);}/*--------------------------------------;模块名称:LCD_init();;功能:初始化LCD1602;占用资源:--;参数说明:--;创建日期:2008.08.15;版本:FV1.0(函数版本Function Version);修改日期:--;修改说明:--;-------------------------------------*/void LCD_init(void){//LCD_write_command(0x38);//设置8位格式,2行,5x7LCD_write_command(0x28);//设置4位格式,2行,5x7LCD_write_command(0x0c);//整体显示,关光标,不闪烁LCD_write_command(0x06);//设定输入方式,增量不移位LCD_write_command(0x01);//清除屏幕显示delay_n10us(100); //延时清屏,延时函数,延时约n个10us}/*--------------------------------------;模块名称:LCD_write_command();;功能:LCD1602写指令函数;占用资源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E). ;参数说明:dat为写命令参数;创建日期:2008.08.15;版本:FV1.0(函数版本Function Version) ;修改日期:--;修改说明:--;-------------------------------------*/ void LCD_write_command(uchar dat){LCD_RS=0;LCD_RW=0; //只读数据而不写时可以直接接地LCD_E=0;dat<<=1;LCD_DB3=CY;dat<<=1;LCD_DB2=CY;dat<<=1;LCD_DB1=CY;dat<<=1;LCD_DB0=CY;LCD_E=1;delay_n10us(1);LCD_E=0;dat<<=1;LCD_DB3=CY;dat<<=1;LCD_DB2=CY;dat<<=1;LCD_DB1=CY;dat<<=1;LCD_DB0=CY;LCD_E=1;delay_n10us(1);LCD_E=0;}/*--------------------------------------;模块名称:LCD_write_data(); ;功能:LCD1602写数据函数;占用资源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E). ;参数说明:dat为写数据参数;创建日期:2008.08.15;版本:FV1.0(函数版本Function Version);修改日期:--;修改说明:--;-------------------------------------*/void LCD_write_data(uchar dat){LCD_RS=1;LCD_RW=0; //只读数据而不写时可以直接接地LCD_E=0;dat<<=1;LCD_DB3=CY;dat<<=1;LCD_DB2=CY;dat<<=1;LCD_DB1=CY;dat<<=1;LCD_DB0=CY;LCD_E=1;delay_n10us(1);LCD_E=0;dat<<=1;LCD_DB3=CY;dat<<=1;LCD_DB2=CY;dat<<=1;LCD_DB1=CY;dat<<=1;LCD_DB0=CY;LCD_E=1;delay_n10us(1);LCD_E=0;}/*-------------------------------------- ;模块名称:LCD_disp_char();;功能:LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)。

LCD1602驱动编程(一)——LCD1602简介

LCD1602驱动编程(一)——LCD1602简介

LCD1602驱动编程(一)——LCD1602简介(一)基本概念1.液晶显示基本原理:(1)线段显示点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。

例如屏的第一行的亮暗由RAM区的000H——00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=FFH,……(00EH)=FFH,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。

这就是LCD显示的基本原理。

(2)字符显示用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。

这样一来就组成某个字符。

但对内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。

(3)汉字显示汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字。

LCD1602的驱动程序的代码编写

LCD1602的驱动程序的代码编写
#define LCD_WRITE_COM 0
sbit RS = P2_;
sbit RW = P2_;
sbit E = P2_;
unsigned char flag = 1;
unsigned char shi = 23, fen = 59, miao = 50;
void lcd1602_write(unsigned char byte, unsigned char flag)
lcd1602_write(0x80,LCD_WRITE_COM);
lcd1602_write((temp / 16) + 0x30,LCD_WRITE_DATA);
lcd1602_write((temp % 16) + 0x37,LCD_WRITE_DATA);
}
void main()
{
time0_init();
{
EA = 1;
TMOD |= 0x01;
TH0 = (65536 - 20000) / 255;
TL0 = (65536 - 20000) % 255;
ET0 = 1;
TR0 = 1;
}
void TIme0_isr() interrupt 1
{
staTIc unsigned char i = 0;
lcd_init();
lcd_dis_hex();
lcd_dis_char(0,2,time:);
while(1)
{
lcd_diaplay_time();
}
}
#include reg52.h
#include ./delay/delay.h
#define LCDPORT P0

LCD1602驱动程序

LCD1602驱动程序

1602是课程设计和毕业设计经常用到的显示器,还在愁怎么对1602操作吗?那么看完1602驱动程序,一切变得那么简单。

LCD1602驱动程序://===========LCD1602.H===============#ifndef _LCD1602_H__#define _LCD1602_H__#include<intrins.h>#include"delay.h"//lcd1602管脚定义#define LCD_Data P0 //第7~14脚:D0~D7为8位双向数据线#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit LCD_RS=P2^0; //寄存器选择位,将LCD_RS位定义为P2.0引脚sbit LCD_RW=P2^1; //读写选择位,将LCD_RW位定义为P2.1引脚sbit LCD_E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚//函数定义声明bit BusyTest(void);//判断液晶模块的忙碌状态void WriteInstruction (unsigned char );//将模式设置指令或显示地址写入液晶模块//void WriteAddress(unsigned char ); //指定字符显示的实际地址void WriteData(unsigned char );//将数据(字符的标准ASCII码)写入液晶模块void CursorFlash(unsigned char,unsigned char); //光标在指定坐标闪烁void InitLcd(void);//初始化LCD1602/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。

LCD1602的单片机驱动详解..

LCD1602的单片机驱动详解..

LCD1602的单片机驱动详解一•接口LCD1602是很多单片机爱好者较早接触的字符型液晶显示器,它的主控芯片是HD44780或者其它兼容芯片。

刚开始接触它的大多是单片机的初学者。

由于对它的不了解,不能随心所欲地对它进行驱动。

经过一段时间的学习,我对它的驱动有了一点点心得,今天把它记录在这里,以备以后查阅。

与此相仿的是LCD12864液晶显示器,它是一种图形点阵显示器,能显示的内容比LCD1602要丰富得多,除了普通字符外,还可以显示点阵图案,带有汉字库的还可以显示汉字,它的并行驱动方式与LCD1602相差无几,所以,在这里花点时间是值得的。

一般来说,LCD1602有16条引脚,据说还有14条引脚的,与16脚的相比缺少了背光电源A(15脚)和地线K(16脚)。

我手里这块LCD1602的型号是HJ1602A,是绘晶科技公司的产品,它有16条引脚。

如图1所示:图1再来一张它的背面的,如图2所示:图2引脚号符号引脚说明引脚号符号引脚说明1VSS电源地9D2数据端口2VDD电源正极10D3数据端口3VO偏压信号11D4数据端口4RS命令/数据12D5数据端口5RW读/写13D6数据端口6E使能14D7数据端口7D0数据端口15A背光正极8D1数据端口16K背光负极对这个表的说明:1. VSS接电源地。

2. VDD 接+5乂3. VO是液晶显示的偏压信号,可接10K的3296精密电位器。

或同样阻值的RM065/RM063蓝白可调电阻。

见图3。

V0VDD|------------- ---------------------------- 卜VSS10K图34. RS是命令/数据选择引脚,接单片机的一个I/O,当RS为低电平时,选择命令;当RS为高电平时,选择数据。

5. RW是读/写选择引脚,接单片机的一个I/O,当RW为低电平时,向LCD1602写入命令或数据;当RW为高电平时,从LCD1602读取状态或数据。

基于VHDL的LCD1602控制

基于VHDL的LCD1602控制
I’ p o os d t c i v h o u e d s ly c nr lse y se , n hec a a tron t c e n o t r p e o a h e et em d l ip a o to tp b t p a d t h r ce s r e fa LCD 6 2 d s S he 1 0 i— p a u p swe l sv ro fe ta er aie y t em eh . l yo t ut l a a i use f c r e lz db h t od a Key wor ds: LCD 1 0 VHDL: mi g 6 2: Ti n
如表二 所示 。
whe e d s > LCD Daa ” 0 011 0” 一/ n s t ip t < 0 0 0 :
关键 词 : C 6 2 V L D1 0 ; HDL 时序 ;
中 图分类 号 : P 9 T 31
文 献标识 码 : A
文章编 号 :6 14 9 ( 0 2 0 — 100 1 7 —7 2 2 1 )60 0 .4
Ab tac :LCD 6 2 i o sr t 1 0 sac mm o l e i ui r sa i ly mod l . c d ngt h t s e to h r n yus d lq d c y t ld  ̄ a u e Ac or i o t edaa h e fa c a —
a d h to f s g DL ( r— g —p e tgae i ut ad ae sr t nL n u g) oc nr1 n e h do i t me u n VH Ve Hi S edI e tdCr iH rw r ci i a g a e t o t . y h nr c De p o o

液晶LCD1602驱动代码

液晶LCD1602驱动代码

液晶LCD1602驱动代码液晶LCD1602简介LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。

它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。

不同厂家生产的LCD1602芯片可能有所不同,但使用方法都是一样的。

为了降低成本,绝大多数制造商都直接将裸片做到板子上。

各引脚的功能介绍如下。

1、引脚1:VSS 为地电源。

2、引脚2:VDD 接5V 正电源。

3、引脚3:VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”现象,使用时可以通过一个10kQ 的电位器调整其对比度。

4、引脚4:RS 为寄存器选择脚,高电平时选择数据寄存器、低电平时选择指令寄存器。

5、引脚5:R/W 为读/写信号线,高电平时进行读操作,低电平时进行写操作。

当RS 和R/W 共同为低电平时可以写入指令或显示地址;当RS 为低电平,R/W 为高电平时,可以读忙信号;当RS 为高电平,R/W 为低电平时,可以写入数据。

6、引脚6:E 端为使能端,当E 端由高电平跳变为低电平时,液晶模块执行命令。

7、引脚7~14:D0~D7为8位双向数据线。

8、引脚15:背光源正极。

9、引脚16:背光源负极。

液晶LCD1602驱动源代码/***********************LCD驱动基本代码************************ 单片机:51单片机* 开发环境:keil uVision3* 名称:1602驱动基本代码**************************************************************/#include<reg51.h> //包含头文件#include<intrins.h>#define LCD_Data P0#define Busy 0x80sbit LCD_RS = P1^0;sbit LCD_RW = P1^1;sbit LCD_E = P2^5;unsigned char code welcome[] = {"YOU ARE WELCOME"};unsigned char code mcu[] = {"SL-51A"};void Delay5Ms(void);void WriteDataLCD(unsigned char WDLCD);void WriteCommandLCD(unsigned char WCLCD,BuysC);unsigned char ReadDataLCD(void);unsigned char ReadStatusLCD(void);void LCDInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); void Info_display(void);/*************************5ms延时函数***************************/void Delay5Ms(void){unsigned int TempCyc = 3552;while(TempCyc--);}/**************************写数据函数***************************/void WriteDataLCD(unsigned char WDLCD){ReadStatusLCD(); //检测忙LCD_Data = WDLCD;LCD_E = 0; //若晶振速度太高可以在这后加小的延时 LCD_E = 0; //延时LCD_RS = 1;LCD_RW = 0;LCD_E = 1;LCD_E = 0;}/*************************写指令函数****************************/void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCD(); //根据需要检测忙LCD_Data = WCLCD;LCD_E = 0;LCD_E = 0;LCD_RS = 0;LCD_RW = 0;LCD_E = 1;LCD_E = 0;}/**************************读状态函数***************************/ unsigned char ReadStatusLCD(void){LCD_Data = 0xFF;LCD_RS = 0;LCD_RW = 1;LCD_E = 0;LCD_E = 0;LCD_E = 1;while (LCD_Data & Busy); //检测忙信号return(LCD_Data);}/***************************LCD初始化***************************/void LCDInit(void) //LCD初始化{LCD_Data = 0;WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置, 开始要求每次检测忙信WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); //显示光标移动设置WriteCommandLCD(0x0C,1); //显示开及光标设置}/**********************按指定位置显示一个字符*********************/void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(DData);}/***********************按指定位置显示一串字符********************/void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) {unsigned char ListLength;ListLength = 0;Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]>=0x20) //若到达字串尾则退出{if (X <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;X++;}}}void main(void){LCDInit();DisplayListChar(5,0,mcu);DisplayListChar(0,1,welcome); while(1){;}}。

LCD1602显示屏的驱动设置及例程

LCD1602显示屏的驱动设置及例程

LCD1602显示屏的驱动设置及例程一般来说,LCD1602有16条引脚,据说还有14条引脚的,与16脚的相比缺少了背光电源A(15脚)和地线K(16脚)。

我手里这块LCD1602的型号是HJ1602A,是绘晶科技公司的产品,它有16条引脚。

如图1所示:图1再来一张它的背面的,如图2所示:引脚号符号引脚说明引脚号符号引脚说明1 VSS 电源地9 D2 数据端口2 VDD 电源正极10 D3 数据端口3 VO 偏压信号11 D4 数据端口4 RS 命令/数据12 D5 数据端口5 RW 读/写13 D6 数据端口6 E 使能14 D7 数据端口7 D0 数据端口15 A 背光正极图2它的16条引脚定义如下:对这个表的说明:1. VSS接电源地。

2. VDD接+5V。

3. VO是液晶显示的偏压信号,可接10K的3296精密电位器。

或同样阻值的RM065/RM063蓝白可调电阻。

见图3。

图34. RS是命令/数据选择引脚,接单片机的一个I/O,当RS为低电平时,选择命令;当RS为高电平时,选择数据。

5. RW是读/写选择引脚,接单片机的一个I/O,当RW为低电平时,向LCD1602写入命令或数据;当RW为高电平时,从LCD1602读取状态或数据。

如果不需要进行读取操作,可以直接将其接VSS。

6. E,执行命令的使能引脚,接单片机的一个I/O。

7. D0—D7,并行数据输入/输出引脚,可接单片机的P0—P3任意的8个I/O口。

如果接P0口,P0口应该接4.7K—10K的上拉电阻。

如果是4线并行驱动,只须接4个I/O 口。

8. A背光正极,可接一个10—47欧的限流电阻到VDD。

9. K背光负极,接VSS。

见图4所示。

8 D1 数据端口16 K 背光负极图4二.基本操作LCD1602的基本操作分为四种:1. 读状态:输入RS=0,RW=1,E=高脉冲。

输出:D0—D7为状态字。

2. 读数据:输入RS=1,RW=1,E=高脉冲。

verilog驱动LCD1602显示

verilog驱动LCD1602显示

module lcd(clk,rst,test_mode,lcd_data_in,RS,RW,cont,en,lcd_data_out); input clk,rst;input [1:0] test_mode;input [15:0] lcd_data_in;output RS,RW,cont,en;output [7:0] lcd_data_out;wire en_out;reg RS,RW;reg[3:0] count;reg[7:0] lcd_data_out;reg[3:0] state;wire clk_out,clk_en,cont;reg en_tmp;parameter Warmup = 4'b0000,Funcset = 4'b0001,Dspoff = 4'b0011,Clsdsp = 4'b0010,Modeset = 4'b0110,Dspon = 4'b0111,Setaddr1 = 4'b0101,Indata1 = 4'b0100,Setaddr2 = 4'b1101,Indata2 = 4'b1100,Idle = 4'b1000;clkdiv U1(clk,clk_out);assign cont = 1'b0;always @(posedge clk or negedge rst)if(~rst)en_tmp<=1'b0;elseen_tmp<=clk_out;assign en= ~clk_out & en_tmp;assign clk_en = ~en_tmp & clk_out;always@(posedge clk or negedge rst)beginif(!rst)begincount<=0;state<=Warmup;endelsebegincase(state)Warmup:beginif(clk_en)begin if(count==4'b0111)beginstate<=Funcset;count<=0;endelsebeginstate<=Warmup;count<=count+4'b0001;endendendFuncset:beginif(clk_en)begin if(count==4'b1111)beginstate<=Dspoff;count<=0;endelsebeginstate<=Funcset;count<=count+4'b0001;endendendDspoff:state<=Clsdsp;Clsdsp:beginif(clk_en)beginif(count==4'b0101)beginstate<=Modeset;count<=0;endelsebeginstate<=Clsdsp;count<=count+4'b0001;endendendModeset: beginif(clk_en) state<=Dspon;endDspon:beginif(clk_en)beginif(count==4'b0100)beginstate<=Setaddr1;count<=0;endelsebeginstate<=Dspon;count<=count+4'b0001;endendendSetaddr1: begin if(clk_en) state<=Indata1;endIndata1:beginif(clk_en)beginif(count==4'b1110)beginstate<=Setaddr2;count<=0;endelsebeginstate<=Indata1;count<=count+4'b0001;endendendSetaddr2:begin if(clk_en) state<=Indata2;endIndata2:beginif(clk_en)beginif(count==4'b1111)beginstate<=Setaddr1;count<=0;endelsebeginstate<=Indata2;count<=count+4'b0001;endendenddefault:state<=Warmup;endcaseendendalways @(state or count)begincase(state)Warmup: beginRS<=0;RW<=0; lcd_data_out<=8'b00000000;endFuncset:lcd_data_out<=8'b00111000;Dspoff: lcd_data_out<=8'b00001000;Clsdsp: lcd_data_out<=8'b00000001;Modeset:lcd_data_out<=8'b00000110;Dspon: lcd_data_out<=8'b00001100;Setaddr1:beginRS<=0;RW<=0; lcd_data_out<=8'b10000000;endIndata1:beginRS<=1;RW<=0;case(count)4'b0000:lcd_data_out<=8'b00100000;4'b0001:lcd_data_out<=8'b01010011;4'b0010:lcd_data_out<=8'b01000011;4'b0011:lcd_data_out<=8'b01001111; 4'b0100:lcd_data_out<=8'b01010000; 4'b0101:lcd_data_out<=8'b01000101;4'b0110:lcd_data_out<=8'b00111010;4'b0111:begincase(test_mode)2'b00:lcd_data_out<=8'b00110000;2'b01:lcd_data_out<=8'b00110000;2'b10:lcd_data_out<=8'b00110010;2'b11:lcd_data_out<=8'b00110000; default: lcd_data_out<=8'b00111100; endcaseend4'b1000:begincase(test_mode)2'b00:lcd_data_out<=8'b00110000;2'b01:lcd_data_out<=8'b00101101;2'b10:lcd_data_out<=8'b00110000;2'b11:lcd_data_out<=8'b00101110; default: lcd_data_out<=8'b00100000; endcaseend4'b1001:case(test_mode) 2'b00:lcd_data_out<=8'b00110000;2'b01:lcd_data_out<=8'b00110010;2'b10:lcd_data_out<=8'b00101101;2'b11:lcd_data_out<=8'b00110010;default: lcd_data_out<=8'b00100000; endcase4'b1010:case(test_mode)2'b00:lcd_data_out<=8'b00110000;2'b01:lcd_data_out<=8'b00110000;2'b10:lcd_data_out<=8'b00110010;2'b11:lcd_data_out<=8'b00101101; default: lcd_data_out<=8'b00100000; endcase4'b1011:case(test_mode) 2'b00:lcd_data_out<=8'b01101101;2'b01:lcd_data_out<=8'b01101101;2'b10:lcd_data_out<=8'b00110000;2'b11:lcd_data_out<=8'b00110010; default: lcd_data_out<=8'b00100000; endcase4'b1100:case(test_mode)2'b00:lcd_data_out<=8'b01000001;2'b01:lcd_data_out<=8'b01000001;2'b10:lcd_data_out<=8'b00110000;2'b11:lcd_data_out<=8'b00101110; default:lcd_data_out<=8'b00100000; endcase4'b1101:case(test_mode)2'b00:lcd_data_out<=8'b00100000;2'b01:lcd_data_out<=8'b00100000;2'b10:lcd_data_out<=8'b01101101;2'b11:lcd_data_out<=8'b00110000; default:lcd_data_out<=8'b00100000; endcase4'b1110:case(test_mode)2'b00:lcd_data_out<=8'b00100000;2'b01:lcd_data_out<=8'b00100000;2'b10:lcd_data_out<=8'b01000001;2'b11:lcd_data_out<=8'b01000001; default:lcd_data_out<=8'b00100000; endcasedefault:lcd_data_out<=8'b00100000;endcaseendSetaddr2:beginRS<=0;RW<=0; lcd_data_out<=8'b11000000;endIndata2:beginRS<=1;RW<=0;case(count) 4'b0000:lcd_data_out<=8'b00100000; 4'b0001:lcd_data_out<=8'b01001001;4'b0010:lcd_data_out<=8'b01101111;4'b0011:lcd_data_out<=8'b01110101; 4'b0100:lcd_data_out<=8'b01110100;4'b0101:lcd_data_out<=8'b00111101;4'b0110:beginif(test_mode[1] & test_mode[0])lcd_data_out<={4'b0011,lcd_data_in[15:12]};else if(~test_mode[1] & test_mode[0])lcd_data_out<={4'b0011,lcd_data_in[11:8]};else lcd_data_out<=8'b00100000;end4'b0111: lcd_data_out<={4'b0011,lcd_data_in[11:8]};4'b1000:begin if(~test_mode[1] & test_mode[0]) lcd_data_out<=8'b00101110;else lcd_data_out<={4'b0011,lcd_data_in[7:4]};end 4'b1001:lcd_data_out<={4'b0011,lcd_data_in[3:0]};4'b1010:lcd_data_out<=8'b01101101;4'b1011:lcd_data_out<=8'b01000001;default:lcd_data_out<=8'b00100000;endcaseenddefault:lcd_data_out<=8'bzzzzzzzz;endcaseendendmodulemodule clkdiv(clk_in,clk_out);input clk_in;output clk_out;reg clk_out;reg[15:0] count;always@(posedge clk_in)beginif(count==15'b111111*********)beginclk_out<=~clk_out;count<=0;endelsecount<=count+15'b0000_0000_0000_001; endendmodule。

lcd1602 C语言驱动

lcd1602 C语言驱动

/*LCD1602驱动程序*//*程序用法:1、按行显示:display(行号,数据指针)2、定位显示:displayUser(行号,列号,字符/字符串)3、动态显示:Ddisplay(行号、列号、字符/字符串)4、闪烁显示:Fldisplay(行号、列号、字符/字符串)*//*声明代码(放工程中需要包含的自定义头文件中):void delay(unsigned char n);void init();void display(unsigned char a,unsigned char table[]);void write_date(uchar);void write_command(uchar);void displayUser(unsigned char hang,unsigned lie,unsigned char table[]); void Ddisplay(unsigned char hang,unsigned lie,unsigned char table[]); void Fldisplay(unsigned char hang,unsigned lie,unsigned char table[]); */#include <reg51.h>#define uchar unsigned charsbit rs=P2^4;sbit rw=P2^5;sbit e=P2^6;uchar busyc,line;void delay(uchar n){uchar x,y;for(x=n;x>0;x--)for(y=110;y>0;y--);}void busy(uchar busyc){rs=0;rw=1;e=1;delay(1);busyc=P0;e=0;}void write_command(uchar command) {busy(busyc);while(busyc); //判断LCD 是否冗忙rs=0;rw=0;e=1;P0=command;delay(10);e=0;}void write_date(uchar date){busy(busyc);while(busyc); //判断LCD 是否冗忙rs=1;rw=0;e=1;P0=date;delay(10);e=0;}void init(){e=0;write_command(0x38);delay(15);write_command(0x0c);write_command(0x06);write_command(0x01);}void display(unsigned int a,unsigned char *table){uchar i;if(a==1){write_command(0x80); //设置显示位置(第一行开头)for(i=0;i<16;i++)write_date(*(table+i)); //显示字符}if(a==2){write_command(0xc0); //设置显示位置(第二行开头)for(i=0;i<16;i++)write_date(*(table+i)); //显示字符}}void displayUser(unsigned char hang,unsigned lie,unsigned char table[])和列号//定位显示,定位行号{unsigned char add,i;if(hang==1){add=0x80+lie-1;}if(hang==2){add=0xc0+lie-1;}write_command(add);for(i=0;i<(add%15);i++)write_date(table[i]); //显示字符}void Ddisplay(unsigned char hang,unsigned lie,unsigned char table[]) //动态、定位显示,定位行号和列号{unsigned char add,i,m;if(hang==1){add=0x80+lie-1;}if(hang==2){add=0xc0+lie-1;}write_command(add);for(i=0;i<(add%15);i++){write_date(table[i]); //显示字符for(m=0;m<4;m++)delay(250);}}void Fldisplay(unsigned char hang,unsigned lie,unsigned char table[])//闪烁、定位显示,定位行号和列号{unsigned char add,i;if(hang==1){add=0x80+lie-1;}if(hang==2){add=0xc0+lie-1;}write_command(add);while(1){for(i=0;i<(add%15);i++){write_date(table[i]); //显示字符}delay(250);delay(250);delay(250);write_command(0x01); delay(250);delay(250);delay(250);}}。

LCD1602四线驱动的方法

LCD1602四线驱动的方法

LCD1602四线驱动的方法一、硬件连接:见下图,图图中LCD1602的高四位DB7-DB4和RS、E端接到单片机的6个I/O 口,R/W 接地。

这种连接方法只能向LCD写入指令和数据,而不能从LCD中读出数据。

单片机引脚的接法可以根据要求改变。

二、驱动说明:1、当E = 0时,数据位和RS位和P4~P7位可以改变2、当E = 1时,数据位内容被写入LCD3、当RS = 0时,写入的为指令4、当RS = 1时,写入的为数据(地址)三、驱动流程:1、写入指令:1)EN = 0 (LCD使能禁止)2)短延时3)RS = 0 (准备写入指令)4)DATA = 指令的高4位(A TA代表D7、D6、D5、D4,下同)5)短延时6)EN = 1 (LCD使能允许,指令写入)7)短延时8)EN = 0 (LCD使能禁止)9)DATA = 指令的低4位10)短延时11)EN = 1 (LCD使能允许,指令写入)12)短延时13)EN = 0 (LCD使能禁止)14)短延时2、写入数据:1)EN = 0 (LCD使能禁止)2)短延时3)RS = 1 (准备写入数据)4)DATA = 数据的高4位5)短延时6)EN = 1 (LCD使能允许,数据写入)7)短延时8)EN = 0 (LCD使能禁止)9)DATA = 数据的低4位10)短延时11)EN = 1 (LCD使能允许,数据写入)12)短延时13)EN = 0 (LCD使能禁止)14)短延时四、指令的格式:。

LCD1602驱动编程(二)——驱动程序编写

LCD1602驱动编程(二)——驱动程序编写
Void LCD_DispStr( uchar x, uchar y, char *p) { if (x!=0x00&&y!=0x00) {
switch( y) {
case 1:LCD_WriteCommand(0x80+x-1);break; //第一行 case2:LCD_WriteCommand(0x80+0x40+x-1); break; //第二行
7. 初始化 void LCD_Initial( void ) { LCD_WriteCommand(0x38); //4 位总线,5*10 点阵字符 LCD_WriteCommand(0x01); //清屏 LCD_WriteCommand(0x06); //显示光标,光标右移 LCD_WriteCommand(0x0c); //开显示 }
8. 滚动字符 Void Character_move( void ) { LCD_WriteCommand(0x18); //字符左移 LCD_WriteCommand(0x1C); //字符右移 }
{
P0=0x00;
RS_SET_C; //数据总线
RW_SET_W; //操作
EN_SET_L;
_NOP( );
//tps1
EN_SET_H; //拉高使能端
while(P0&0x80); } 4. 清屏 Void LCD_Clear( void ) {
Read_busy( ); //判忙 LCD_WriteCommand(0x01) ; DelayMs(5); } 5. 显示字符串
{
Read_busy( ); //判忙
RS_SET_C; //命令总线
RW_SET_R; //写操作

LCD1602VHDL程序

LCD1602VHDL程序
constant cgram1:ram1:=(x"46",x"50",x"47",x"41",x"2f",x"43",x"50",x"4c",x"44",x"20",x"73",x"74",x"75",x"64",x"79",x"20",x"20",x"42",x"79",x"20",x"4d",x"49",x"41",x"4f",x"53",x"48",x"41",x"4e",x"4c",x"49",x"4e");
if n1<19999 then
n1:=n1+1;
else
n1:=0;
Clk_Out<=not Clk_Out;
end if;
end if;
end process;
LCD_Clk <= Clk_Out;
process(Clk_Out)
LCD_RS <= '0';
case Current_State is
when set_dlnf=>
cnt1:="00000";
LCD_Data<="00000001";

verilog驱动LCD1602程序

verilog驱动LCD1602程序
//工作方式设置1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
parameter SETCGRAM=10'b0001000000;//设置CGRAM
parameter SETDDRAM1=10'b0010000001;//设置DDRAM
parameter SETDDRAM2=10'b0010000010;//设置DDRAM
state<=SWITCHMODE;end
SWITCHMODE:begin LCD_RS<=0;LCD_RW<=0;LCD_D[7:3]<=5'b00001; //显示状态开关设置0C
LCD_D[2]<=open_display;LCD_D[1]<=open_cur;
LCD_D[0]<=blank_cur;
end
endcase
end
endmodule
下面是testbench代码
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company: HITsz
最近在网上找了很多用verilog驱动LCD1602的程序,但基本没有一个是完美运行,很多论坛所谓大神的代码综合时候一样很多缺陷,要知道每一个warning都有可能是导致最终失败的原因。于是乎只能自己下功夫,找到一个稍微靠谱的开发板配套例程,但是分频器模块编的叫一塌糊涂,主时钟分频后继续分频而且组合时序乱用,通过分频模块重新编写后基本无warning完美运行,仿真功能实现并且下载显示成功,后面附上了我的testbench,本人用的软件为ISE12.2,不过个人感觉quartus应该一样跑,下面是代码,需要在1602显示什么字符自己改显示函数就行,希望对大家有帮助。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

[VHDL代码]LCD1602驱动
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity LCD1602 is
Port ( Clk : in std_logic; --状态机时钟信号,同时也是液晶时钟信号,其周期应该满足液晶数据的建立时间Sec_low,Sec_high,Min_low,Min_high,Hour_low,Hour_high: in std_logic_vector(3 downto 0);
LCD_RS : out std_logic; --寄存器选择信号
LCD_RW : out std_logic; --液晶读写信号
LCD_EN : out std_logic; --液晶时钟信号
LCD_Data : out std_logic_vector(7 downto 0)); --液晶数据信号
end LCD1602;
architecture Behavioral of LCD1602 is
type STATE_TYPE is
(START,write_C,write_D,WRITE_BYTE_C,WRITE_BYTE_D,wait_3m1,wait_3m2,wait_5m1,wait_5m2,w ait_100m);
type MY_ARRAY1 is array(0 to 4) of std_logic_vector(7 downto 0);
type MY_ARRAY2 is array(0 to 7) of std_logic_vector(7 downto 0);--长度为14的8位/字数组
constant c_d: MY_ARRAY1:=(x"38",x"0c",x"06",x"01",x"84");
signal d_d: MY_ARRAY2:=(x"20",x"20",x"3A",x"20",x"20",x"3A",x"20",x"20");
signal STATE: STATE_TYPE:=START;
signal w_c_flag : integer range 0 to 2:=0;
signal w_d_flag : integer range 0 to 2:=0;
signal write_c_cnt : integer range 0 to 5:=0;
signal write_d_cnt : integer range 0 to 8:=0;
signal cnt : integer range 0 to 10000:=0;
signal count : integer range 0 to 10000:=0;
begin
LCD_RW <= '0' ; --写数据
d_d(0)<="0000"&Hour_high+x"30";
d_d(1)<="0000"&Hour_low+x"30";
d_d(3)<="0000"&Min_high+x"30";
d_d(4)<="0000"&Min_low+x"30";
d_d(6)<="0000"&Sec_high+x"30";
d_d(7)<="0000"&Sec_low+x"30";
process(Clk,STATE) --液晶驱动控制器begin
if rising_edge(Clk) then
case STATE is
when START=>
LCD_EN<='0';
w_c_flag<=0;
w_d_flag<=0;
write_c_cnt<=0;
write_d_cnt<=0;
STATE<=WRITE_C;
when WRITE_C=>
case write_c_cnt is
when 0 to 4=>
STATE<=WRITE_BYTE_C;
when 5=>
write_c_cnt<=4;
STATE<=WRITE_D;
end case;
when WRITE_BYTE_C=>
if(w_c_flag=0) then
LCD_RS<='0';
LCD_Data<=c_d(write_c_cnt);
w_c_flag<=1;
STATE<=wait_3m1;
elsif(w_c_flag=1) then
LCD_EN<='1';
w_c_flag<=2;
STATE<=wait_5m1;
elsif(w_c_flag=2) then
LCD_EN<='0';
w_c_flag<=0;
write_c_cnt<=write_c_cnt+1;
STATE<=WRITE_C;
end if;
when WRITE_D=>
case write_d_cnt is
when 0 to 7=>
STATE<=WRITE_BYTE_D;
when 8=>
write_d_cnt<=0;
STATE<=wait_100m;
end case;
when WRITE_BYTE_D=>
if(w_d_flag=0) then
LCD_RS<='1';
LCD_Data<=d_d(write_d_cnt); w_d_flag<=1;
STATE<=wait_3m2;
elsif(w_d_flag=1) then
LCD_EN<='1';
w_d_flag<=2;
STATE<=wait_5m2;
elsif(w_d_flag=2) then
LCD_EN<='0';
w_d_flag<=0;
write_d_cnt<=write_d_cnt+1; STATE<=WRITE_D;
end if;
when wait_3m1=>
if (cnt>=3) then
STATE<=WRITE_BYTE_C; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_3m1;
end if;
when wait_5m1=>
if (cnt>=5) then
STATE<=WRITE_BYTE_C; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_5m1;
end if;
when wait_3m2=>
if (cnt>=3) then
STATE<=WRITE_BYTE_D; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_3m2;
end if;
when wait_5m2=>
if (cnt>=5) then
STATE<=WRITE_BYTE_D; cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_5m2;
end if;
when wait_100m=>
if (cnt>=100) then
STATE<=START;
cnt<=0;
else
cnt<=cnt+1;
STATE<=wait_100m;
end if;
end case;
end if;
end process;
end Behavioral;。

相关文档
最新文档