專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

基于atmega的LCD1602驅(qū)動(8線/4線)

作者:佚名   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2011年10月17日   【字體:
//*************************************************
// 文件名: 1602.h
// 作用:    AVR的LCD1602 4/8線驅(qū)動
// 作者:    seabisuit
// 最新修改: 2011年6月22日
// 說明:   使用GCC編程,1602提供4/8線驅(qū)動
//     4線暫時(shí)高4位
//*************************************************/
#ifndef __1602_H_
#define __1602_H_ 1
//***頭文件調(diào)用***//
#include <avr/io.h>
#include <util/delay.h>
#include <avr/portpins.h>
#include <compat/deprecated.h>

//***定義uchar***//
#ifndef uchar
#define uchar unsigned char
#endif

//***本頭文件增強(qiáng)功能設(shè)置***//
#define _LCD_DEF    0 //使自定義功能實(shí)現(xiàn),如不需要將其定義為0(#define _LCD_DEF 0)
#define _LCD_BIT_IS_8 1 //定義4線或者8線

/*控制針腳設(shè)置*/
#define LCD_CZ PORTB
#define LCD_CZDDR DDRB 
#define LCD_E 2
#define LCD_RW 1
#define LCD_RS 0
#define LCDDATA PORTE
#define LCDDDR DDRE
#define LCDPIN PINE
#define busy 7

/*LCD命令定義*/
#define E0()   cbi(LCD_CZ,LCD_E)
#define E1()   sbi(LCD_CZ,LCD_E)
#define RW0()    cbi(LCD_CZ,LCD_RW)
#define RW1()    sbi(LCD_CZ,LCD_RW)
#define RS0()    cbi(LCD_CZ,LCD_RS)
#define RS1()    sbi(LCD_CZ,LCD_RS)
#define nop()    asm("nop")



/*基本功能函數(shù)聲明。*/
void lcd_busy(void);//測試LCD忙碌狀態(tài)
void lcd_wrcmd(uchar CMD,uchar wait);//LCD寫入指令
void lcd_wrdata(uchar);//LCD寫入數(shù)據(jù)
void lcd_xy(uchar,uchar);//lcd顯示定位
void lcd_char(uchar,uchar,uchar);//lcd顯示字符
void lcd_string(uchar,uchar,uchar *);//lcd顯示字符串
void lcd_cls(void);//1602清顯示
void lcd_init(void); //LCD初始化設(shè)定程序
void lcd_def(void);//自定義字符串


/********************************************************/
/* 函數(shù):void lcd_busy(void)                            */
/* 功能:檢查LCD忙狀態(tài)                                  */
/*busy為1時(shí),忙,等待。busy為0時(shí),閑,可寫指令與數(shù)據(jù)     */
/*                                                      */
/********************************************************/ 
void lcd_busy(void)
{
   #if (_LCD_BIT_IS_8==1) //8位數(shù)據(jù)線

uchar tmp;

LCDDDR&=~1<<7;//設(shè)置為輸入
E0();RS0();RW1();

/*循環(huán)讀取忙位*/
do{ 
   E1();_delay_us(1);
   tmp=LCDPIN;
   E0();
}
while(tmp&1<<busy);
LCDDDR=0xff;

#else    //4位數(shù)據(jù)線

uchar tmp;
LCDDDR=0;
E0();RS0();RW1();
/*循環(huán)讀取忙位*/
do{
E1();_delay_us(1);
tmp=LCDPIN;
E0();_delay_us(1);
E1();_delay_us(1);

E0();_delay_us(6);
}
while(tmp&1<<busy);

LCDDDR=0xff;

#endif

}
/********************************************************/
/* 函數(shù):lcd_wrcmd(uchar CMD,uchar wait)                */
/* 功能:寫入命令到LCD                                  */
/*RS=0,RW=0,E=高脈沖,D0-D7=指令碼。                  */
/*CMD為指令,wait指定是否要檢測LCD忙信號                */
/*                                                      */
/********************************************************/
void lcd_wrcmd(uchar CMD,uchar wait)
{   
   #if (_LCD_BIT_IS_8==1) //8位數(shù)據(jù)線

if (wait) //是否讀忙
lcd_busy();
//else 
//_delay_us(40);
    RS0();RW0();
    LCDDATA=CMD;    
    E1();E0();

#else    //4位數(shù)據(jù)線

if (wait) 
lcd_busy();
else 
_delay_us(40);
    RS0();RW0();E0();     
    
    LCDDATA=CMD&0xf0;
    E1();_delay_us(1);E0();_delay_us(6);
LCDDATA=(CMD<<4)&0xf0;
E1();_delay_us(1);E0();
#endif
}
/********************************************************/
/* 函數(shù):void lcd_wrdate(uchar);                        */
/* 功能:寫入數(shù)據(jù)到LCD                                  */
/*RS=1,RW=0,E=高脈沖,D0-D7=指令碼。                  */
/*dat為要寫入的數(shù)據(jù)                                     */
/*                                                      */
/********************************************************/
void lcd_wrdata(uchar dat)      //寫數(shù)據(jù)
{ 
   #if (_LCD_BIT_IS_8==1) //8位數(shù)據(jù)線

lcd_busy();
    RW0();RS1();      
LCDDATA=dat;
    E1();E0();

#else    //4位數(shù)據(jù)線
lcd_busy();
    RW0();RS1();      

    LCDDATA=dat&0xf0;
    E1();_delay_us(1);E0();_delay_us(6);


    LCDDATA=(dat<<4)&0xf0;
E1();_delay_us(1);E0();
#endif
    
}
/********************************************************/
/* 函數(shù):lcd_xy(uchar x,uchar y)                        */
/* 功能:lcd顯示定位                                    */
/*                                                      */
/********************************************************/
void lcd_xy(uchar x,uchar y)
{ 
uchar add;
if(y==0) 
add=0x80+0x00+x;
    else
    add=0x80+0x40+x;
    lcd_wrcmd(add,1);
}

