我爱嵌入式系统

当前位置:首页 > 硬件天地 > 详细内容
12232液晶屏幕多种应用
发布时间:2009/10/28  阅读次数:2613  字体大小: 【】 【】【
TG12232E是一款带字库的122×32点液晶屏,可以串接(3线或2线),可并接。并接又有两种接法,4位并接和8位并接。可以说这是一款很好用的液晶屏。它的控制芯片是ST7920。目前市面上的带字库的液晶屏基本上也是用这个芯片,所以本程序是可以移植到其他液晶屏的。
 

这个屏我们有几种玩法:

1、采用3线串行方式

2、采用并行8位式

3、采用并行8位式(C++)

TG12232E的数据手册和芯片资料

 
采用3线串行方式的程序

//--------------------------------------------
//name:    TG12232E  驱动程序
//mcu:      ATmega8
//software:  winavr
//time:  2005.5.10
//--------------------------------------------
//    CS  -----  PB2      LCD片选(串行)  0:禁止  1:允许
//    SID  ----  PB3      LCD输入串行数据(串行)
//    CLK  ----  PB5      LCD输入串行脉冲(串行)

#include  <inttypes.h>
#include  <avr/io.h>
#include  <avr/delay.h>

#define    FREQ  8    //Meaga8L,8MHz
#define    SS      PB2//LCD片选(串行)  0:禁止  1:允许
#define    MOSI  PB3//LCD输入串行数据(串行)
#define    SCK    PB5//LCD输入串行脉冲(串行)

void  port_init(void)
{
    DDRB    =  0;//设置B口全为输入
    DDRC    =  0;//设置C口全为输入
    DDRD    =  0;//设置D口全为输入
    PORTB  =  0xff;//设置B口全部上拉
    PORTC  =  0xff;//设置C口全部上拉
    PORTD  =  0xff;//设置D口全部上拉
}

void  spi_init(void)
{
//  设置MOSI  和SCK  及SS  为输出,其他为输入
    DDRB  =  (1  <<  MOSI)  |  (1  <<  SCK)  |  (1  <<  SS);
    PORTB  =  (1  <<  MOSI)  |  (1  <<  SCK)  |  (1  <<  SS);
    SPCR  =  (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0);
}

void  delay_ms(unsigned  int  t)
{
  unsigned  int  i;
  for(i  =  0;  i  <  t;  i++)
        _delay_loop_2(250  *  FREQ);
}

void  spi_send(unsigned  char  data)
{

      SPDR  =  data;                  //  启动spi
      while(!(SPSR  &  (1  <<  SPIF)));  //  等待传输结束
}
//---------------------------------------------------
//    发送8位LCD控制命令
//--------------------------------------------------
void  lcd_send_com(unsigned  char  com)
{

    PORTB  |=  (1  <<  SS);                              //SS=1,启动SPI
    spi_send(0xf8);                    //发送LCD控制命令
    spi_send(com  &  0xf0);              //发送高4位LCD控制命令
    spi_send(com  <<  4);              //发送低4位LCD控制命令
    PORTB  &=  ~(1  <<  SS);                              //SS=0,关闭SPI
    if  (com  ==  0x01)  _delay_loop_2(1600  *  FREQ);//1.6mS
    else  _delay_loop_2(72  *  FREQ);                //st7920要求等待72uS
}

//--------------------------------------------------------
//      发送8位LCD显示数据
//-------------------------------------------------------
void  lcd_send_data(unsigned  char  data)
{
    PORTB  |=  (1  <<  SS);            //SS=1,启动SPI
    spi_send(0xfa);          //发送LCD显示数据
    spi_send(data  &  0xf0);      //发送高4位LCD显示数据
    spi_send(data  <<  4);      //发送低4位LCD显示数据
    PORTB  &=  ~(1  <<  SS);            //SS=0,关闭SPI
    _delay_loop_2(72  *  FREQ);          //st7920要求等待延时72uS
}


