[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
  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;。

相关文档
最新文档