网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  4-bit方式的 LCD 驱动程序 (在AT90S2313上实现)         ★★★ 【字体:
4-bit方式的 LCD 驱动程序 (在AT90S2313上实现)
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    

下面给出了采用4-bit数据宽度带动LCD显示器的整套
(子)程序, (使用WINAVR编译):

/***********************************************************************

    LCD.C

        LCD routines that are base on 4-bit data bus operation.
        (implemented on AT90S2313, PORTB[3..0] connected LCD D7..D4)

***********************************************************************/
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/ina90.h>
#include "define.h"
#include "lcd.h"
#include "timer.h"

#define LCD_RS  5       // pin-5 on PORTD
#define LCD_RW  3       // pin-3 on PORTD
#define LCD_E   4       // pin-4 on PORTD

#define SET_LCD_E       sbi (PORTD, LCD_E)      // LCD: E = 1
#define CLR_LCD_E       cbi (PORTD, LCD_E)      // LCD: E = 0
#define SET_LCD_RW      sbi (PORTD, LCD_RW)     // LCD: R/W = 1 (read)
#define CLR_LCD_RW      cbi (PORTD, LCD_RW)     // LCD: R/W = 0 (write)
#define SET_LCD_RS      sbi (PORTD, LCD_RS)     // LCD: R/S = 1 (data reg)
#define CLR_LCD_RS      cbi (PORTD, LCD_RS)     // LCD: R/S = 0 (status reg)


////////////////////////////////////////////////////////////////////////
u08 LCD_Clock (void)
{
    u08 ret_code;

    SET_LCD_E;
    _NOP (); _NOP ();       // make a delay
    ret_code = PINB & 0x0f; // read bus[7:4]
    CLR_LCD_E;

    return ret_code;
}

////////////////////////////////////////////////////////////////////////
u08 LCD_BusyStat (void)
{
    u08 n;

    DDRB &= 0xf0;           // PORTB[3:0] input

    SET_LCD_RW;             // R/W = 1
    CLR_LCD_RS;             // R/S = 0

    n = LCD_Clock () & 0x08;// bit7..4
    LCD_Clock ();           // bit3..0

    return n;
}

////////////////////////////////////////////////////////////////////////
void LCD_WriteStat1 (u08 byte)
{
    DDRB |= 0x0f;           // PORTB[3:0] output

    CLR_LCD_RW;             // R/W = 0
    CLR_LCD_RS;             // R/S = 0

    PORTB = byte & 0x0f;
    LCD_Clock ();
}

////////////////////////////////////////////////////////////////////////
void LCD_WriteStat2 (u08 byte)
{
    while ( LCD_BusyStat () );

    LCD_WriteStat1 (byte >> 4);
    LCD_WriteStat1 (byte);
}

////////////////////////////////////////////////////////////////////////
void LCD_WriteData1 (u08 byte)
{
    PORTB = byte & 0x0f;  // PORTB[3:0] = data
    DDRB  = 0x0f;         // PORTB[3:0] = output

    CLR_LCD_RW;           // R/W = 0
    SET_LCD_RS;           // R/S = 1

    LCD_Clock ();
}

////////////////////////////////////////////////////////////////////////
void LCD_WriteData2 (u08 byte)
{
    while ( LCD_BusyStat () );

    LCD_WriteData1 (byte >> 4);
    LCD_WriteData1 (byte);
}

////////////////////////////////////////////////////////////////////////
void LCD_Init (void)
{
    sbi (DDRD,  LCD_E);     // LCD E: output
    cbi (PORTD, LCD_E);     // LCD E = 0
    sbi (DDRB,  LCD_RW);    // LCD R/W  (Read/Write)
    sbi (DDRB,  LCD_RS);    // LCD R/S  (Reg/Status)

    TMR0_DelayMs (100);
    LCD_WriteStat1 (0x3);   // 4-bit data bus
    TMR0_DelayMs (10);
    LCD_WriteStat1 (0x3);
    TMR0_DelayMs (5);
    LCD_WriteStat1 (0x3);

    while ( LCD_BusyStat () );
    LCD_WriteStat1 (0x2);

    LCD_WriteStat2 (0x28);  // 2-line, 5x8 font
    LCD_WriteStat2 (0x0c);  // LCD on, no cursor & blinking
    LCD_WriteStat2 (0x06);  //
}

////////////////////////////////////////////////////////////////////////
void LCD_SetPosition (u08 row, u08 col)
{
    if ( row & 1 )          /* mark 2nd line bit */
        col |= 0x40;

    LCD_WriteStat2 (col | 0x80);
}

////////////////////////////////////////////////////////////////////////
void LCD_DisplayStrROM (u08 row, u08 col, PGM_P str)
{
    LCD_SetPosition (row, col);

    for (;;)
    {
        u08 c = __LPM (str++);

        if ( c == 0 )
            return;

        LCD_WriteData2 (c);
    }
}

////////////////////////////////////////////////////////////////////////
void LCD_DisplayStr (u08 row, u08 col, char *str)
{
    if ( (row < 2) && (col < 16) )
        LCD_SetPosition (row, col);

    for (;;)
    {
        u08 c = *str++;

        if ( c == 0 )
            return;

        LCD_WriteData2 (c);
    }
}

////////////////////////////////////////////////////////////////////////
void LCD_DisplayChar (u08 row, u08 col, char chr)
{
    LCD_SetPosition (row, col);
    LCD_WriteData2 (chr);
}

////////////////////////////////////////////////////////////////////////
void LCD_Clear (void)
{
    LCD_WriteStat2 (0x01);
}


////////////////////////////////////////////////////////////////////////
void LCD_SlideStrROM (u08 row, PGM_P str)
{
    u08 i, j, col;

    for (i = 16; i--;)
    {
        j = 0;
        LCD_SetPosition (row, i);

        for (col = i; col < 16; col++)
        {
            u08 c = __LPM (&str[j]);

            if ( c == 0 )
                c = ' ';
            else
                j++;

            LCD_PrintChar (c);
        }

        if ( i )
            TMR0_DelayMs (200);
    }
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号