LCD1602用C语言编程如何显示字符? 5
软件:MPlABv8.70。单片机:PIC32MX795F512L,主频80MHz以下是我写的代码:头文件:test.h#include<plib.h>//voidLCD...
软件:MPlABv8.70。单片机:PIC32MX795F512L,主频80MHz以下是我写的代码:
头文件:test.h
#include<plib.h>
//void LCD_busy_wait();//忙则等待
void delay(uint z);//延时,1微妙
void LCD_write_cmd(uchar cmd);//写命令
void LCD_write_data(uchar data);//显示字符
void LCD_init();//初始化
void LCD_disp_char(uchar x,uchar y,uchar dat);//在指定位置显示一个字符
/*void LCD_busy_wait()
{
do
{
E=0;
RS=0;
RW=1;
DB0=1;DB1=1;DB2=1;DB3=1;DB4=1;DB5=1;DB6=1;DB7=1;
E=1;
}while(DB7==1);
}*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
void LCD_write_cmd(uchar cmd)
{
PORTSetPinsDigitalOut(IOPORT_E, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);//IO口设为输出
PORTSetPinsDigitalOut(IOPORT_G, BIT_13|BIT_12|BIT_14|BIT_0);
PORTSetPinsDigitalOut(IOPORT_A, BIT_7|BIT_6);
DB0=cmd%2;
DB1=(cmd/2)%2;
DB2=(cmd/4)%2;
DB3=(cmd/8)%2;
DB4=(cmd/16)%2;
DB5=(cmd/32)%2;
DB6=(cmd/64)%2;
DB7=(cmd/128)%2;
E=1;
RS=0;
RW=0;
E=0;
delay(5);
//LCD_busy_wait();
}
void LCD_write_data(uchar data)
{
PORTSetPinsDigitalOut(IOPORT_E, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
PORTSetPinsDigitalOut(IOPORT_G, BIT_13|BIT_12|BIT_14|BIT_0);
PORTSetPinsDigitalOut(IOPORT_A, BIT_7|BIT_6);
DB0=data%2;
DB1=(data/2)%2;
DB2=(data/4)%2;
DB3=(data/8)%2;
DB4=(data/16)%2;
DB5=(data/32)%2;
DB6=(data/64)%2;
DB7=(data/128)%2;
E=1;
RS=1;
RW=0;
E=0;
delay(5);
//LCD_busy_wait();
}
void LCD_init()
{
LCD_write_cmd(0x01);delay(100);//清屏
LCD_write_cmd(0x38);//8位,2行,5×7点阵
LCD_write_cmd(0x06);//输入后光标右移
LCD_write_cmd(0x0e);//显示光标并闪烁
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==0)
{address=0x80+x;}
else
{address=0xc0+x;}
LCD_write_cmd(address);
LCD_write_data(dat);
}
主函数:test.c
#include"test.h"
void main()
{
LCD_init();
//LCD_disp_char(3,0,0x30);
while(1);
}
已知IO口没接错,LCD应该不是坏的,输出电平用电压表测过是正确的。但是就是什么都不显示。主函数中LCD_disp_char(3,0,0x30);前面的注释是后来才加的,不是这个的问题。 展开
头文件:test.h
#include<plib.h>
//void LCD_busy_wait();//忙则等待
void delay(uint z);//延时,1微妙
void LCD_write_cmd(uchar cmd);//写命令
void LCD_write_data(uchar data);//显示字符
void LCD_init();//初始化
void LCD_disp_char(uchar x,uchar y,uchar dat);//在指定位置显示一个字符
/*void LCD_busy_wait()
{
do
{
E=0;
RS=0;
RW=1;
DB0=1;DB1=1;DB2=1;DB3=1;DB4=1;DB5=1;DB6=1;DB7=1;
E=1;
}while(DB7==1);
}*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
void LCD_write_cmd(uchar cmd)
{
PORTSetPinsDigitalOut(IOPORT_E, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);//IO口设为输出
PORTSetPinsDigitalOut(IOPORT_G, BIT_13|BIT_12|BIT_14|BIT_0);
PORTSetPinsDigitalOut(IOPORT_A, BIT_7|BIT_6);
DB0=cmd%2;
DB1=(cmd/2)%2;
DB2=(cmd/4)%2;
DB3=(cmd/8)%2;
DB4=(cmd/16)%2;
DB5=(cmd/32)%2;
DB6=(cmd/64)%2;
DB7=(cmd/128)%2;
E=1;
RS=0;
RW=0;
E=0;
delay(5);
//LCD_busy_wait();
}
void LCD_write_data(uchar data)
{
PORTSetPinsDigitalOut(IOPORT_E, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
PORTSetPinsDigitalOut(IOPORT_G, BIT_13|BIT_12|BIT_14|BIT_0);
PORTSetPinsDigitalOut(IOPORT_A, BIT_7|BIT_6);
DB0=data%2;
DB1=(data/2)%2;
DB2=(data/4)%2;
DB3=(data/8)%2;
DB4=(data/16)%2;
DB5=(data/32)%2;
DB6=(data/64)%2;
DB7=(data/128)%2;
E=1;
RS=1;
RW=0;
E=0;
delay(5);
//LCD_busy_wait();
}
void LCD_init()
{
LCD_write_cmd(0x01);delay(100);//清屏
LCD_write_cmd(0x38);//8位,2行,5×7点阵
LCD_write_cmd(0x06);//输入后光标右移
LCD_write_cmd(0x0e);//显示光标并闪烁
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==0)
{address=0x80+x;}
else
{address=0xc0+x;}
LCD_write_cmd(address);
LCD_write_data(dat);
}
主函数:test.c
#include"test.h"
void main()
{
LCD_init();
//LCD_disp_char(3,0,0x30);
while(1);
}
已知IO口没接错,LCD应该不是坏的,输出电平用电压表测过是正确的。但是就是什么都不显示。主函数中LCD_disp_char(3,0,0x30);前面的注释是后来才加的,不是这个的问题。 展开
3个回答
展开全部
void delay(uint z);//延时,1微妙时间有点短
你看看下面我做的程序,在2051+12M晶振通过你可以套用这个程序,不行的话就改长延时
/******************AT89S51使用12M晶振*******************/
//LCD脚接法,根据实际接法定义
#define LCM_D4_RS P3_2//第4脚数据/命令
#define LCM_D5_RW P3_5//第5脚读/写
#define LCM_D6_E P3_7//第6脚使能
#define LCM_D16_BLK P3_0//背光负极
#define LCM_D7_Data P1//第7-14脚数据
//LCD脚接法,根据实际接法定义
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define _LCD_BIT_IS 4 //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
#include <at89x51.h> //头文件
#include <string.h> //strlen()函数头文件
void LCMInit(void); //LCM初始化化
void WriteDataLCM(unsigned char WDLCM); //写数据
void WriteCommandLCM(unsigned char WCLCM,int BuysC); //写指令
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); //按指定位置显示一个字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//按指定位置显示一串字符
void Delay5Ms(void); //5ms延时
unsigned char ReadStatusLCM(void); //读状态
unsigned char code Greetings_Line1[] = {"Welcome Control"};
unsigned char code Greetings_Line2[] = {" ChuLong Make "};
data unsigned char cou = 0; // 定义软计数器,放在程序最前面的寄存器定义部分
void main(void)
{
LCMInit(); //LCM初始化
LCM_D16_BLK = 0; //开背光灯
TMOD = 0x11; // 定时/计数器0,1工作于方式1 16位定时
TH0 = 0x3c; // 预置产生50ms时基信号
TL0 = 0xb0;
EA = 1; // 开总中断
ET0 = 1; // 定时/计数器0允许中断
TR0 = 1; // 开定时/计数器0
DisplayListChar(0, 0, Greetings_Line1);
DisplayListChar(0, 1, Greetings_Line2);
// while(1);
}
//
void LCMInit(void) //LCM初始化
{
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
WriteCommandLCM(0x38,1); //显示8位模式设置,开始要求每次检测忙信号
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
WriteCommandLCM(0x28,1); //显示4位模式设置,开始要求每次检测忙信号
#endif
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_D4_RS = 1;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
{
LCM_D7_Data = WDLCM;
}
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WDLCM = WDLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,int BuysC) //BuysC为0时忽略忙检测
{
if(BuysC)
ReadStatusLCM(); //根据需要检测忙
LCM_D4_RS = 0;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
{
LCM_D7_Data = WCLCM;
}
#else
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WCLCM = WCLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_D7_Data = 0xff;
LCM_D4_RS = 0;
LCM_D5_RW = 1;
LCM_D6_E = 1;
while (LCM_D7_Data & Busy); //检测忙信号
return(LCM_D7_Data);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
int ListLength;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
for(ListLength = 0;ListLength < strlen(DData);ListLength++) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
X++;
}
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//10s延时
void tiem0(void) interrupt 1
{ // T/C0中断服务程序(产生50ms时基信号)
if(cou < 60)
{ // 计数值到1000(1s) (****时间为倒计时****)
cou = 0; // 软计数器清零
}
cou++; // 软计数器加1
TH0 = 0x3c; // 重置定时常数
TL0 = 0xb0;
}
你看看下面我做的程序,在2051+12M晶振通过你可以套用这个程序,不行的话就改长延时
/******************AT89S51使用12M晶振*******************/
//LCD脚接法,根据实际接法定义
#define LCM_D4_RS P3_2//第4脚数据/命令
#define LCM_D5_RW P3_5//第5脚读/写
#define LCM_D6_E P3_7//第6脚使能
#define LCM_D16_BLK P3_0//背光负极
#define LCM_D7_Data P1//第7-14脚数据
//LCD脚接法,根据实际接法定义
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
#define _LCD_BIT_IS 4 //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
#include <at89x51.h> //头文件
#include <string.h> //strlen()函数头文件
void LCMInit(void); //LCM初始化化
void WriteDataLCM(unsigned char WDLCM); //写数据
void WriteCommandLCM(unsigned char WCLCM,int BuysC); //写指令
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); //按指定位置显示一个字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);//按指定位置显示一串字符
void Delay5Ms(void); //5ms延时
unsigned char ReadStatusLCM(void); //读状态
unsigned char code Greetings_Line1[] = {"Welcome Control"};
unsigned char code Greetings_Line2[] = {" ChuLong Make "};
data unsigned char cou = 0; // 定义软计数器,放在程序最前面的寄存器定义部分
void main(void)
{
LCMInit(); //LCM初始化
LCM_D16_BLK = 0; //开背光灯
TMOD = 0x11; // 定时/计数器0,1工作于方式1 16位定时
TH0 = 0x3c; // 预置产生50ms时基信号
TL0 = 0xb0;
EA = 1; // 开总中断
ET0 = 1; // 定时/计数器0允许中断
TR0 = 1; // 开定时/计数器0
DisplayListChar(0, 0, Greetings_Line1);
DisplayListChar(0, 1, Greetings_Line2);
// while(1);
}
//
void LCMInit(void) //LCM初始化
{
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
WriteCommandLCM(0x38,1); //显示8位模式设置,开始要求每次检测忙信号
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
WriteCommandLCM(0x28,1); //显示4位模式设置,开始要求每次检测忙信号
#endif
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_D4_RS = 1;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB0-DB8这8根数据线进行传输
{
LCM_D7_Data = WDLCM;
}
#else //CPU与LCD1602间使用DB0-DB4这4根数据线进行传输
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WDLCM = WDLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WDLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,int BuysC) //BuysC为0时忽略忙检测
{
if(BuysC)
ReadStatusLCM(); //根据需要检测忙
LCM_D4_RS = 0;
LCM_D5_RW = 0;
#if(_LCD_BIT_IS == 8) //CPU与LCD1602间使用DB7-DB4这4根数据线进行传输
{
LCM_D7_Data = WCLCM;
}
#else
{
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写高四位
LCM_D6_E = 0;
LCM_D6_E = 1;
WCLCM = WCLCM << 4; //低四位移到高四位
LCM_D7_Data &= 0x0f; //清高四位
LCM_D7_Data |= WCLCM & 0xf0; //写低四位
}
#endif
LCM_D6_E = 0;
LCM_D6_E = 1;
}
//读状态
unsigned char ReadStatusLCM(void)
{
LCM_D7_Data = 0xff;
LCM_D4_RS = 0;
LCM_D5_RW = 1;
LCM_D6_E = 1;
while (LCM_D7_Data & Busy); //检测忙信号
return(LCM_D7_Data);
}
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
int ListLength;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
for(ListLength = 0;ListLength < strlen(DData);ListLength++) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
X++;
}
}
}
//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//10s延时
void tiem0(void) interrupt 1
{ // T/C0中断服务程序(产生50ms时基信号)
if(cou < 60)
{ // 计数值到1000(1s) (****时间为倒计时****)
cou = 0; // 软计数器清零
}
cou++; // 软计数器加1
TH0 = 0x3c; // 重置定时常数
TL0 = 0xb0;
}
展开全部
1、需要修改引脚设置,就到LCD1602.h中修改
2、主函数头写上#include“LCD1602.h”,将“LCD1602.c”添加到项目中
3、使用的时候先调用LCD1602_initialise();对1602初始化;其中光标移动方式已经设定好了
4、根据需要开关函数开关(注释掉定义就是关闭相应函数,取消注释则是打开),调用相关函数。关于函数功能,库文件注释得很详细,请自行查看;
提供一段main()函数代码,供参考:
#include<REG52.h>
#include"LCD1602.h"
void main(void)
{
LCD1602_initialise();
LCD1602_displayStr(0,0,"Hello World!");
LCD1602_displayInt(1,0,2015);
while(1);
}
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询