资源描述
实验七
一、 阅读(要求做相应的笔记记录)
阅读1602液晶片手册
二、 硬件电路(内部线已连接,不需要外部排线)
说明:
VSS:电源地;
VDD:电源;
VL(第3脚):提供偏压,电压太低无显示,电压太高全黑;
RS/RW/E:控制总线;
DB0-DB7:数据总线;
R25:背光LED限流电阻
1602,一共可以两行,每行16个字符显示;
上电运行后要先设置工作模式;
每个字符显示有一个对应的寄存器地址,在寄存器中写入ASCII字符值,就可以显示相应的字符。
三、 测试代码
#include <p18F452.h> //调用头文件
#include <delays.h>
#define RSPIN PORTBbits.RB5 //Data or Instrument Select
#define RWPIN PORTBbits.RB4 //Write or Read
#define EPIN PORTBbits.RB3 //6800 mode Enable single
//---------------------------------------
//名称: 1602忙检测函数
//-----------------------------------------
void lcd_wait_busy(void)
{
TRISDbits.TRISD7=1; //为读状态做准备
RSPIN=0; //选择指令寄存器
RWPIN=1; //选择读
EPIN=1; //使能线电平变化
while(PORTDbits.RD7==1); //读忙状态,不忙时退出
EPIN=0; //恢复使能线电平
TRISDbits.TRISD7=0;
}
//---------------------------------------
//名称: 1602写命令函数
//-----------------------------------------
void lcd_write_com(unsigned char combuf)
{
RSPIN=0; //选择指令寄存器
RWPIN=0; //选择写
PORTD=combuf; //把命令字送入RD
EPIN=1; //使能线电平变化,命令送入1602的8位数据口
Delay1TCY();
EPIN=0; //恢复使能线电平
}
//---------------------------------------
//名称: 1602写命令函数(带忙检测)
//-----------------------------------------
void lcd_write_com_busy(unsigned char combuf)
{
lcd_wait_busy(); //调用忙检测函数
lcd_write_com(combuf); //调用写命令函数
}
//---------------------------------------
//名称: 1602写数据函数(带忙检测)
//-----------------------------------------
void lcd_write_data(unsigned char databuf)
{
lcd_wait_busy(); //调用忙检测函数
RSPIN=1; //选择数据寄存器
RWPIN=0; //选择写
PORTD=databuf; //把数据字送入P2
EPIN=1; //使能线电平变化,命令送入1602的8位数据口
Delay1TCY();
EPIN=0; //恢复使能线电平
}
//---------------------------------------
//名称: 1602显示地址写函数
//-----------------------------------------
void lcd_write_address(unsigned char x,unsigned char y)
{
x&=0x0f; //列地址限制在0-15
y&=0x01; //行地址限制在0-1
if(y==0x00)
lcd_write_com_busy(x|0x80); //第一行的列地址写入
else
lcd_write_com_busy((x+0x40)|0x80); //第二行的列地址写入
}
//---------------------------------------
//名称: 1602初始化函数
//-----------------------------------------
void lcdreset(void)
{
Delay100TCYx(15);
lcd_write_com(0x38);
Delay100TCYx(5);
lcd_write_com(0x38);
Delay100TCYx(5);
lcd_write_com(0x38);
lcd_write_com_busy(0x38); //8位数据,双列,5*7字形
lcd_write_com_busy(0x08); //显示功能关,无光标
lcd_write_com_busy(0x01); //清屏指令
lcd_write_com_busy(0x06); //写入新的数据后,光标右移,显示屏不移动
lcd_write_com_busy(0x0c); //显示功能开,无光标,
}
//---------------------------------------
//名称: 指定地址写入函数
//-----------------------------------------
void lcd_write_char(unsigned char x,unsigned char y,unsigned char buf)
{
lcd_write_address(x,y); //写入地址
lcd_write_data(buf); //写入显示数据
}
//---------------------------------------
//名称: 主函数
//-----------------------------------------
void main(void)
{
ADCON1=0X06; //所有IO均为数字口,模拟量输入禁止
TRISB=0B11000111; //RB3-5设置为输出
TRISD=0B00000000; //RD设置为输出
lcdreset(); //复位1602
lcd_write_char(0,0,0x41); //A
lcd_write_char(1,0,0x42); //B
lcd_write_char(2,0,0x43); //C
lcd_write_char(3,0,0x44); //D
lcd_write_char(4,0,0x45); //E
lcd_write_char(5,0,0x46); //F
lcd_write_char(6,0,0x47); //G
lcd_write_char(7,0,0x48); //H
lcd_write_char(8,0,0x49); //I
lcd_write_char(9,0,0x4A); //J
lcd_write_char(10,0,0x4B); //K
lcd_write_char(11,0,0x4C); //L
lcd_write_char(12,0,0x4D); //M
lcd_write_char(13,0,0x4E); //N
lcd_write_char(14,0,0x4F); //O
lcd_write_char(15,0,0x50); //P
lcd_write_char(0,1,0x61); //a
lcd_write_char(1,1,0x62); //b
lcd_write_char(2,1,0x63); //c
lcd_write_char(3,1,0x64); //d
lcd_write_char(4,1,0x65); //e
lcd_write_char(5,1,0x66); //f
lcd_write_char(6,1,0x67); //g
lcd_write_char(7,1,0x68); //h
lcd_write_char(8,1,0x69); //i
lcd_write_char(9,1,0x6A); //j
lcd_write_char(10,1,0x6B); //k
lcd_write_char(11,1,0x6C); //l
lcd_write_char(12,1,0x6D); //m
lcd_write_char(13,1,0x6E); //n
lcd_write_char(14,1,0x6F); //o
lcd_write_char(15,1,0x70); //p
while(1)
{
}
}
四、 重点理解
代码的设计是以时序图为依据的;
代码运行I/O端口的输出波形和时序图是一致的;
五、 思考
测试程序是每次写一个字符,你可以设计一个写字符串的子程序么?
5
展开阅读全文