lcd1602四线驱动

合集下载

4根IO口线驱动1602(带PWM调光)

4根IO口线驱动1602(带PWM调光)

4根IO口线驱动1602(带PWM调光)呵呵,不用我说你们也知道为什么只需要4根线:因为咱用了74hc595啊!因为74HC595最近我手里一抓一大把。

但是STC的单片机IO口紧缺。

就算使用4线驱动模式也要8个IO(还要算上背光PWM)。

这一次我几乎做到了他的一半。

如果不用PWM的话。

大概只需要3个IO,如果需要PWM就四个罗。

MCU当然是老掉牙的死特惨89C52罗~画原理图实在是不方便。

就不画了。

另外求酷~也可以在595后面级联类似三极管开关……继电器之类的玩意。

当然友情提醒,别超过4个595.否则速度会慢的可怕。

我现在1个595.写1602都可以丢掉延时函数了。

这一次硬件设计的比较简单,但是IO全反了。

所以需要占用额外的CPU时间修正,但是毕竟方便洞洞板嘛。

还有大家别看到我给A和B赋了好几次值而去“优化”代码。

如果您“优化”的话,那么就根本驱动不起来,因为51的加法减法乘除都要经过ACC和B,如果不去重新赋值的话,那么就会发生改变的现象。

不过我这种位寻址软件修正可比那种xx=xx & xx的效率高多了。

如果我这么写的话。

恐怕刷一个屏幕没1秒下不来啊。

12T的51就这个速度……不过这一次焊板子实在是太仓促了。

对比度电位器焊在液晶下面,结果初始化成功了显示两排方块。

晕了半天。

调试半天还是没用。

后来捅了一下背面就好了……晕……!上代码:#include <stc89c5x.h>//STC89C52//串行驱动1602,powered by 595#define LCD1602_BACKLIGHT P1_3//背光#define LCD1602_SDA P1_0//数据输入#define LCD1602_SCK P1_1//移位时钟,SHCP,11pin#define LCD1602_SCL P1_2//锁存时钟,STCP,12pin/** 硬件连接:* 74HC595 Q7 - 1602 RS* GND - 1602 RW(595没有输入功能,所以判定忙只能靠延时,另外就是MCU的速度比较的慢。

经典的KEIL_C51_LCD1602_4总线驱动+中文注释程序(有程序)

经典的KEIL_C51_LCD1602_4总线驱动+中文注释程序(有程序)

网上下载的资料。

因为论坛不支持.doc文件,我就直接复制上来了。

