×
单片机 > 单片机程序设计 > 详情

ATMEGA16 驱动1602 LCD程序

发布时间:2020-06-05 发布时间:
|

下面表格是16*2 LCD液晶与 单片机 的硬件接法:


1

VSS

接地

2

VCC

接电源,+5V

3

VO

反视度调整,接地吧

4

RS

寄存器选择,1-资料、0-指令

5

R/W

读写选择,1-读、0-写,如果LCD函数没有用到这个IO口的话就把它接地

6

E

信号使能,E由 1 -> 0 的下降沿时,LCD对RS和DATA进行取样和执行操作

7

DATA-DB0

悬空

8

DATA-DB1

悬空

9

DATA-DB2

悬空

10

DATA-DB3

悬空

11

DATA-DB4

接 单片机 IO口

12

DATA-DB5

接 单片机 IO口

13

DATA-DB6

接 单片机 IO口

14

DATA-DB7

接 单片机 IO口


// 04:lcd_init()            //LCD初始化函数 
// 05:lcd_DICtate(byte)     //写指令的函数 
// 07:lcd_gotoxy(x,y)       //列行定位函数 
// 06:lcd_putchar(byte)     //以ASCII方式显示一个字节变量 
// 08:lcd_hex(byte)         //以十六进制显示一个字节变量 
// 09:lcd_byte(byte)        //以十进制显示一个字节变量 
// 10:lcd_putsf(地址, 个数) //显示FLASH里面的字符串

#include  
#include  
#include <1602lcd.h> 
unsigned char byte;   
unsigned char flash string[]="M8V20"; 
void main(void) 
{   
   
  lcd_init();                         //1602LCD初始化函数  
  lcd_dICtate(1);                     //LCD清屏指令是(1) 
  while (1) 
        {   
          byte++; 
          lcd_gotoxy(4,0);             //光标定位到第4列第0行          
          lcd_byte(byte);              //以十进制的方式显示键值(字节形)  
          lcd_putchar('=');            //显示 = 字符 
          lcd_putchar(48);             //显示数字0 ,数字0的ASCII值是48 
          lcd_putchar('x');            //显示 x 字符 
          lcd_hex(byte);               //以十六进制的方式显示键值(字节型)             
          lcd_gotoxy(2,1);             //定位到第2列第1行          
          lcd_putsf(string,5);         //显示FLASH里面的字符串   
          lcd_putsf("-AVRDIY",7);      //显示FLASH里面的字符串 
          delay_ms(500); 
        } 
}

/*下面是<1602LCD.h>文件内容

在使用LCD之前先了解一下4位数据线传输的原理
1:LCD在E由 1->0 时对RS和DB4-DB7进行取样和执行操作 
2:RS=0 时表示"准备"写指令,RS=1 时表示"准备"写显示的数据 
3:不管是指令数据还是显示数据,数据位都是8位,由于LCD用的是4个数据线,所以在传输时先传输数据的高4位(Msb),然后再传输数据的低4位(Lsb) 
比如说我们要写一个指令,指令是0b11001000 ( 高4位是1100,低4位是1000 )  
那么就要这样: 
先传输高4位  |  接着传输低4位 
   E=1 ;     |    E=1 ; 
   RS=0 ;    |    RS=0 ; 
   DB7=1;    |    DB7=1; 
   DB6=1;    |    DB6=0; 
   DB5=0;    |    DB5=0; 
   DB4=0;    |    DB4=0; 
   E=0;      |    E=0; 
这样,我们就完成了写一个指令了,相反,写显示数据时就是把RS=1就可以了 
对LCD的写操作只有写指令和写显示数据两种,所以,一个"写指令函数"和一个"写显示数据函数"就可以满足全部要求 
*/   
#ifndef _1602lcd_INCLUDED_             //如果原来没有宏定义本名字就... 
#define _1602lcd_INCLUDED_             //定义一下,防止多次被头文件包含 
#include                      //本例使用7线连接(也可以使用6线,但是没有读"忙"功能,不推荐) 
#define RS        PORTB.4              //请修改LCD与 单片机 的连接IO口 
#define RS_DDRn    DDRB.4 

#define RW        PORTB.5  
#define RW_DDRn    DDRB.5      

#define E         PORTB.2 
#define E_DDRn     DDRB.2  

#define DB4       PORTC.4 
#define DB4_DDRn   DDRC.4  

#define DB5       PORTC.5 
#define DB5_DDRn   DDRC.5

