AVR六个IO口驱动液晶LCD1602

发布者:chaochen最新更新时间:2016-07-18 来源: eefocus关键字:AVR  IO口  驱动液晶  LCD1602 手机看文章 扫描二维码
随时随地手机看文章
液晶LCD1602比中文大液晶12864较容易驱动,这个驱动程序只用六个单片机IO口驱动,可以减少四个IO口,套用也方便...

//LCD1602.h

/*---------------------------------------------------------------
要使用本驱动,改变下面配置信息即可

注意:RW要接地
-----------------------------------------------------------------*/
#define LCD_EN_PORT    PORTD   //以下2个要设为同一个口
#define LCD_EN_DDR     DDRD
#define LCD_RS_PORT    PORTD   //以下2个要设为同一个口
#define LCD_RS_DDR     DDRD
#define LCD_DATA_PORT  PORTD   //以下3个要设为同一个口
#define LCD_DATA_DDR   DDRD    //一定要用高4位
#define LCD_DATA_PIN   PIND
#define LCD_RS         (1<<0) //0x04   portd2       out
#define LCD_EN         (1<<2) //0x08   portd3       out
#define LCD_DATA       ((1<<4)|(1<<5)|(1<<6)|(1<<7)) //0xf0   portd4/5/6/7 out
/*-------------------------------------------------------------------------------
函数说明
------------------------------------------------------------------------------*/
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 delay_nus(unsigned int n);
void delay_nms(unsigned int n);

//LCD1602.c

#include
#include
#include"LCD1602.h"


void delay_1us(void)                 //1us延时函数
  {
   asm("nop");
  }

void delay_nus(unsigned int n)       //N us延时函数
  {
   unsigned int i=0;
   for (i=0;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   delay_1ms();
  }


/*----------------------------------------------------------------------------*/
void LCD_init(void)         //液晶初始化
{
  LCD_DATA_DDR|=LCD_DATA;   //数据口方向为输出
  LCD_EN_DDR|=LCD_EN;       //设置EN方向为输出
  LCD_RS_DDR|=LCD_RS;       //设置RS方向为输出
  LCD_write_command(0x28); 
  LCD_en_write();
  delay_nus(40);
  LCD_write_command(0x28);  //4位显示
  LCD_write_command(0x0c);  //显示开
  LCD_write_command(0x01);  //清屏
  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) //写指令
{
  delay_nus(16);
  LCD_RS_PORT&=~LCD_RS;        //RS=0
  LCD_DATA_PORT&=0X0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写高四位
  LCD_en_write();
  command=command<<4;          //低四位移到高四位
  LCD_DATA_PORT&=0x0f;         //清高四位
  LCD_DATA_PORT|=command&0xf0; //写低四位
  LCD_en_write();
  
}
/*----------------------------------------------------------------------------*/
void LCD_write_data(unsigned char data) //写数据
{
  delay_nus(16);
  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;   //写低四位
  LCD_en_write();
}
/*----------------------------------------------------------------------------*/
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);
}
/*----------------------------------------------------------------------------*/

//列x=0~15,行y=0,1
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)

{
    LCD_set_xy( X, Y ); //写地址    
    while (*s)  // 写显示字符
    {
      LCD_write_data( *s );
      s ++;
    }
      
}

/*----------------------------------------------------------------------------*/

//列x=0~15,行y=0,1
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data)

{
  LCD_set_xy( X, Y ); //写地址
  LCD_write_data( data);
  
}

//main.c

#include
#include
#include"LCD1602.h"

void main(void)
{
   LCD_init();
                    //      X  Y      *s
   LCD_write_string(2, 0, "hello!!");
   while(1)
   {
                    //      X  Y      *s
   LCD_write_string(2, 1,"1234567890");
                    //     X  Y   data
   LCD_write_char(12, 0, '8');
   LCD_write_char(13, 0, '8');    
   }
 
}

关键字:AVR  IO口  驱动液晶  LCD1602 引用地址:AVR六个IO口驱动液晶LCD1602

上一篇:一个URAT(RS232)低层驱动 中间层软件示例
下一篇:AVR简单好用的4x4矩阵键盘

推荐阅读最新更新时间:2024-03-16 15:00