==================================================================/******************************************************************************经典的KEIL_C51_LCD1602_4总线驱动+中文注释程序文件名:1602.ccpu:STC12C5A32S2 晶振频率:11.0592Mhz编程者:BG1EQ@2011-8-25 测试通过*******************************************************************************LCD1602 实际硬件连接:LCM_RS-----P2^0; //1602定义引脚LCM_RW-----P2^1;LCM_E -----P2^7;LCM_DB0-----P0.0LCM_DB1-----P0.1LCM_DB2-----P0.2LCM_DB3-----P0.3LCM_DB4-----P0.4LCM_DB5-----P0.5LCM_DB6-----P0.6LCM_DB7-----P0.7*******************************************************************************/#include <reg52.h> //包含52头文件#include <string.h> //包含初试化头文件#include <intrins.h>//#include <stdlib.h> //包含标准函数库头文件#include "4bitlcm1602.h" //包含delay头文件#include "delay.h" //包含delay头文件#def ine uchar unsigned char#def ine uint unsigned int//------硬件端口定义--------------------------------//------函数(声明)--------------------------------void sys_init(void); //系统初始化函数(声明)/****************************************************************************************** * 函数名称:主程序* 功能描述:******************************************************************************************/ main() //主程序入口{// LCMInit(); //初始化LCDsys_init(); //系统初始化while(1){ //主程序循环(开始)LCD_cls(); //清屏DisplayListChar(0,0," MONITOR V1.0 "); //第1行显示DisplayListChar(0,1," APPLY IN CHINA "); //第2行显示Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();LCD_cls(); //清屏DisplayListChar(0,0," BG1EQ@ "); //第1行显示DisplayListChar(0,1," 2011Y 08M 25D "); //第2行显示Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();LCD_cls(); //清屏DisplayOneChar(0,0,'0'); //显示字符DisplayOneChar(1,0,'1'); //显示字符DisplayOneChar(2,0,'2'); //显示字符DisplayOneChar(3,0,'3'); //显示字符DisplayOneChar(4,0,'4'); //显示字符DisplayOneChar(5,0,'5'); //显示字符DisplayOneChar(6,0,'6'); //显示字符DisplayOneChar(7,0,'7'); //显示字符DisplayOneChar(8,0,'8'); //显示字符DisplayOneChar(9,0,'9'); //显示字符DisplayOneChar(10,0,'0'); //显示字符DisplayOneChar(11,0,'-'); //显示字符DisplayOneChar(12,0,'+'); //显示字符DisplayOneChar(13,0,'='); //显示字符DisplayOneChar(14,0,'#'); //显示字符DisplayOneChar(15,0,'$'); //显示字符Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();LCD_cls(); //清屏DisplayOneChar(0,1,'A'); //显示字符DisplayOneChar(1,1,'B'); //显示字符DisplayOneChar(2,1,'C'); //显示字符DisplayOneChar(3,1,'D'); //显示字符DisplayOneChar(4,1,'E'); //显示字符DisplayOneChar(5,1,'F'); //显示字符DisplayOneChar(6,1,'G'); //显示字符DisplayOneChar(7,1,'H'); //显示字符DisplayOneChar(8,1,'I'); //显示字符DisplayOneChar(9,1,'J'); //显示字符DisplayOneChar(10,1,'K'); //显示字符DisplayOneChar(11,1,'L'); //显示字符DisplayOneChar(12,1,'M'); //显示字符DisplayOneChar(13,1,'N'); //显示字符DisplayOneChar(14,1,'O'); //显示字符DisplayOneChar(15,1,'P'); //显示字符Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();Delay400Ms();} //主程序循环结束返回}/****************************************************************************************** * 函数名称:sys_init* 功能描述:系统初始化******************************************************************************************/ void sys_init(){Delay400Ms(); //上电后延时,让LCD1602进入稳定状态,LCMInit(); //初始化LCD1602}以上是C51主程序以下是C51 模块化4BITLCM1602.H函数程序/*--------------------------------------------------------------------------4BITLCM1602.H4位总线驱动LCD1602 头文件--------------------------------------------------------------------------*/#if ndef __4BITLCM1602_H__#def ine __4BITLCM1602_H__/*******************************************************************************///#include <reg52.h> //包含52头文件//#include <string.h> //包含初试化头文件//#include <intrins.h>//#include <stdlib.h> //包含标准函数库头文件#def ine uchar unsigned char#def ine uint unsigned int//------硬件端口定义--------------------------------sbit LCM_RS = P2^0; //1602定义引脚sbit LCM_R W = P2^1;sbit LCM_E = P2^7;sbit LCD7=P0^7;sbit LCD6=P0^6;sbit LCD5=P0^5;sbit LCD4=P0^4;uchar bdata lcdbuff; //声明,全局的、可以位寻址的变量sbit lcd_buff7=lcdbuff^7;sbit lcd_buff6=lcdbuff^6;sbit lcd_buff5=lcdbuff^5;sbit lcd_buff4=lcdbuff^4;sbit lcd_buff3=lcdbuff^3;sbit lcd_buff2=lcdbuff^2;sbit lcd_buff1=lcdbuff^1;sbit lcd_buff0=lcdbuff^0;//------函数(声明)--------------------------------void LCMInit(void); //LCM屏初始化void R_BF(); //读忙标志BFvoid w_com(uchar com); //写指令函数void w_cdata(void); //写数据函数void WriteDataLCM(unsigned char WDLCM); //LCM屏写数据函数(声明)void LCD_cls(void); //LCM屏清屏void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);/******************************************************************************************* 函数名称:WriteDataLCM* 功能描述:LCM写数据******************************************************************************************/void WriteDataLCM(uchar WDLCM){R_BF();lcdbuff = WDLCM;LCM_RS = 1;LCM_R W = 0;w_cdata(); //这里写入字符码}/****************************************************************************************** * 函数名称:DisplayListChar* 功能描述:按指定位置显示一串字符,原来的遇到空格0x20就不显示* 函数说明:******************************************************************************************/ void DisplayListChar(uchar X, uchar Y, uchar code *DData){uchar ListLength,j; //定义局部变量ListLength = strlen(DData); //读取字符串长度X &= 0xF; //限制X不能大于15 Y &= 0x1; //限制Y不能大于1 if (X <= 0xF)//X坐标应小于0xF{f or(j=0;j<ListLength;j++){DisplayOneChar(X, Y, DData[j]); //显示单个字符X++;}}}/****************************************************************************************** * 函数名称:DisplayOneChar* 功能描述:按指定位置显示一个字符* 函数说明:******************************************************************************************/ void DisplayOneChar(uchar X, uchar Y, uchar DData){X &= 0xF; //限制X不能大于15Y &= 0x1; //限制Y不能大于1if (Y) X |= 0x40; //如果Y是“1”,则合成显示第二行时地址码+0x40;X |= 0x80; //合成的、显示位置码,指令码:1Yxx xxxx (B)w_com(X); //写入地址码,X数据包含字符的显示位置WriteDataLCM(DData); //写入数据码,要显示的字符数据}/****************************************************************************************** * 函数名称:LCMInit* 功能描述:LCM初始化* 函数说明:LCM初始化******************************************************************************************/ void LCMInit(void){w_com(0x2c); //功能设置为:四位数据总线w_com(0x01); //清屏w_com(0x06); //设置显示输入模式(A C指针自加1,显示不移位)w_com(0x0c); //显示开/关设置(设置显示、光标和闪烁开关)}/****************************************************************************************** * 函数名称:R_BF* 功能描述:读忙标志BF* 函数说明:读忙标志BF*******************************************************************************************/ void R_BF(){LCD7=1; //BF端口在DB7,置LCD7为“1”等待测试本端口电平LCM_RS=0;LCM_R W=1;LCM_E=1; //RS=0;R W=1;E=1表示读忙标志BFwhile(LCD7); //若内部操作位BF忙CPU就等待BF不忙才能操作LCM_E=0;}/****************************************************************************************** * 函数名称:w_com* 功能描述:写命令* 函数说明:主要用来初始化一些设置显示、输入模式、显示开关、光标、移位、功能、地址*******************************************************************************************/ void w_com(uchar com){R_BF();lcdbuff = com;LCM_RS = 0;LCM_R W = 0;w_cdata();}/****************************************************************************************** * 函数名称:w_cdata* 功能描述:写命令的公共* 函数说明:四位数据总线, 每发送一字节,先发送高四位,再发送低四位*******************************************************************************************/ void w_cdata(void){//-----写命令的高4位LCD7 = lcd_buff7;LCD6 = lcd_buff6;LCD5 = lcd_buff5;LCD4 = lcd_buff4;LCM_E = 1;_nop_();LCM_E = 0;_nop_();_nop_();//-----写命令的低4位LCD7 = lcd_buff3;LCD6 = lcd_buff2;LCD5 = lcd_buff1;LCD4 = lcd_buff0;LCM_E = 1;_nop_();LCM_E = 0;}/****************************************************************************************** * 函数名称:LCD_cls* 功能描述:LCM清屏*******************************************************************************************/void LCD_cls(void){w_com(0x01); //清屏}#endi f以下是C51 模块化DELA Y.H 函数程序/*--------------------------------------------------------------------------DELA Y.H延时函数头文件--------------------------------------------------------------------------*/#if ndef __DELA Y_H__#def ine __DELA Y_H__#def ine uchar unsigned char#def ine uint unsigned int//------函数(声明)--------------------------------void Delay400Ms(void); //延时400mS函数(子程序)/******************************************************************************************* 函数名称:Delay400Ms* 功能描述:400ms延时******************************************************************************************/ void Delay400Ms(void){uchar TempCycA = 30; //1周期MPU用30, 12周期MPU用5uint TempCycB;while(TempCycA--){TempCycB=7269;while(TempCycB--);};}#endi f。

1602的AVR的C驱动(4线方式)

1602的AVR的C驱动(4线方式)