/********************************************************/
/* 函數(shù):void lcd_char(uchar x,uchar y,uchar dat)       */
/* 功能:lcd于(x,y)處顯示字符                        */
/*                                                      */
/********************************************************/
void lcd_char(uchar x,uchar y,uchar dat) 
{   
    lcd_xy(x,y);
    lcd_wrdata(dat);
}           
/********************************************************/
/* 函數(shù):void lcd_string(uchar x,uchar y,uchar *s)      */
/* 功能:lcd于(x,y)處開始顯示字符串                  */
/*                                                      */
/********************************************************/
void lcd_string(uchar x,uchar y,uchar *s)
{ 
lcd_xy(x,y);
while(*s) 
    {
   lcd_wrdata(*s);
        s++;
    }
}
/********************************************************/
/* 函數(shù):void lcd_cls(void)                             */
/* 功能:對1602顯示屏清除,并進(jìn)行延時(shí)                   */
/* 延時(shí)是為了使1602又時(shí)間進(jìn)行清除                       */
/*                                                      */
/********************************************************/
void lcd_cls(void)
{ 
lcd_wrcmd(0x01,1);
_delay_ms(10);
}
/********************************************************/
/* 函數(shù):void LcdReset(void);                           */
/* 功能:對1602進(jìn)行復(fù)位                                 */
/*                                                      */
/********************************************************/
void lcd_init(void)     
{   
   #if (_LCD_BIT_IS_8==1) //8位數(shù)據(jù)線
   
LCD_CZDDR=1<<LCD_E|1<<LCD_RS|1<<LCD_RW;
LCDDDR=0xff;
_delay_ms(15);
lcd_wrcmd(0x38,0);    
_delay_ms(5);
lcd_wrcmd(0x38,0);    
_delay_ms(5);
lcd_wrcmd(0x38,0); 
_delay_us(1);
lcd_wrcmd(0x38,1);
lcd_wrcmd(0x08,1);
lcd_cls();

    lcd_wrcmd(0x06,1); 
    lcd_wrcmd(0x0e,1);

#else    //4位數(shù)據(jù)線
LCD_CZDDR=1<<LCD_E|1<<LCD_RS|1<<LCD_RW;
LCDDDR=0xf0;
_delay_ms(15);
lcd_wrcmd(0x38,0);    
_delay_ms(5);
lcd_wrcmd(0x38,0);    
_delay_ms(5);
lcd_wrcmd(0x38,0); 
_delay_us(1);
lcd_wrcmd(0x38,1);
lcd_wrcmd(0x02,1);
lcd_wrcmd(0x28,1);
lcd_cls();
lcd_wrcmd(0x06,1); 
    lcd_wrcmd(0x0e,1);


#endif

    
}


#if (_LCD_DEF==1)
//定義CGRAM的值,在功能開啟后再主文件加入如下面字符串?dāng)?shù)組定義
const uchar lcd_cgram[64]=
{
0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00
};

void lcd_def(uchar cg[64])
{
    uchar temp=0;
    lcd_wrcmd(0x40,1);
    while(temp<64)
    {
      lcd_wrdata(cg[temp]);
      temp++;
    }
}
#endif

#endif /*__1602_H_*/

 

關(guān)閉窗口

相關(guān)文章