//---------------------------------------------------
//      LCD初始化设置
//---------------------------------------------------
void  lcd_init(void)
{
    delay_ms(100);                        //上电等待延时1000Ms
    spi_init();                                //SPI初始化
    lcd_send_com(0b00100000);  //发送4位控制命令
    lcd_send_com(0b00000100);  //发送进入点命令
    lcd_send_com(0b00001100);  //发送开显示关光标命令
    lcd_send_com(0b00000001);  //发送清除显示命令
    lcd_send_com(0b10000000);  //发送设定DDRAM地址0x00命令
}
//------------------------------------------
//定位
//----------------------------------------
unsigned  char  set_lcd_position(unsigned  char  row,  unsigned  char  col)
{
    if  ((row  <  2)  &&  (col  <  8))        //汉字字符为2行7.5列(汉字必须偶数对齐)
    {
        lcd_send_com(0x80  +  row  *  16  +  col);//发送设定DDRAM地址row  *  16  +  col命令
        return  1;//成功返回
    }
    else
        return  0;//失败返回
}

//---------------------------------------------------
//显示字符串
//---------------------------------------------------
void  lcd_display_string(unsigned  char  *  string)
{
    while(*string)  lcd_send_data(*string  ++);
}
//------------------------------------------------------------------------------------
//在指定位置显示
//------------------------------------------------------------------------------------
void  lcd_display(unsigned  char  row,  unsigned  char  col,  unsigned  char  *  string)
{
    if  (set_lcd_position(row,  col))
    {
        lcd_display_string(string);
    }
}

//========main=======================
int  main(void)
{

      port_init();
      lcd_init();

      set_lcd_position(0,1);        //汉字定位到上行左端
      lcd_display_string('欢迎光临本站');
      
      lcd_display(1,0,'  WWW.ICBEAN.COM  ');

      while(1);
}

 

 

采用并行8位式的程序

//--------------------------------------------
//name:    TG12232E  驱动程序
//mcu:      ATmega8
//software:  winavr
//time:  2005.5.10
//author:Bromi  
//7920中文LCD屏,带中文字库    TG12232E      并行8位
//联接:  LCD            MEGA8  
//            RS  -----  PORTD.0  
//            RD  -----  PORTD.1  
//            EN  -----  PORTD.2  
//          DB0~7  -----  PORTB      
//-----------------------------------------------
#include  <inttypes.h>
#include  <avr/io.h>
#include  <avr/delay.h>

#define    FREQ  8    //Meaga8L,8MHz

void  delay_ms(unsigned  int  t)    //毫秒延迟
{
  unsigned  int  i;
  for(i  =  0;  i  <  t;  i++)
        _delay_loop_2(250  *  FREQ);
}


#define  d_us(d)  _delay_loop_2(d  *  FREQ)//微秒延迟
//-----------------------------------------------
//将数据输出到LCD接口,LCD数据口宽度为8bit  
//rs:  1  操作指令寄存器,0  操作数据寄存器  
//rd:  1  从LCD读出数据,  0  向LCD写数据  
//portb:  要写入的数据
//-----------------------------------------------
//rs=PORTD.0
#define  set_rs  sbi(  PORTD,0)    //数据
#define  clr_rs  cbi(  PORTD,0)      //控制
//rw=PORTD.1  
#define  set_rw  sbi(  PORTD,1)    //读
#define  clr_rw  cbi(  PORTD,1)    //写
//en=PORTD.2  
#define  set_e  sbi(  PORTD,2)    
#define  clr_e  cbi(  PORTD,2)    

#define  lcd_send_com(d)  clr_rs;clr_rw;PORTB=d;set_e;d_us(200);clr_e    //写指令      
#define  lcd_send_data(d)  set_rs;clr_rw;PORTB=d;set_e;d_us(200);clr_e  //写数据      

//---------------------------------------------------
//      LCD初始化设置
//---------------------------------------------------
void  lcd_init(void)
{
    delay_ms(100);            //上电等待延时1000Ms
    lcd_send_com(0b00110000);  //发送8位控制命令
    lcd_send_com(0b00000100);  //发送进入点命令
    lcd_send_com(0b00001100);  //发送开显示关光标命令
    lcd_send_com(0b00000001);  //发送清除显示命令
    lcd_send_com(0b10000000);  //发送设定DDRAM地址0x00命令
}
//------------------------------------------
//定位
//----------------------------------------
unsigned  char  set_lcd_position(unsigned  char  row,  unsigned  char  col)
{
    if  ((row  <  2)  &&  (col  <  8))        //汉字字符为2行7.5列(汉字必须偶数对齐)
    {
        lcd_send_com(0x80  +  row  *  16  +  col);//发送设定DDRAM地址row  *  16  +  col命令
        return  1;//成功返回
    }
    else
        return  0;//失败返回
}