51单片机对LCD1602液晶显示的驱动控制设计
利用串行A/D转换器TLC549对输入信号电压源进行采集转换成数字信号给51单片机,经单片机进行数据处理后给1602液晶显示。 误差小于1%. #include #include #define uint unsigned int #define uchar unsigned char uchar LCD[6]; //电压数据转换成LCD1602液晶字符显示 uint Volt; sbit DO= P1^0; //时钟 sbit CS= P1^1; //片选 sbit CLK = P1^2; //数据输出 sbit RS = P2^0; //1602液晶数据/命令选择端 sbit RW = P2^1; //1602液晶读写端
[单片机]
51单片机对<font color='red'>LCD1602</font><font color='red'>液晶</font>显示的<font color='red'>驱动</font>控制设计
PIC16F877驱动KS0066U液晶程序
为了电子设计大赛,我又要重新学习单片机了! 现在来总结总结以前学习单片机的经验和体会: 1、单片机其实并不难,无非就是那几个模块,而真正难的是:一个外围芯片(比如下面将要驱动的液晶芯片)的工作时序以及准确的延时;然后利用单片机的资源去按照时序编程就得了,所以说了只要把一种单片机的常用模块搞通了,其它也就一样简单,很容易就OK了! 2、单片机编程的框架:模块的初始化,然后死循环和中断,很简单吧! 3、单片机编程应该注意的问题,一是要按照说明书给出的时序来编程,不要自己想当然了;二是要控制好延时,大部分单片机系统的不稳定,有很多是因为延时不到位引起的;而对PIC等单片机来说,还得注意使用时一定得注意单片机的端口的方向(输入还是输出
[单片机]
PIC16F877<font color='red'>驱动</font>KS0066U<font color='red'>液晶</font>程序
AVR 编程之矩阵键盘
#include iom16v.h #include macros.h #define uchar unsigned char #define uint unsigned int uchar const table ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71,0X00};// 显示段码值0123456789abcdef void main() { uchar key=0; uchar i=0; DDRC|=BIT(7); PORTC|=BIT(7); DDRA=0XFF; PORTA=0X00; DDR
[单片机]
<font color='red'>AVR</font> 编程之矩阵键盘
基于AVR及MTURTU的无线电遥测系统设计
一、引言 基于AVR单片机及专用MODEM芯片的MTU(Master Terminal Unit中心调度机)、RTU无线电遥测系统。 分散地分布在全市的管网监测点上的远端RTU(系统可带256个RTU)采集数据,进行数据处理后通过无线电台向中心调度端发送数据,中心调度端接收到数据后进行数据处理,数据存储,并送给模拟屏显示。 二、设计思想 原有系统的使用中,主要存在以下几个问题:1. 无线通信波特率低(300bps),误码率高,巡测速度慢,最多带32个RTU终端;2. 当某一远程RTU端的无线电台一直处于长时间误发射状态时(简称“长发” )一直占用系统频点,由于系统共用一组无线电频点,这将使系统其他所有电台无法通信,整个系统瘫
[单片机]
采用AVR单片机为核心设计电冰箱控制系统
多年来电冰箱在国内市场上一直作为储物、保鲜的空间,人们对于电冰箱的需求也是最基本的冷冻、冻藏等功能。近年来,随着家用电冰箱的普及以及80后主流消费群体的迅速崛起,人们对电冰箱的性能要求越来越高,加速了对电冰箱功能和需求的转型和升级,相应地对电冰箱的控制功能要求也越来越高。 单片机自问世以来,性能不断提高,功能不断增多和完善,加之具有集成度高、功能强、速度快、体积小、功耗低、使用方便、性能可靠、价格低廉等特点,因此,广泛应用在工业控制、智能仪器仪表、数据采集和处理、通信系统、高级计算器、家用电器等领域,基于AVR单片机的电冰箱控制系统的设计把单片机技术充分利用在电冰箱的控制系统上,为现代电冰箱的发展提供技术支撑。 1 系统总
[单片机]
采用<font color='red'>AVR</font>单片机为核心设计电冰箱控制系统
Proteus仿真AVR单片机时使用外部晶振熔丝位设置
根据上面两张表来看,高频晶体(大于3M),CKSEL应当设置为1111比较合理,CKOPT不被编程时,支持到的最大频率为8M,那么大于8M的话,应当是CKOPT为0。 而SUT参考下表 BOD是电源低电压检测模块,还有一个小细节,那个proteus下面的频率那个M字应当大写,否则认不出来。
[单片机]
AVR 的 IO 端口特性与应用
AVR的IO端口特性分析: 分析IO引脚Pxn。DDRxn 只有为1时,可控单向开关才工作,PORTxn 的数值才能通过可控单向开送到 Pxn. 结论:DDRxn=1 时,为输出状态。输出值等于PORTxn。所以,DDRxn 为方向寄存器。PORTxn 为数据寄存器。 分析上拉电阻。E的电位为0时,即D为1时,上拉电阻有效。 从与门的输入分析,只有以下的条件同时满足时,上拉电阻才有效 1、PUD 为0 2、DDxn 为0 3、PORTxn 为1 结论是:只有DDRxn = 0 即管脚定义为输入状态,并且 PORTxn=1, 而且UPD设置为0时,上拉电阻才生效。 分析 Pxn 及 SLEEP。只有当 S
[单片机]
<font color='red'>AVR</font> 的 IO 端口特性与应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved