snifer

【技术分享】【原创】基于智能车的LCD显示接口设计

0
阅读(2628)

智能车中经常需要进行显示设计,在二次开发中少不了进行接口扩充,今天我就写一下关于这方面的一点应用。灵感来源于一位同学的问题,结合我自己的思路编写了相关程序,一并给大家展示一下。

 

 LCD液晶显示器由于具有体积小、重量轻、电压低、功耗低等特点,在大量便携式产品中得到了广泛的应用。在智能车系统中,LCD显示也提供了比LED显示更为灵活方便的一种显示解决方案。

LCD可分为段位式LCD、字符式LCD和点阵式LCD,其中段位式LCD和字符式LCD只能用于字符和数字的简单显示,不能满足图形、曲线和汉字显示的要求;而点阵式LCD不仅可以显示字符、数字、还可以显示各种图形、曲线以及汉字,并且可以实现屏幕上下左右滚动、动画、分区开窗口、反转、闪烁等多种功能。

本文以YM-0802B系列字符式LCD模块为例,叙述LCD显示在智能车系统中的应用。YM-0802B实物如下图所示,是2×8字符式LCD模块(可显示2行,每行8个字符)。

 

 

LCD显示接口设计

  

YM-0802B可以工作在全字或半字模式下。在此采用了半字模式,以节省MC9S12XS128的I/O口线。采用PORA口的高4位作为数据线,与YM-0802B的DB4~DB7连接,用PORTB的低3位作为控制线,分别与YM-0802B的RS、R/W、E连接,应用原理图下图所示。

关键的来了,我调试通过的程序:

#define LCD_EN  PORTB_BIT0
#define LCD_RW  PORTB_BIT1
#define LCD_RS  PORTB_BIT2
#define LCD_DAT  PORTA

/*************************************************************************
//功    能:检测忙信号
//入口参数:无
//出口参数:unsigned char
*************************************************************************/
unsigned char lcd_get_busy_state(void)
{
     unsigned char ret_value;

     LCD_RS = 0;
     LCD_RW = 1;
     PUCR_PUPAE = 1;    //PORTA使能上拉
     LCD_EN = 1;     //产生一EN脉冲  
 
delay_short(10);

     ret_value = LCD_DAT;  //返回最高位即数据最高位
     ret_value &= 0x80;
     PUCR_PUPAE = 0;    //PORTA上拉电阻关闭
     LCD_EN = 0;
 
delay_short(10);

    return ret_value;
}

/*************************************************************************
//功    能:向LCD写高4位数据
//入口参数:unsigned char dat
//出口参数:无
*************************************************************************/
void lcd_write_4bit(unsigned char dat)
{
DDRA = 0xF0;                //设置数据口PORTA高4位为输出
 
    LCD_DAT = dat & 0xF0  //将数据送到数据口
                           
    LCD_EN = 1;     //产生一EN脉冲  
    delay_short(10);
 
    LCD_EN = 0;
    delay_short(10);
 
    DDRA = 0x00;     //恢复数据口PORTA为输入
}

/*************************************************************************
//功    能:向LCD写命令
//入口参数:unsigned char cmd
//出口参数:无
*************************************************************************/
void lcd_write_command(unsigned char cmd)
{
while (lcd_get_busy_state() == 0x80)    //忙检测
    {
        ;
    }
      
    LCD_RS = 0;
    LCD_RW = 0;
 
    lcd_write_4bit(cmd);   //写高4位
    lcd_write_4bit(cmd<<4);   //写低4位
}

/*************************************************************************
//功    能:向LCD写数据
//入口参数:unsigned char dat
//出口参数:无
*************************************************************************/
void lcd_write_data(unsigned char dat)
{
while (lcd_get_busy_state() == 0x80) //忙检测
    {
        ;
    }
    
    LCD_RS = 1;
    LCD_RW = 0;
 
    lcd_write_4bit(dat);    //写高4位
    lcd_write_4bit(dat<<4);    //写低4位
}

/*************************************************************************
//功    能:LCD清屏
//入口参数:无
//出口参数:无
*************************************************************************/
void lcd_clear(void)
{
lcd_write_command(0x01);
}

/*************************************************************************
//功    能:LCD初始化
//入口参数:无
//出口参数:无
*************************************************************************/
void lcd_init(void)
{
DDRA = 0;      //数据口设置为输入
    DDRB_BIT0 = 1;     //控制口EN设置为输出
    DDRB_BIT1 = 1;     //控制口RS设置为输出
    DDRB_BIT2 = 1;     //控制口RW设置为输出
delay(500);                               
 
LCD_RS = 0;                               
    LCD_RW = 0;
 
lcd_write_4bit(0x20); 
    lcd_write_command(0x28);  //功能设置    
    lcd_write_command(0x0C);  //开显示,不显示光标
    lcd_write_command(0x01);  //清屏             
 
delay(30);                                
 
lcd_write_command(0x06);  //增长模式           
}

/*************************************************************************
//功    能:在指定位置显示数字
//入口参数:unsigned char x,unsigned char y,unsigned char num
//出口参数:无
*************************************************************************/
void lcd_display_number(unsigned char x, unsigned char y, unsigned char num)
{  
if ((num >= 0) && (num <= 9))
    {
        num += 0x30;
    }
 
if(x == 0)      //设置当前位置 
    {
        lcd_write_command(0x80 + y);
    }    
    else
    {
       lcd_write_command(0xC0 + y);
    }
                       
    lcd_write_data(num);   
}