1602的AVR的C驱动(4线方式)2009-06-19 21:03参考了OURAVR的程序,自己写了一个,加上光标和屏幕滚动代码#define LCD_EN_PORT PORTA //以下2个要设为同一个口#define LCD_EN_DDR DDRA#define LCD_RS_PORT PORTA //以下2个要设为同一个口#define LCD_RS_DDR DDRA#define LCD_DATA_PORT PORTA //以下3个要设为同一个口#define LCD_DATA_DDR DDRA //一定要用高4位#define LCD_DATA_PIN PINA#define LCD_RS (1<<PA1) //0x02 portA1 out#define LCD_EN (1<<PA3) //0x08 portA3 out#define LCD_DATA ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7))//0xf0 portA4/5/6/7 outuchar LCD="1" ; //是否让LCD显示 0,不显示;;;1显示/*--------------------------------------------------------------------------------------------------函数说明--------------------------------------------------------------------------------------------------*/void LCD_init(void);void LCD_en_write(void);void LCD_write_command(unsigned char command) ;void LCD_write_data(unsigned char data);void LCD_set_xy (unsigned char x, unsigned char y);void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s); void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data);void LCD_Init(void) //液晶初始化{LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出LCD_EN_DDR|=LCD_EN; //设置EN方向为输出LCD_RS_DDR|=LCD_RS; //设置RS方向为输出CLI();PORTA&=~0x04;//RW=0DDRA=0xff;LCD_write_command(0x30);Delay_nms(10);LCD_write_command(0x30);Delay_nms(5);LCD_write_command(0x30);Delay_nms(5);LCD_write_command(0x28);//写指令,4位数据线,5*10字体LCD_en_write();Delay_nms(4);LCD_write_command(0x28); //4位显示LCD_en_write();LCD_write_command(0x0c); //显示开光标关,字符不闪烁LCD_en_write();SEI();Delay_nms(2);}void LCD_en_write(void) //液晶使能{LCD_EN_PORT|=LCD_EN; //Delay_nus(1);LCD_EN_PORT&=~LCD_EN; // 给出下降沿}void LCD_write_command(unsigned char command) //写指令 E下降,RS=0,RW=0{Delay_nms(6);LCD_RS_PORT&=~LCD_RS; //RS=0LCD_DATA_PORT&=0X0f; //清高四位LCD_DATA_PORT|=command&0xf0; //写高四位LCD_en_write(); //E下降command="command"<<4; //低四位移到高四位LCD_DATA_PORT&=0x0f; //清高四位LCD_DATA_PORT|=command&0xf0; //写这次低四位到数据线高4位LCD_en_write();}void LCD_write_data(unsigned char data) //写数据 E下降,RS=1,RW=0 {Delay_nms(6);LCD_RS_PORT|=LCD_RS; //RS=1LCD_DATA_PORT&=0X0f; //清高四位LCD_DATA_PORT|=data&0xf0; //写高四位LCD_en_write();data="data"<<4; //低四位移到高四位LCD_DATA_PORT&=0X0f; //清高四位LCD_DATA_PORT|=data&0xf0; //写低四位LCD_en_write();}void LCD_set_xy( unsigned char x, unsigned char y ) //写地址函数{unsigned char address;if (y == 0) address = 0x80 + x; // 最高位是1,另七位才是地址故有+0x80else address = 0xc0 + x;LCD_write_command( address);}void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1{LCD_set_xy( X, Y ); //写地址while (*s) // 写显示字符{LCD_write_data( *s );s ++;}}void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1{LCD_set_xy( X, Y ); //写地址LCD_write_data( data);}/*光标移动*/void CursorScroll(void){LCD_write_command(0x10); //光标左移}/*画面滚动*/void ScreenScroll(void){//while(1){LCD_write_command(0x18); //画面左滚Delay_nms(300);}}。

lcd1602四线驱动

