代码如下:
#include <pic.h> //调用头文件
__CONFIG(XT&WDTEN); //定义配置字,晶振类型:XT,启动开门狗
//#include <pic16f7x.h>
//__CONFIG(XT&WDTEN);
#define RSPIN RC0 //定义IO口
#define RWPIN RC1 //定义IO口
#define EPIN RC2 //定义IO口
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++)
{
for(j=0;j<10;j++)
{
asm("CLRWDT");
}
}
}
void write_bus(unsigned char buf)
{
if(buf&0x01) RB0=1;
else RB0=0;
if(buf&0x02) RB1=1;
else RB1=0;
if(buf&0x04) RB2=1;
else RB2=0;
if(buf&0x08) RB3=1;
else RB3=0;
if(buf&0x10) RB4=1;
else RB4=0;
if(buf&0x20) RB5=1;
else RB5=0;
if(buf&0x40) RB6=1;
else RB6=0;
if(buf&0x80) RB7=1;
else RB7=0;
}
void lcd_wait_busy(void)
{
TRISB7=1; //为读状态做准备,将RB7置为输入
RSPIN=0; //选择指令寄存器
RWPIN=1; //选择读
EPIN=1; //使能线电平变化
while(RB7==1); //读忙状态,不忙时退出
EPIN=0; //恢复使能线电平
TRISB7=0; //将RB0置为输出
}
void lcd_write_com(unsigned char combuf)
{
RSPIN=0; //选择指令寄存器
RWPIN=0; //选择写
write_bus(combuf); //把命令字送入P2
EPIN=1; //使能线电平变化,命令送入1602的8位数据口
asm("NOP"); //空操作,不做任何事情,只是延时一个指令周期,以下同
EPIN=0; //恢复使能线电平
}
void lcd_write_com_busy(unsigned char combuf) //1602写命令函数(带忙检测)
{
lcd_wait_busy(); //调用忙检测函数
lcd_write_com(combuf); //调用写命令函数
}
void lcd_write_data(unsigned char databuf) //1602写数据函数(带忙检测)
{
lcd_wait_busy(); //调用忙检测函数
RSPIN=1; //选择数据寄存器
RWPIN=0; //选择写
write_bus(databuf); //把databuf送入数据总线
EPIN=1; //使能线电平变化,命令送入1602的8位数据口
asm("NOP");
EPIN=0; //恢复使能线电平
}
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 //需要自行查看1602写地址的指令格式
lcd_write_com_busy((x+0x40)|0x80); //第二行的列地址写入
}
void lcdreset(void)
{
delay(150);
lcd_write_com(0x38);
delay(50);
lcd_write_com(0x38);
delay(50);
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 init(void)
{
asm("CLRWDT");
ADCON1=0X07; //RA口为数字量
OPTION=0x80; //关闭RB口电平变化功能
TRISB=0B00000000; //RB0-RB7置为输出
TRISC=0B11111000; //RC0-RC2为输出,其他未用设置为输入
RBIE=0; //RB口电平变化中断禁止
}
void main(void)
{
init(); //调用初始化函数
lcdreset(); //复位1602液晶
lcd_write_char(0,0,'A'); //在坐标(0,0)处写入A
lcd_write_char(1,0,'B'); //在坐标(1,0)处写入B
lcd_write_char(2,0,'C'); //在坐标(2,0)处写入C
lcd_write_char(3,0,'D'); //在坐标(3,0)处写入D
lcd_write_char(4,0,'E'); //在坐标(4,0)处写入E
lcd_write_char(5,0,'F'); //在坐标(5,0)处写入F
lcd_write_char(6,0,'G'); //在坐标(6,0)处写入G
lcd_write_char(7,0,'H'); //在坐标(7,0)处写入H
lcd_write_char(8,0,'I'); //在坐标(8,0)处写入I
lcd_write_char(9,0,'J'); //在坐标(9,0)处写入J
lcd_write_char(10,0,'K'); //在坐标(10,0)处写入K
lcd_write_char(11,0,'L'); //在坐标(11,0)处写入L
lcd_write_char(12,0,'M'); //在坐标(12,0)处写入M
lcd_write_char(13,0,'N'); //在坐标(13,0)处写入N
lcd_write_char(14,0,'O'); //在坐标(14,0)处写入O
lcd_write_char(15,0,'P'); //在坐标(15,0)处写入P
lcd_write_char(0,1,'Q'); //在坐标(0,1)处写入Q
lcd_write_char(1,1,'R'); //在坐标(1,1)处写入R
lcd_write_char(2,1,'S'); //在坐标(2,1)处写入S
lcd_write_char(3,1,'T'); //在坐标(3,1)处写入T
lcd_write_char(4,1,'U'); //在坐标(4,1)处写入U
lcd_write_char(5,1,'V'); //在坐标(5,1)处写入V
lcd_write_char(6,1,'W'); //在坐标(6,1)处写入W
lcd_write_char(7,1,'X'); //在坐标(7,1)处写入X
lcd_write_char(8,1,'Y'); //在坐标(8,1)处写入Y
lcd_write_char(9,1,'Z'); //在坐标(9,1)处写入Z
while(1)
{
asm("CLRWDT"); //看门狗喂狗指令,即清看门狗定时器指令
}
} |