#define DB6       PORTC.6 
#define DB6_DDRn   DDRC.6 

#define DB7       PORTC.7  
#define DB7_DDRn   DDRC.7 
#define DB7_PINn   PINC.7 

//====================================================================================== 
//写LCD 
//datas是数据,高4位有效,rs决定datas是显示还是指令,read_lcd决定是否需要读取忙标志BF 
void lcd_h(unsigned char datas,unsigned char rs,unsigned char read_lcd) 
{   
  RS_DDRn =1;                         //RS/RW/E设置为输出 
  RW_DDRn =1; 
  E_DDRn  =1;   
  if(read_lcd)                        //如果需要读LCD忙标志就... 
    {        
      DB4_DDRn=0;                     //先把4个数据口设置为输入 
      DB5_DDRn=0; 
      DB6_DDRn=0; 
      DB7_DDRn=0; 
      RS=0;  
      RW=1;                           //读BF 
      E=1; 
      E=1;                            //相同的操作相当于等待几个时钟周期 
      E=1; 
      while(DB7_PINn);                //等待,直到DB7=0  
    } 
  RS=rs;                              //写指令或者数据 
  RW=0;                               //写  
  DB4_DDRn=1; 
  DB5_DDRn=1; 
  DB6_DDRn=1; 
  DB7_DDRn=1;  
  E=1;    
  if(datas&128) DB7=1; else DB7=0;
  if(datas&64)  DB6=1; else DB6=0;
  if(datas&32)  DB5=1; else DB5=0;
  if(datas&16)  DB4=1; else DB4=0;
  E=0;                                //LCD在E下降沿时对RS与DB4-DB7进行取样 
}  
//================================================================================== 
void lcd_dictate(unsigned char data)  //写指令函数 
{  
  lcd_h(data,0,1);                    //输出高4位  
  lcd_h(data*16,0,1);                 //输出低4位 
}  
//=================================================================================== 
void lcd_putchar(unsigned char data)  //写显示函数 
{   
  lcd_h(data,1,1);                    //输出高4位  
  lcd_h(data*16,1,1);                 //输出低4位 
}  
//==================================================================================== 
//初始化函数 
void lcd_init(void) 
{    
  delay_ms(20); 
  lcd_h(48,0,0); delay_ms(6);         //这3条是初始化语句 
  lcd_h(48,0,0); delay_ms(5);  
  lcd_h(48,0,0);               
  lcd_h(32,0,1);                      //使能4位数据线 
  lcd_dictate(40);                    //显示参数设定 
  lcd_dictate(12);                    //显示参数设定 
}  
  
//====================================================================================== 
//列/行定位函数,最开头的地址是0列0行 
void lcd_gotoxy(unsigned char x, unsigned char y)  //列/行定位函数 
{       
  if(x<=19 && y<=3)                    //防止输入的数据不正确 
    {                                 
      if(y==0) lcd_dictate(x+128);     //第0行的地址是从128开始 
      if(y==1) lcd_dictate(x+192);     //第1行...... 
      if(y==2) lcd_dictate(x+148); 
      if(y==3) lcd_dictate(x+212); 
    } 
}      
//===================================================================================== 
void lcd_hex(unsigned char byte_data)                //以十六进制显示一个字节变量 

  unsigned char data;  
   
  data=byte_data>>4;                             //求高4位 
  if(data<10) data+=48; else data+=55; //转化为ASCII值 
  lcd_putchar(data);                             //显示 
   
  data=byte_data&15;                             //求低4位 
  if(data<10) data+=48; else data+=55; //转化为ASCII值 
  lcd_putchar(data);                             //显示 
}   
//===================================================================================== 
void lcd_byte(unsigned char byte_data)                //以十进制显示一个字节变量 

  unsigned char data;  
   
  data=byte_data/100;                            //求百位数 
  lcd_putchar(data+48);                          //转化为ASCII值再显示 
   
  data=byte_data/10%10;                          //求十位数 
  lcd_putchar(data+48);                          //转化为ASCII值再显示 
   
  data=byte_data%10;                             //求个位数 
  lcd_putchar(data+48);                          //转化为ASCII再再显示 
}   
//===================================================================================== 
void lcd_putsf(flash unsigned char *string , unsigned char n) //显示FLASH里面的字符串 
{         
  unsigned char i=0; 
  while(i       {   
         lcd_putchar( string[ i ] ) ;                 //顺序显示字符 
         i++;                          
       } 
}  
//===================================================================================== 
#endif//



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
浅谈AVR中定时器几种工作模式