lcd1602四线驱动
else address = 0xc0 + x;
LCD_write_command(address);
}
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata)//列x=0~15,行 y=0,1
{
LCD_set_xy(X, Y);//写地址
void delay_nms(unsigned int n);
//以下函数用于输出数字
int LCD_PutNum(unsigned long num,int XS,int pos);
int LCD_PutStr(unsigned char *DData,int pos);
void delay_1us(void) //1us延时函数
{LCD_write_command(0x01);
delay_nms(2);
pos=0;
}
if(num==0)
{
LCD_write_char(pos%16, pos/16, '0'); pos++;
}
else
{
if(num<0)
{LCD_write_char(pos%16, pos/16, '-');
/*
单片机I/O口使单片机资源的重要组成部分,也是用来扩展外围设备的必选资源,
尽可能以更少的I/O口实现更多的功能是单片机工程师追求的目标,现在的一些串
行器件也为这一目标的实现添加了更多的可能性,比如I2C总线,MAXIM力推

1-WIRE 等等,都可以以很少的I/O口实现更多的功能,当然这是以降低一定的 速度

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)。

基于msp430g2553的1602四线驱动C源码

基于msp430g2553的1602四线驱动C源码

/*--------------------------------------------------------------*/基于msp430G2553de LCD1602四线驱动由于G2系列的IO口过于少,所以我们采用了四线驱动LCD1602的方法程序附后①液晶显示原理液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。

液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。

②液晶显示器的分类液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。

除了黑白显示外,液晶显示器还有多灰度有彩色显示等。

如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。

③液晶显示器各种图形的显示原理:线段的显示点阵图形式液晶由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)=00H,……(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。

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

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

1602 四线制驱动程序

1602 四线制驱动程序

/************************************************************************** 1602 四线制驱动程序--基于MSP430F149File Name: LCD1602x4_mps.hAuthor: HuNB***************************************************************************/#include<msp430x14x.h>#define set(x) P6OUT |=x#define clr(x) P6OUT &=~x#define rs BIT2 //RA1#define rw BIT3 //RA2#define e BIT4 //RA3/*--------------------------------------------------------------------------------------------------函数说明--------------------------------------------------------------------------------------------------*/void init(); //申明I/O口初始化函数void delay_nus(unsigned int n); //N nS延时函数void delay_nms(unsigned int n); //N mS延时函数void LCD_init(void); //LCD初始化函数void LCD_en_write(void); //LCD写入使能函数void LCD_write_command(unsigned char command) ; //LCD写入命令函数void LCD_write_data(unsigned char Recdata); //LCD写入数据函数void LCD_set_xy (unsigned char x, unsigned char y); //LCD设置显示位置函数void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata); //LCD显示字符函数int LCD_PutStr(unsigned char *DData,int pos); //LCD显示字符串函数//int LCD_PutNum(unsigned long num,int XS,int pos);//LCD显示数字函数int p=0;//---------------------------------------//---------------------------------------//I/O口初始化函数void init(){//ADCON1=0X07; //设置A口为普通I/O口//TRISA=0X00; //设置A口为输出//TRISD=0X00; //设置D口为输出P4DIR=0xff;P6DIR=0x1c; //设置A口为输出WDTCTL = WDTPW + WDTHOLD; //杀狗}void delay_1us(void) //1us延时函数{_NOP();}void delay_nus(unsigned int n) //N us延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1us();}void delay_1ms(void) //1ms延时函数{unsigned int i;for (i=0;i<1140;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i=0;for (i=0;i<n;i++)delay_1ms();}void LCD_en_write(void) //液晶使能{set(e);delay_nus(1);clr(e);}void LCD_write_command(unsigned char command) //写指令{unsigned char temp;temp=command>>4; //高四位移到低四位delay_nus(16);clr(rs); //RS=0 选择指令地址clr(rw); //RW=0 写操作P4OUT&=0Xf0; //清低四位P4OUT|=temp&0x0f; //写高四位//command&0x0f;LCD_en_write();P4OUT&=0xf0; //清高四位P4OUT|=command&0x0f; //写低四位LCD_en_write();set(rw); //RW=1 结束写操作}void LCD_write_data(unsigned char Recdata) //写数据{ unsigned char temp;temp=Recdata>>4; //高四位移到低四位delay_nus(16);set(rs); //RS=1 选择数据地址clr(rw); //RW=0 写操作P4OUT&=0Xf0; //清高四位P4OUT|=temp&0x0f; //Recdata&0xf0写高四位LCD_en_write();// Recdata=Recdata<<4; //低四位移到高四位P4OUT&=0Xf0; //清高四位P4OUT|=Recdata&0x0f; //写低四位LCD_en_write();set(rw); //RW=1 结束写操作}void LCD_set_xy( unsigned char x, unsigned char y ) //写地址函数{unsigned char address;if (y == 0) address = 0x80 + x;else address = 0xc0 + x;LCD_write_command(address);}void LCD_init(void) //液晶初始化{LCD_write_command(0x28);delay_nus(40);LCD_write_command(0x28);delay_nus(40);LCD_write_command(0x28);delay_nus(40);LCD_en_write();delay_nus(40);LCD_write_command(0x28); //4位显示LCD_write_command(0x0c); //显示开LCD_write_command(0x01); //清屏delay_nms(5);}void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata) //列x=0~15,行y=0,1{LCD_set_xy(X, Y); //写地址LCD_write_data(Recdata);}int LCD_PutStr(unsigned char *DData,int pos){unsigned char i;if(pos==-1){LCD_write_command(0x01); //清屏delay_nms(2);pos=0;}while((*DData)!='\0'){switch(*DData){case '\n': //如果是\n,则换行{if(pos<17){for(i=pos;i<16;i++)LCD_write_char(i%16, i/16, ' ');pos=16;}else{for(i=pos;i<32;i++) LCD_write_char(i%16, i/16, ' ');pos=32;}break;}case '\b': //如果是\b,则退格{if(pos>0) pos--;LCD_write_char(pos%16, pos/16, ' ');break;}default:{if((*DData)<0x20){*DData=' ';}LCD_write_char(pos%16, pos/16,*DData);pos++;break;}}DData++;}return(pos);}/*----------------------------以下函数用于输出数字---------------------int LCD_PutNum(unsigned long num,int XS,int pos){ //从右边数,保留几位小数unsigned long tmp=0;unsigned char numbits=0;if(pos==-1){LCD_write_command(0x01);delay_nms(2);pos=0;}if(num==0){LCD_write_char(pos%16, pos/16, '0');pos++;}else{if(num<0){LCD_write_char(pos%16, pos/16, '-');num*=(-1);pos++;}while(num){tmp=tmp*10+(num%10);num=num/10;numbits++;}while(tmp){LCD_write_char(pos%16, pos/16, (tmp%10)+48);tmp=tmp/10;pos++;numbits--;if(numbits==XS) pos=LCD_PutStr(".",pos); //显示小数点 }while(numbits--){LCD_write_char(pos%16, pos/16, '0');pos++;}}return(pos);}**/。

51单片机驱动1602液晶(4线串行)

51单片机驱动1602液晶(4线串行)

51单片机驱动1602液晶(4线串行) 2015-06-26 12:04:01 来源:51hei关键字:51单片机1602液晶4线串行/*单片机I/O 口使单片机资源的重要组成部分,也是用来扩展外围设备的必选资源,尽可能以更少的I/O口实现更多的功能是单片机工程师追求的目标,现在的一些串行器件也为这一目标的实现添加了更多的可能性,比如I2C总线,MAXIM力推的1-WIRE等等,都可以以很少的I/O口实现更多的功能,当然这是以降低一定的速度为代价的。

废话少说,进入正题。

显示器件多见的是LED数码管,LCD液晶屏等。

一般的数码管成本低廉,在显示内容要求不多的时候适用;LCD液晶屏以更多的显示空间得到了许多人的爱好,不过成本上要高的多(市场价在20元左右),本文以LCD1602为例说明如何驱动液晶屏。

LCD1602外接的控制接口有RS,R/W,E;数据接口为DB7--DB0。

总共有11跟线与单片机的I/O口连接,若使用标准的51单片机,至少占用了一个端口再加上另一个端口的部分I/O口。

这再很多应用场合是不大可取的。

所以很有必要减少连接数。

从其数据手册上介绍的4线连接方式可以达到只使用7个I/O口即可满足要求,其中为3个控制口RS,R/W,E和数据口的DB7--DB4;写入数据或指令的顺序是先写高半个字节,再写低半个字节。

其中P0口的高四位接到LCD1602的DB7-DB4,P3.0-P3.1分别接RS,R/W,E;下面给出驱动源程序*/#include <reg52.h>#include "intrins.h"#define uint unsigned int#define uchar unsigned char#define TRUE 1#define FALSE 0#define nop _nop_()#define PtData P0 //定义连接口线,#define PtContr P3sbit RS="PtContr"^0;sbit RW="PtContr"^1;sbit E="PtContr"^2;void InitialLcd();void WriteLcdInstr(uchar);void WriteLcdData(uchar);void CheckLcdBusy();uchar HexToDdram(uchar);void Delay(unsigned int);main(){Delay(1000);InitialLcd();WriteLcdInstr(0x80); WriteLcdData('e');WriteLcdData('l');WriteLcdData('k');WriteLcdData('e');WriteLcdData('l');WriteLcdData('i');WriteLcdData('k');WriteLcdData('e');WriteLcdInstr(0xc0); WriteLcdData('L');WriteLcdData('C');WriteLcdData('D');WriteLcdData('1');WriteLcdData('6');WriteLcdData('0');WriteLcdData('2');while(1){WriteLcdInstr(0x0f);Delay(30000);WriteLcdInstr(0x08);Delay(40000);}}//----------------LCD1602函数---------------------////---初始化void InitialLcd(){Delay(600);//延时应大于15ms,不同的晶振使需要修改,本程序再6M下调试通过RS=0;RW=0;nop;E=0;nop;E=1;nop;PtData=0x20;//nop;E=0;Delay(200);//延时应大于4.1msE=1;nop;PtData=0x20;//nop;E=0;Delay(5);//延时应大于100usE=1;nop;PtData=0x20;//nop;E=0;//设置4位操作;WriteLcdInstr(0x01);//清屏WriteLcdInstr(0x28);//设置4位操作,1行显示,5x8WriteLcdInstr(0x02);//光标归位WriteLcdInstr(0x06);//AC自动加1,画面不动WriteLcdInstr(0x0f);//0x0f:光标闪烁开;}//---写指令void WriteLcdInstr(uchar Temp){CheckLcdBusy();RS=0;RW=0;E=0;nop;PtData=Temp;nop;E=0;nop;E=1;nop;PtData=(Temp<<4);nop;E=0;nop;}//---写数据void WriteLcdData(uchar Temp) {CheckLcdBusy();RS=1;RW=0;E=0;nop;E=1;nop;PtData=Temp;nop;E=0;nop;E=1;nop;PtData=(Temp<<4);nop;E=0;nop;}//---查忙void CheckLcdBusy(){uchar Temp,t;PtData=0xff;RW=1;RS=0;nop;E=0;nop;do{nop;E=1;nop;Temp=PtData;nop;nop;nop;E=0;nop;nop;t=PtData;nop;nop;nop;E=0;nop;nop;Temp&=0x80;}while(Temp==0x80);}//---delayvoid Delay(unsigned int N) {unsigned int i;for(i=0;i<N;i++){i=i;}}。

1602四线制驱动程序,51单片机验证通过

1602四线制驱动程序,51单片机验证通过

delay_xms(1);//delay 1ms LCD_E=1; delay_xms(1);//delay 1ms LCD_E=0; */ //for 4bits data // uint8_t temp; LCD_RS=com;//com=1,write data //com=0,write construction //write high 4bits data LCD_DB7=x&0x80; LCD_DB6=x&0x40; LCD_DB5=x&0x20; LCD_DB4=x&0x10; // LCD_PORT= x&0xf0; delay_xms(1); //delay 1ms LCD_E=1; delay_xms(1); //delay 1ms LCD_E=0; //write low 4bits data LCD_DB7=x&0x08; LCD_DB6=x&0x04; LCD_DB5=x&0x02; LCD_DB4=x&0x01; // LCD_PORT= (x&0x0f)<<4; delay_xms(1); //delay 1ms LCD_E=1; delay_xms(1); //delay 1ms LCD_E=0; } //write address void write_address(uint8_t x,uint8_t y) { /* // for 1602 //write address
/*************************************************** 说明:1602和0802是我们常用的显示接口,由于有时候我们要节约io口 资源,需要用到4线制的接法,这样就可以由原来的11个io口(8个数据 端口+3个控制端口)减小到6个io口(4个数据端口+2个控制端口,RW 接地只写不读)。有时候我们也要显示一个字符串或一个整形或浮点型 数字,我也相关的函数整理一下供有需要的人参考。关于整数或浮点数 转换成字符串,也可以用库里面的函数。#include <stdio.h> sprintf 函 数。 **************************************************/ /*************************************************** 调试时注意事项说明:我们常用延时的方法一定要给硬件足够的反应时 间,因为如果延时太短的话,屏幕可能没显示。具体延时时间的大小可 参考例程并适当修改延时时间观察效果以确定一个合适的延时时间。 **************************************************/ /************************************************ *以下是1602头文件 *************************************************/ /** ****************************************************** * @file lcd1602.h * @brief This file contains all lcd1602 functions declaration. **/ #ifndef __LCD1602_H #define __LCD1602_H #include <reg51.h> #define uint8_t unsigned char #define uint16_t unsigned int //LCD1602/0802 define #define LCD_PORT P0 sbit LCD_DB4= P0^4; sbit LCD_DB5= P0^5; sbit LCD_DB6= P0^6; sbit LCD_DB7= P0^7; sbit LCD_RS= P1^0; sbit LCD_E= P1^1; //#define LCD_RW 0 //Only Write

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=高脉冲。

AVR单片机1602四线驱动程序

AVR单片机1602四线驱动程序
LCD_en_write();
/*
//连线为低四位的写法
delay_nus(16);
LCD_RS_PORT|=LCD_RS; //RS=1
LCD_DATA_PORT&=0Xf0; //清高四位
LCD_DATA_PORT|=(data>>4)&0x0f; //写高四位
LCD_en_write();
LCD_DATA_PORT&=0Xf0; //清高四位
LCD_DATA_PORT|=command&0xf0;//写低四位
LCD_en_write();
/*
//连线为低四位的写法
delay_nus(16);S=0
LCD_DATA_PORT&=0xf0; //清高四位
LCD_DATA_PORT|=(command>>4)&0x0f; //写高四位
LCD_RS_PORT|=LCD_RS;//RS=1
LCD_DATA_PORT&=0X0f;//清高四位
LCD_DATA_PORT|=data&0xf0;//写高四位
LCD_en_write();
data=data<<4;//低四位移到高四位
LCD_DATA_PORT&=0X0f;//清高四位
LCD_DATA_PORT|=data&0xf0;//写低四位
#defineLCD_EN_DDR DDRC
#defineLCD_RS_PORT PORTC//以下2个要设为同一个口
#defineLCD_RS_DDR DDRC
#defineLCD_DATA_PORT PORTA//以下3个要设为同一个口

LCD1602——用四位总线

LCD1602——用四位总线
for(i=0;;i++)
{
if(cs/10==0)
break;
cs=cs/10;
}
sz[i+1]='\0';
for(;;i--)
{
sz[i]=zs%10+0x30;
if(zs/10==0)
break;
zs=zs/10;
write_1602_byte(0,0x40+add_i*8); //写CGRAM地址+add_i
for(L1602_i=0;L1602_i<8;L1602_i++) //写数据
write_1602_byte(1,*p++);
if(hang==1)
}
/*在1602第hang行第lie列显示整形数 */
void L1602_Int(uchar hang,uchar lie,int zs) //可显示5位数
{
uchar sz[6]={0x20,0x20,0x20,0x20,0x20,'\0'},i;
uint cs=zs;
if(hang==1)
L1602_a=0x80+lie-1;
else
L1602_a=0xc0+lie-1;
write_1602_byte(0,L1602_a);
for(;;s++)
ቤተ መጻሕፍቲ ባይዱ {
if(*s=='\0')
break;
{
check_busy(); //读忙
RS=R_S; //R_S:1/0=数据/命令

lcd1602的用法

lcd1602的用法

LCD1602的用法一、简介LCD1602是一款常用的液晶显示模块,它具有16x2的字符显示能力,可以显示基本的英文、数字和符号。

通过与微处理器或单片机等控制器的连接,可以实现各种数据和信息的显示。

二、硬件连接1. 电源:LCD1602模块需要5V电压供电,可以使用USB转RS232接口或直接连接5V电源。

2. 数据线:LCD1602模块需要连接数据线才能与控制器通信。

常见的连接方式是使用4条数据线:RS、RW、E。

其中RS线控制亮灭,RW线控制光标,E线控制开关。

3. 地线:通常需要连接一个公共地线,以使电路稳定。

三、软件实现以下是一个简单的示例代码,使用C语言和LCD1602模块实现显示字符串的功能:```c#include <reg52.h> // 包含8051单片机寄存器定义#include <lcd1602.h> // 包含LCD1602驱动库文件// 声明LCD1602结构体变量LCD1602 lcd;void main() {// 初始化LCD1602模块lcd_init(&lcd);lcd_clear(&lcd); // 清空屏幕// 显示字符串"Hello, world!"lcd_puts(&lcd, "Hello, world!");// 等待一段时间,以便观察显示效果delay(500);}```四、常用命令LCD1602模块支持一些常用的命令,如光标移动、清屏、显示文本等。

具体命令可以参考LCD1602驱动库文档。

五、注意事项1. LCD1602模块的字符宽高比为4:5,因此需要调整显示的字符大小以适应屏幕。

2. 需要根据具体的应用场景和硬件配置选择合适的LCD1602模块和驱动库。

不同的模块和库可能存在差异,需要参考相应的文档进行操作。

3. 在实际应用中,需要考虑与其他设备的接口和控制方式,确保数据传输的正确性和稳定性。

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 的4线接法

详解一种LCD1602 的4线接法

详解一种LCD1602 的4线接法
 虽然LCD1602的显示屏幕与显示字符都较小,实用性并不强,但是在一般的教学实验中,它仍不失为一个常用的输出显示设备。

 LCD1602与单片机连接的线路共有11条,其中有8条数据线,3条控制线。

如果把它们都连接上,将占用较多的单片机的接口。

 LCD1602还有一种使用高4位数据线的接法,可以减少单片机的负担。


 另外,RW的控制也并非是必用的,如果仅仅是用于读取LCD1602忙的状态,就可以用稍事等待来代替。

这样一来,RW就可以直接接地,使
LCD1602永远处于写入的状态。

 那幺,LCD1602和单片机之间就仅仅需要6条线了,这就是LCD1602最简洁的连接方法。

 下面的一个例子是使用P0口的高4位连接到LCD1602的高4位数据线,。

1602四线八线驱动程序,非常完整

1602四线八线驱动程序,非常完整

/*--------------------------------------------------------------*///防止被重复定义#ifndef __LCD1602_8A_H__#define __LCD1602_8A_H__/*--------------------------------------------------------------*///模式选择(条件编译)#define Port_Type_Select 1 //=1, 选择八位数据模式//=0, 选择四位数据模式, LCD高四位接MCU端口高四位#defineInt_Transfer 1 //=1, 允许中断服务函数调用//=0, 不允许中断服务函数调用/*--------------------------------------------------------------*///LCD1602与单片机接口定义#define LCD_IO P0 //P0-0x80,P1-0x90,P2-0xA0,P3-0xB0; sbit LCD_RS = P1^0; //LCD数据/命令选择端(H/L)sbit LCD_RW = P1^1; //LCD 读/写选择端(H/L)sbit LCD_EN = P1^2; //LCD使能控制端/*--------------------------------------------------------------*///工作方式设置#define LCD_DISPLAY8_DOUBLE_LINE LCD_cmd(0x38); //两行显示8-bits#define LCD_DISPLAY8_SINGLE_LINE LCD_cmd(0x30); //单行显示8-bits#define LCD_DISPLAY4_DOUBLE_LINE LCD_cmd(0x28); //两行显示4-bits#define LCD_DISPLAY4_SINGLE_LINE LCD_cmd(0x20); //单行显示4-bits/*--------------------------------------------------------------*///输入方式设置#define LCD_AC_AUTO_INCREMENT LCD_cmd(0x06); //数据读、写操作后,AC 自动加1#define LCD_AC_AUTO_DECREASE LCD_cmd(0x04); //数据读、写操作后,AC自动减1#define LCD_MOVE_ENABLE LCD_cmd(0x07); //数据读、写操作,画面平移#define LCD_MOVE_DISENABLE LCD_cmd(0x06); //数据读、写操作,画面不动/*--------------------------------------------------------------*///设置显示、光标及闪烁开、关#define LCD_DISPLAY_ON LCD_cmd(0x0c); //LCD开显示#define LCD_DISPLAY_OFF LCD_cmd(0x08); //LCD关显示#define LCD_CURSOR_ON LCD_cmd(0x0e); //光标显示#define LCD_CURSOR_OFF LCD_cmd(0x0c); //光标不显示#define LCD_CURSOR_BLINK_ON LCD_cmd(0x0f); //光标闪烁#define LCD_CURSOR_BLINK_OFF LCD_cmd(0x0e); //光标不闪烁#define LCD_GO_HOME LCD_cmd(0x02); //AC=0,光标、画面回HOME位, DDRAM内容不变#define LCD_CLR LCD_cmd(0x01); //LCD清屏, 清除DDRAM, 清除屏幕, 置AC为0, 光标回位?/*--------------------------------------------------------------*///光标、画面移动,不影响DDRAM#define LCD_LEFT_MOVE LCD_cmd(0x18); //LCD显示左移一位#define LCD_RIGHT_MOVE LCD_cmd(0x1c); //LCD显示右移一位#define LCD_CURSOR_LEFT_MOVE LCD_cmd(0x10); //光标左移一位#define LCD_CURSOR_RIGHT_MOVE LCD_cmd(0x14); //光标右移一位/*--------------------------------------------------------------*///LCD1602地址相关/*#define LINE1_HEAD 0x80 //第一行DDRAM起始地址#define LINE2_HEAD 0xc0 //第二行DDRAM起始地址#define LINE1 0 //第一行#define LINE2 1 //第二行#define LINE_LENGTH 16 //每行的最大字符长度(40-DDRAM)/*--------------------------------------------------------------*///函数声明void LCD_busy (void); //检测LCD是否忙void LCD_init (void); //LCD初始化void LCD_cmd (unsigned char cmd); //写入指令void LCD_dat (unsigned char dat); //写入数据void LCD_pos (unsigned char x, unsigned char y); //显示定位void LCD_printc(unsigned char x, unsigned char y, unsigned char c); //定位输出字符void LCD_prints(unsigned char x, unsigned char y, unsigned char *s); //定位输出字符串void LCD_printn(unsigned char x, unsigned char y, unsigned int num); //定位输出16位二进制数字unsigned char LCD_current_addr(void); //读出AC当前地址(DB6~DB0)或忙标志位DB7unsigned char LCD_current_addr_dat(void); //读出AC当前地址的数据//unsigned char LCD_addr_dat(unsigned char x, unsigned char y); //读出AC指定地址的数据//void LCD_pos_CG(unsigned char x, unsigned char *CGRAM_dat); //指定地址(x: 0-7)写入8bytes数据CGRAM/*--------------------------------------------------------------*/ //读出AC当前地址(DB6~DB0)或忙标志位DB7#if Port_Type_Select //选择八位数据模式unsigned char LCD_current_addr(void){unsigned char ac_addr;LCD_EN = 0;LCD_RS = 0; //指令LCD_RW = 1; //读出LCD_IO = 0xff; //端口置为输入方式(P0)LCD_EN = 1;ac_addr = LCD_IO;LCD_EN = 0;return (ac_addr);}#else //选择四位数据模式unsigned char LCD_current_addr(void) {unsigned char ac_addr;LCD_EN = 0;LCD_RS = 0; //指令LCD_RW = 1; //读出LCD_IO |= 0xf0; //端口置为输入方式(P0) LCD_EN = 1;ac_addr = LCD_IO & 0xf0; //高四位LCD_EN = 0;LCD_EN = 1;ac_addr |= LCD_IO >> 4; //低四位LCD_EN = 0;return (ac_addr);}#endif/*--------------------------------------------------------------*/ //检测LCD忙状态#if Int_Transfer //允许中断服务函数调用void LCD_busy(void)unsigned char ac_dat;unsigned char busy_flag;do{ac_dat = LCD_current_addr();busy_flag = ac_dat & 0x80;}while(busy_flag); //=1表示忙, =0表示空闲}#else //不允许中断服务函数调用void LCD_busy(void){unsigned char ac_dat;bit busy_flag;do{ac_dat = LCD_current_addr();busy_flag = (bit)(ac_dat & 0x80);}while(busy_flag); //=1表示忙, =0表示空闲#endif///*--------------------------------------------------------------*/ ////读出AC当前地址的数据//#if Port_Type_Select //选择八位数据模式//unsigned char LCD_current_addr_dat(void)//{//unsigned char addr_dat;//// unsigned char i;//LCD_busy(); //或者检查忙最可靠//// for(i = 0; i < 3; i++) //要连续读出三次才会有效//{//LCD_EN = 0;//LCD_RS = 1; //数据//LCD_RW = 1; //读出//LCD_IO = 0xff; //端口置为输入方式(P0)//LCD_EN = 1;//addr_dat = LCD_IO;//LCD_EN = 0;//}//return (addr_dat);//}//#else //选择四位数据模式//unsigned char LCD_current_addr_dat(void)//{//unsigned char addr_dat;//// unsigned char i;//LCD_busy(); //或者检查忙最可靠//// for(i = 0; i < 3; i++) //要连续读出三次才会有效//{ //LCD_EN = 0;//LCD_RS = 1; //数据//LCD_RW = 1; //读出//LCD_IO |= 0xf0; //端口置为输入方式(P0)//LCD_EN = 1;//addr_dat = LCD_IO & 0xf0; //高四位//LCD_EN = 0;//LCD_EN = 1;//addr_dat |= LCD_IO >> 4; //低四位//LCD_EN = 0;//}//return (addr_dat);//}//#endif/*--------------------------------------------------------------*/ //写入指令#if Port_Type_Select //选择八位数据模式void LCD_cmd(unsigned char cmd){LCD_busy(); //检测忙LCD_RS = 0; //指令LCD_RW = 0; //写入LCD_EN = 1;LCD_IO = cmd; //传指令LCD_EN = 0; //下降沿有效}#else //选择四位数据模式void LCD_cmd(unsigned char cmd) {LCD_busy(); //检测忙LCD_IO &= 0x0f; //清高四位LCD_RS = 0; //指令LCD_RW = 0; //写入LCD_EN = 1;LCD_IO |= cmd & 0xf0; //写高四位LCD_EN = 0; //下降沿有效cmd <<= 4; //低四位移到高四位LCD_IO &= 0x0f; //清高四位LCD_EN = 1;LCD_IO |= cmd & 0xf0; //写高四位LCD_EN = 0; //下降沿有效}#endif/*--------------------------------------------------------------*/ //写入数据#if Port_Type_Select //选择八位数据模式void LCD_dat(unsigned char dat){LCD_busy(); //检测忙LCD_RS = 1; //数据LCD_RW = 0; //写入LCD_EN = 1;LCD_IO = dat; //传数据LCD_EN = 0; //下降沿有效}#else //选择四位数据模式void LCD_dat(unsigned char dat) {LCD_busy(); //检测忙LCD_IO &= 0x0f; //清高四位LCD_RS = 1; //数据LCD_RW = 0; //写入LCD_EN = 1;LCD_IO |= dat & 0xf0; //写高四位LCD_EN = 0; //下降沿有效dat <<= 4; //低四位移到高四位LCD_IO &= 0x0f; //清高四位LCD_EN = 1;LCD_IO |= dat & 0xf0; //写高四位LCD_EN = 0; //下降沿有效}#endif/*--------------------------------------------------------------*///显示定位DDRAMvoid LCD_pos(unsigned char x, unsigned char y){if(y) LCD_cmd(x|0xc0);//y=1第二行显示,y=0第一行显示0<=x<16(40-DDRAM)else LCD_cmd(x|0x80);//数据指针=80+地址码(00H~27H,40H~67H) }///*--------------------------------------------------------------*/////指定地址(x: 0-7)写入8bytes数据CGRAM//void LCD_pos_CG(unsigned char x, unsigned char *CGRAM_dat)//{//unsigned char i;//x <<= 3; //转化为6位数据的高三位,就是x*8;//x |= 0x40;//LCD_cmd(x); //写入地址//for(i = 0; i < 8; i++)//LCD_dat(CGRAM_dat[i]); //写入数据//}///*--------------------------------------------------------------*/////读出AC指定地址的数据//unsigned char LCD_addr_dat(unsigned char x, unsigned char y) //{//unsigned char addr_dat;//LCD_pos(x, y); //定位//addr_dat = LCD_current_addr_dat(); //读出数据//return (addr_dat);//}/*--------------------------------------------------------------*///定位输出字符void LCD_printc(unsigned char x, unsigned char y, unsigned char c) {LCD_pos(x, y);LCD_dat(c);}/*--------------------------------------------------------------*///定位输出字符串void LCD_prints(unsigned char x, unsigned char y, unsigned char *s) {LCD_pos(x, y);while(*s){LCD_dat(*s);s++;}}/*--------------------------------------------------------------*///定位输出16位二进制数字// 0<= num <65536void LCD_printn(unsigned char x, unsigned char y, unsigned int num) {char i=0;unsigned char ii=0;unsigned char dat[6]={0,0,0,0,0,0};for(i = 0; i < 6; i++) dat[i] = 0; i = 0; //初始化数据while(num / 10) //拆位{dat[i] = num % 10; //最低位num /= 10; i++;}dat[i] = num; //最高位ii = i; //保存dat的位数for(; i >= 0; i--) dat[i] += 48; //转化成ASCIILCD_prints(x, y, " "); //清显示区域LCD_pos(x, y);for(i = ii; i >= 0; i--) LCD_dat(dat[i]); //输出数字字符///*--------------------------------------------------------------*/////定位输出32位二进制数字//// 0<= num <65536//void LCD_print_long(unsigned char x, unsigned char y, unsigned long num)//{////char i;//unsigned char ii;//unsigned char dat[11];//for(i = 0; i < 11; i++) dat[i] = 0; i = 0; //初始化数据//while(num / 10) //拆位//{//dat[i] = num % 10; //最低位//num /= 10; i++;//}//dat[i] = num; //最高位//ii = i; //保存dat的位数//for(; i >= 0; i--) dat[i] += 48; //转化成ASCII//LCD_prints(x, y, " "); //清显示区域//LCD_pos(x, y);//for(i = ii; i >= 0; i--)// LCD_dat(dat[i]); //输出数字字符//}/*--------------------------------------------------------------*/ //LCD初始化void LCD_init(void){#if Port_Type_Select //选择八位数据模式LCD_DISPLAY8_DOUBLE_LINE //设置LCD为16X2显示,5X7点阵,八位数据接口#elseLCD_DISPLAY4_DOUBLE_LINE //设置LCD为16X2显示,5X7点阵,四位数据接口#endifLCD_AC_AUTO_INCREMENT //LCD显示光标移动设置(光标地址指针加1,整屏显示不移动)LCD_DISPLAY_ON //LCD开显示及光标设置(光标不闪烁,不显示"_")LCD_CLR //清屏}/*--------------------------------------------------------------*/ #endif。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LCD_DATA|=Recdata&0xf0;//写低四位
LCD_en_write();
}
void LCD_set_xy( unsigned char x, unsigned char y )//写地址函数
{
unsigned char address;
if (y == 0) address = 0x80 + x;
-(Ov)SnUIAGIOP
-(φWMIUOI<rπ-(Ov)SnUIAGIOP-(Bzxo)PuGulluoQJUJMItOJ
-(Ov)SnUIAGIOP-(Bzxo)PuGulluoQJUJMItOJ
-(Ov)SnUIAGIOP-(Bzxo)PuGulluoQJUJMItOJ
一芒怨足ms⅛∕7(PIoA)UU「3」PIoA
1---GND
2---VCC
3---VO
4---RS
5---RW
6---EN
7到14--D0-D7
15--背景灯+
16--背景灯-
*/ #include <at89X52.h>
#include <intrins.h> #define LCD_DATA P2 sbit LCD1602_RS=P2^2; sbit LCD1602_EN=P2^3;

1-WIRE 等等,都可以以很少的I/O口实现更多的功能,当然这是以降低一定的 速度
为代价的。
显示器件多见的是LED数码管,LCD液晶屏等。一般的数码管成本低廉,在显 示内
容要求不多的时候适用;LCD液晶屏以更多的显示空间得到了许多人的爱好, 不过
成本上要高的多(市场价在 20元左右),本文以LCD1602为例说明如何驱动液晶屏。
{delay_nus(16);
LCD1602_RS=1; //RS=1
LCD_DATA&=0X0f;//清高四位
LCD_DATA|=Recdata&0xf0;//写高四位
LCD_en_write();
Recdata=Recdata<<4;//低四位移到高四位
LCD_DATA&=0X0f;//清高四位
void delay_1us(void) //1us延时函数
{
_nop_();
}
void delay_nus(unsigned int n) //N us延时函数
{
unsigned int i=0;
for (i=0;i<n;i++) delay_1us();
}
void delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i=0;i<1140;i++);
}
void delay_nms(unsigned int n) //N ms延时函数

-(φWMIU0l<rπ⅛s≡w∖∖o∙JXO=apu13l≡OF一vrvtr<m⅛s≡≡∖∖匚OXO芯VrVereDJOHSHZyO"SHlZOs<rπ
LCD1602 外接的控制接口有RS,R/W,E;数据接口为 DB7--DB0。总共有11跟 线与单
片机的I/O口连接,若使用标准的51单片机,至少占用了一个端口再加上另一 个端
口的部分I/O口。这再很多应用场合是不大可取的。所以很有必要减少连接数。 从
其数据手册上介绍的 4线连接方式可以达到只使用 7个I/O口即可满足要求,其中为
//1602_RWvoid LCD_init(void);
void LCD_en_write(void);
void LCD_write_command(unsigned char command) ;
void LCD_write_data(unsigned char Recdata);
-()SlUIIAeI①P(++Vu〉VOHDlO4-OH-UIP①usun
LCD_DATA&=0x0f;//清高四位
LCD_DATA|=command&0xf0;//写低四位
LCD_en_write();
}
void LCD_write_data(unsigned char Recdata)//写数据
LCD1602 4位数据线连接方式 驱动程序(转载)
2008-10-1411:00
LCD1602 4位数据线连接方式 驱动程序(转载)
/*
单片机I/O口使单片机资源的重要组成部分,也是用来扩展外围设备的必选资源,
尽可能以更少的I/O口实现更多的功能是单片机工程师追求的目标,现在的一些串
行器件也为这一目标的实现添加了更多的可能性,比如I2C总线,MAXIM力推
3个控制口RS,R/W,E和数据口的DB7--DB4;写入数据或指令的顺序是先写高 半个
字节,再写低半个字节。
其中P2口的高四位接到LCD1602的DB7-DB4,P2.2-P2.3分别接RS,E; RW接地
下面给出驱动源程序*/
/*
液晶LCD1602C使用4条数据线(D4~D7)
*/
/*
LCD引脚定义
-(91)SnU—API①P
一令、、(PUeluiUoQ⅛^QP①usun)puel!≡0QJHllα2πP-OA

HN409IeD」
-(I)SnU—API①P
二HN409IeD」
一温迪ms⅛∕γ(PloA)OuJMIUOIaCnPIOA
-(Z)SlUUIAGIOP∖∖IOXO)PUeWIOO—①二*—C□」∖∖-(QoXo)Pueu≡oo—①二JIlα2π底鸣皑Wy,8ZXO)PUl3l≡OQJUjMleDJ
void delay_nus(unsigned int n);
void delay_nms(unsigned int n);
//以下函数用于输出数字
int LCD_PutNum(unsigned long num,int XS,int pos);
int LCD_PutStr(unsigned char *DData,int pos);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata);
相关文档
最新文档