首页 > 代码库 > 自己动手做个智能小车(6)

自己动手做个智能小车(6)

自己动手做个智能小车(6)

——给小车装个脸(显示屏)

现在轮子可以由程序控制了,但总感觉少点啥,程序在跑,但不知道里面的情况,就象一台电脑没有显示器一样。所以我们也来组小车安装个小显示器。

选什么屏呢,对于小的屏幕,就当然是比较流程的1602LCD了:

1602字符型LCD专门用于显示数字、字母、图形符号和少量的自定义符号。这类显示器的LCD控制器、点阵驱动器、字符存储器等做在一块板上,再与液晶屏一起组成一个显示模块,这类显示器的安装和使用非常简单。

目前字符型LCD常用的有16字行、16字X2行、20字X2行、20字X4行等液晶模块,型号通常用XXX1602、XXX1604、X2002、XXX2004等其中为厂家商标名称16代表液晶每行可以显示16个字符,02代表共有2行,也就是说这个液晶一共可以显示32字符。

如何连接呢,比较容易,连接图如下:

图中,

第1脚:vss为地电源,

第2脚:VDD接5V正电源"

第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生"鬼影",使用时可以通过一个10K的电位器调整对此度,

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器"

第5脚;R/W,为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/V共同为低电平时可以写入指令或者显示地址,当RS为低电平R/w为高电平时可以读忙信号,当RS为高电平R/w为低电平时可以写入数据,

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:DO—D7为8位双向数据线,实际过程中,为了减少接口的使用(多留些给以后扩展用),所以我们采用4根线的(即用D0~D3),就是一个8位数据通过4根线传输2次。

第15脚:背光源正极,

第16脚:背光源负极。

?

小车中连接后的效果如下:

?

好了,连接好了硬件后,就开始软件了,为了方便管理,代码增加一个LCD.c类:

同时,为了方便调用,对外,我们提供两个函数:

LcdInitiate() 用于对液晶片初步化;

Print(字符串) 用于将字符串显示在屏上,跟C语言习惯相似。

?

好了,上代码:

?

?

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

* LCD.c 描述:

* LCD1602可以分为8位和4位控制方式,8位控制方式是用D0-D7数据线

* 来传送控制命令及数据。4位控制方式是用D4-D7数据线来传送控制命令

* 及数据。使用4位数据线做控制时,需要分两次来传送,先送出高4位数

* 据,再送出低4位数据。可以节省单片机的4根端口线。

*

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

#include "common.h"

?

sfr LCD_Data = 0x80; //P0 显示接入P0口的高4 P4 P5 P6 P7

sbit LCD_RS=P0^3; //寄存器选择位,将RS位定义为P2.0引脚

sbit LCD_BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚

sbit LCD_RW=P2^6; //读写选择位,将RW位定义为P2.1引脚

sbit LCD_EN=P2^7; //使能信号位,将E位定义为P2.2引脚

?

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

* 5us 延时子程序

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

void delayNOP()

{

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

}

?

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

* 检查LCD忙状态

* lcd_busy1时,忙,等待。

* lcd-busy0,闲,可写指令与数据

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

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

delayNOP();

result = LCD_BF;

LCD_EN = 0;

return(result);

}

?

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

* 写指令或数据

* start=0, 写入命令; start=1, 写入数据

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

?

void lcd_write(bit start, uchar in_data)

{

uchar Hdata,Ldata;

?

while(lcd_busy());

?

Hdata=in_data&0xf0; //取高四位

Ldata=(in_data<<4)&0xf0; //取低四位

?

if(start==0)

LCD_RS = 0; //写入命令

else

LCD_RS = 1; //写入数据

?

LCD_RW = 0;

LCD_EN = 0;

delayNOP();

?

//发送高四位

LCD_Data = LCD_Data & 0x0F;

LCD_Data = Hdata | LCD_Data;

?

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

delayNOP();

?

//发送低四位

LCD_Data = LCD_Data & 0x0F;

LCD_Data = Ldata | LCD_Data;

?

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

delayNOP();

}

?

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

* LCD初始化设定

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

void LcdInitiate()

{

Delay(15);

lcd_write(0,0x28); //16*2显示,5*7点阵,4位数据

Delay(5);

lcd_write(0,0x28);

Delay(5);

lcd_write(0,0x28);

?

Delay(5);

lcd_write(0,0x0c); //显示开,关光标

Delay(5);

lcd_write(0,0x06); //移动光标

Delay(5);

lcd_write(0,0x01); //清除LCD的显示内容

Delay(25); //延时

}

?

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

* 设定显示位置

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

void lcd_pos(uchar pos)

{

lcd_write(0,pos|0x80); //数据指针=80+地址变量

}

?

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

* 显示字符串

* 示例: print("Hello World!") print("aaa\rbbb")

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

void print(unsigned char *str)

{

unsigned char i;

lcd_write(0,0x01); //清除LCD的显示内容

Delay(10);

lcd_pos(0); // 设置显示位置为第一行的第1个字

i = 0;

while(*str != ‘\0‘) //‘\0‘是数组结束标志

{

//超过一行时,另起一行

if (i == 16 || str[i] == ‘\r‘)

lcd_pos(0x40); //设置显示位置为第二行

?

if (*str == ‘\r‘)

{

i++;

str++;

continue;

}

?

lcd_write(1,*str);

i++;

str++;

}

}

?

有了这个显示函数(print),我们就很方便在主函数中调一下,比如print("Hello")之类的进行测试。 同时也可以将给小车的PWM值显示出来。