//---------------------------------------------------
//显示字符串
//---------------------------------------------------
void  lcd_display_string(unsigned  char  *  string)
{
    while(*string)  lcd_send_data(*string  ++);
}
//------------------------------------------------------------------------------------
//在指定位置显示
//------------------------------------------------------------------------------------
void  lcd_display(unsigned  char  row,  unsigned  char  col,  unsigned  char  *  string)
{
    if  (set_lcd_position(row,  col))
    {
        lcd_display_string(string);
    }
}

void  port_init(void)
{
    DDRB    =  0xff;  //设置B口全为输出
    DDRC    =  0;  //设置C口全为输出
    DDRD    =  0xff;  //设置D口全为输出
    
    PORTB  =  0xff;  //设置B口全部上拉
    PORTC  =  0xff;  //设置C口全部上拉
    PORTD  =  0xff;  //设置D口全部上拉
}
//========main=======================
int  main(void)
{

      port_init();
      lcd_init();

      set_lcd_position(0,1);        //汉字定位到上行左端
      lcd_display_string('?迎光临本站')'
      
      lcd_display(1,0,'  'WW.ICBEAN.COM  ')'

      while(1);
}

 

采用并行8位式的程序(C++版)

//-------------------------------------------
//name:    TG12232E  驱动程序
//mcu:      ATmega8
//software:  AVR-GCC          C++  TEST
//time:  2005.5.10
//-------------------------------------------
#include  <inttypes.h>
#include  <avr/io.h>
#include  <avr/interrupt.h>
#include  <avr/signal.h>
#include  <avr/wdt.h>
#include  <avr/ina90.h>
#include  <avr/eeprom.h>
#include  <stdio.h>
#include  <avr/delay.h>
#include  <string.h>
#include  <stdlib.h>

#define  uchar  unsigned  char
#define  uint  unsigned  int

#define    FREQ  8    //Meaga8L,8MHz

#define    SS      PB2//LCD片选(串行)  0:禁止  1:允许
#define    MOSI  PB3//LCD输入串行数据(串行)
#define    SCK    PB5//LCD输入串行脉冲(串行)

class  lcd
{
  private:
      unsigned  char  row,col;
      void  spi_mode_set(void);
  public:
      lcd(void);      //lcd的构造函数
      void  lcd_send(unsigned  char);
      void  dl_ms(unsigned  int);
      void  lcd_init(void);
      void  lcd_send_com(unsigned  char);
      void  lcd_send_data(unsigned  char);
      unsigned  char  set_position(unsigned  char,  unsigned  char);
      void  get_position(unsigned  char  &,  unsigned  char  &);

      void  lcd_display(unsigned  char,  unsigned  char,  const  char  *);
      void  lcd_display(const  char  *);
      void  lcd_display(uchar);
      void  lcd_display(int);
};


lcd::lcd(void)
{
    row  =  0;
    col  =  0;
    spi_mode_set();
}

void  lcd::spi_mode_set(void)
{
    DDRB  =  (1  <<  MOSI)  |  (1  <<  SCK)  |  (1  <<  SS);
    PORTB  =  (1  <<  MOSI)  |  (1  <<  SCK)  |  (1  <<  SS);
    SPCR  =  (1  <<  SPE)  |  (1  <<  MSTR)  |  (1  <<  CPOL)  |  (1  <<  CPHA)  |  (1  <<  SPR0);
}

void  lcd::lcd_send(unsigned  char  cData)
{
    SPDR  =  cData;
    while(!(SPSR  &  (1  <<  SPIF)));
}

void  lcd::dl_ms(unsigned  int  t)
{
unsigned  int  i;
    for(i  =  0;  i  <  t;  i++)
        _delay_loop_2(250  *  FREQ);
}


//--------------------------------------------------------
//        发送8位LCD控制命令
//------------------------------------------------------
void  lcd::lcd_send_com(unsigned  char  cCommand)
{
/*--------------------------------------------------------
        发送同步脉冲11111  WR(0)  RS(0)  0发送顺序从左至右)
--------------------------------------------------------*/

    PORTB  |=  (1  <<  SS);    //SS=1,启动SPI
    lcd_send(0xf8);          //发送LCD控制命令
    lcd_send(cCommand  &  0xf0);//发送高4位LCD控制命令
    lcd_send(cCommand  <<  4);//发送低4位LCD控制命令
    PORTB  &=  ~(1  <<  SS);//SS=0,关闭SPI
    if  (cCommand  ==  0x01)  _delay_loop_2(1600  *  FREQ);//1.6mS
    else  _delay_loop_2(72  *  FREQ);//st7920要求等待72uS
}

/*--------------------------------------------------------
        发送8位LCD显示数据
--------------------------------------------------------*/

void  lcd::lcd_send_data(unsigned  char  cData)
{
/*--------------------------------------------------------
        发送同步脉冲11111  WR(0)  RS(0)  0发送顺序从左至右)
--------------------------------------------------------*/

    PORTB  |=  (1  <<  SS);//SS=1,启动SPI
    lcd_send(0xfa);//发送LCD显示数据
    lcd_send(cData  &  0xf0);//发送高4位LCD显示数据
    lcd_send(cData  <<  4);//发送低4位LCD显示数据
    PORTB  &=  ~(1  <<  SS);//SS=0,关闭SPI
    _delay_loop_2(72  *  FREQ);//st7920要求等待延时72uS
}


/*---------------------------------------------------
        LCD初始化设置
----------------------------------------------------*/

void  lcd::lcd_init(void)
{
    dl_ms(100);//上电等待延时1000Ms
    spi_mode_set();//SPI初始化
    lcd_send_com(0b00100000);//发送4位控制命令
    lcd_send_com(0b00000010);//发送位址归位命令,设定DDRAM位址计数器为0
    lcd_send_com(0b00000100);//发送进入点命令
    lcd_send_com(0b00001100);//发送开显示关光标命令
    lcd_send_com(0b00000001);//发送清除显示命令
    lcd_send_com(0b10000000);//发送设定DDRAM地址0x00命令
}

unsigned  char  lcd::set_position(unsigned  char  row,  unsigned  char  col)
{
    row  --;
    col  --;
    if  ((row  <  2)  &&  (col  <  8))  {//汉字字符为2行7.5列(汉字必须偶数对齐)
        lcd_send_com(0x80  +  row  *  16  +  col);//发送设定DDRAM地址row  *  16  +  col命令
        row  =  row;
        col  =  col  <<  1;
        return  1;
    }
    else
        return  0;
}

void  lcd::get_position(unsigned  char  &row,  unsigned  char  &col)
{
    row  =  row  +  1;
    col  =  col  +  1;
}


void  lcd::lcd_display(unsigned  char  row,  unsigned  char  col,  const  char  *  string)
{
    if  (set_position(row,  col))  lcd_display(string);
}


void  lcd::lcd_display(const  char  *  string)
{
    while(*string)  {
        lcd_send_data(*string  ++);
        col  ++;
    }
}

void  lcd::lcd_display(uchar  Val)
{
char  str[4];
    itoa((int)Val,  (char  *)str,  10);
    lcd_display((char  *)str);
}

void  lcd::lcd_display(int  Val)
{
char  str[6];
    itoa(Val,  (char  *)str,  10);
    lcd_display((char  *)str);
}


lcd  disp;

//-------------main程序------------------
int  main(void)
{
      disp.lcd_init();      //LCD初始化
      for(;;)
      {                                    //死循环
  //----------------------------------------------------------------
  //        C++函数重载演示,所有LCD显示函数都使用一个函数名lcd_display()
  //----------------------------------------------------------------

          disp.lcd_display(1,2,'迎光临本站');       //在当前位置显示汉字串
          disp.dl_ms(1000);                                           //延时1000Ms
          disp.lcd_display(2,1,'WWW.ICBEAN.COM');//www.ICBEAN.COM'

      }

}

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

51RTOS.com 版权所有  

Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号