LCD1602实际显示位置和程序设定位置不一致
各位大神好:
我程序设定的显示是:
shidu:00.0%RH
wendu:00.0%℃
调试了很久一直都没有发现到问题所在。求各位大神指点迷津。谢谢
下面是我的代码:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_DB P0
uint S1[5]; //湿度采集1bit数据
uint S2[5]; //温度采集1bit数据
int HUMIDITY_THRESHOLD=70; //湿度阈值
int TEMPERATURE_HRESHOLD =35; //温度阈值
uchar MODE_COUNT=0;
uchar FLAG;
uchar COUNT,TEMP;
uchar T_DATA_H, T_DATA_L,
RH_DATA_H, RH_DATA_L,
CHECK_DATA;
uchar T_DATA_H_TEMP, T_DATA_L_TEMP,
RH_DATA_H_TEMP, RH_DATA_L_TEMP,
CHECK_DATA_TEMP;
uchar COM_DATA;
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit DHTDATA=P3^2; //待定,DHT数据传输口
sbit MODE=P3^4; //待定,按键选择模式
sbit INCREASE=P3^5; //待定,按键加
sbit DECREASE=P3^6; //待定,按键减
sbit ALARM=P1^5; //待定,控制蜂鸣器报警
void LCD_INITIALIZATION(void); //LCD初始化函数
void LCD_WRITE_COMMAND(uchar COMMAND); //LCD写指令函数
void LCD_WRITE_DATA(uchar DAT); //LCD写数据函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT);//LCD显示一个字符
void LCD_DISPLAY(void); //LCD显示函数
void DELAY_10US(void); //延时函数,延时10us
void DELAY_MS(uint n); //延时函数,延时n*ms
void COMMUNICATION_ONE_BIT(void); //1字节数据传送函数
void DHT11_TCP(void); //DHT11传输协议
void THRESHOLD_SETTING(void); //阈值设置函数
void BUZZER_ALARM(void); //蜂鸣器报警函数
/*****************************************************************************/
//LCD初始化函数
void LCD_INITIALIZATION(void)
{
DELAY_MS(15);
LCD_WRITE_COMMAND(0x38);
DELAY_MS(15);
LCD_WRITE_COMMAND(0x38);
DELAY_MS(15);
LCD_WRITE_COMMAND(0x38);
DELAY_MS(15);
LCD_WRITE_COMMAND(0x0c);
DELAY_MS(15);
LCD_WRITE_COMMAND(0x06);
DELAY_MS(15);
LCD_WRITE_COMMAND(0x01);
DELAY_MS(15);
}
//LCD写指令函数
void LCD_WRITE_COMMAND(uchar COMMAND)
{
LCD_DB=COMMAND;
LCD_RS=0;
LCD_RW=0;
DELAY_MS(15);
LCD_EN=1;
DELAY_MS(15);
LCD_EN=0;
DELAY_MS(15);
}
//LCD写数据函数
void LCD_WRITE_DATA(uchar DAT)
{
LCD_DB=DAT;
LCD_RS=1;
LCD_RW=0;
LCD_EN=1;
DELAY_MS(15);
LCD_EN=0;
DELAY_MS(15);
}
//LCD显示一个字符函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT)
{
uchar address;
if(y==0)
address=0x80+x; //第一行显示
else
address=0xc0+x; //第二行显示
LCD_WRITE_DATA(DAT);
DELAY_MS(15);
LCD_WRITE_COMMAND(address);
DELAY_MS(15);
}
//延时10us
void DELAY_10US(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
//延时函数,延时n*ms
void DELAY_MS(uint n)
{
uint i,j;
for(i=n;i>0;i--)
for(j=110;j>0;j--);
}
//一字节数据传输函数
void COMMUNICATION_ONE_BIT(void)
{
uchar i;
FLAG=2;
for(i=0;i<8;i++)
{
while(!P3^2&&FLAG++)
{
if(P3^2&&FLAG++) break;
}
DELAY_10US();
DELAY_10US();
DELAY_10US();
if(P3^2==1)
TEMP=1;
else
TEMP=0;
COM_DATA<<=1;
COM_DATA|=TEMP;
}
}
//DHT11传输数据函数
void DHT11_TCP(void)
{
uint a,b,c,d;
FLAG=2;
DHTDATA=0;
DELAY_MS(18); //主机拉低18ms
DHTDATA=1;
DELAY_10US();
DELAY_10US();
DELAY_10US();
DELAY_10US(); //主机拉高延时40us,等待DHT11响应
DHTDATA=1; //主机设为输入状态,判断DHT11响应信号
DELAY_10US();
if(!DHTDATA) //判断DHT11是否有响应,没有响应则跳出,响应则向下运行
{
while(DHTDATA&&FLAG++); //轮询80us的DHT低电平响应是否结束
while(!DHTDATA&&FLAG++); //轮询80us的DHT高电平响应是否结束
//开始接收数据
COMMUNICATION_ONE_BIT();
RH_DATA_H_TEMP=COM_DATA;
COMMUNICATION_ONE_BIT();
RH_DATA_L_TEMP=COM_DATA;
COMMUNICATION_ONE_BIT();
T_DATA_H_TEMP=COM_DATA;
COMMUNICATION_ONE_BIT();
T_DATA_L_TEMP=COM_DATA;
COMMUNICATION_ONE_BIT();
CHECK_DATA_TEMP= COM_DATA;
DHTDATA=1; //数据传输完毕,拉高总线
//数据校验
TEMP=( T_DATA_H_TEMP+T_DATA_L_TEMP+RH_DATA_H_TEMP+RH_DATA_L_TEMP);
if(TEMP==CHECK_DATA_TEMP)
{
RH_DATA_H= RH_DATA_H_TEMP;
RH_DATA_L= RH_DATA_L_TEMP;
T_DATA_H= T_DATA_H_TEMP;
T_DATA_L= T_DATA_L_TEMP;
CHECK_DATA= CHECK_DATA_TEMP;
a=(RH_DATA_H*256+RH_DATA_L);
b=a/10;
c=(T_DATA_H*256+T_DATA_L);
d=c/10;
//湿度整数部分
S1[0]=(b/10);
S1[1]=(b%10);
//湿度小数部分
S1[2]=(a%10);
//温度整数部分
S2[0]=(d/10);
S2[1]=(d%10);
//温度小数部分
S2[2]=(c%10);
}
}
}
//LCD显示函数
void LCD_DISPLAY(void)
{
//湿度显示
LCD_DISPLAY_CHARACTER (0x00,0,'s');
LCD_DISPLAY_CHARACTER (0x01,0,'h');
LCD_DISPLAY_CHARACTER (0x02,0,'i');
LCD_DISPLAY_CHARACTER (0x03,0,'d');
LCD_DISPLAY_CHARACTER (0x04,0,'u');
LCD_DISPLAY_CHARACTER (0x05,0,':');
LCD_DISPLAY_CHARACTER (0x06,0,S1[0]+0x30);
LCD_DISPLAY_CHARACTER (0x07,0,S1[1]+0x30);
LCD_DISPLAY_CHARACTER (0x08,0,'.');
LCD_DISPLAY_CHARACTER (0x09,0,S1[2]+0x30);
LCD_DISPLAY_CHARACTER (0x0A,0,'%');
LCD_DISPLAY_CHARACTER (0x0B,0,'R');
LCD_DISPLAY_CHARACTER (0x0C,0,'H');
//温度显示
LCD_DISPLAY_CHARACTER (0x00,1,'w');
LCD_DISPLAY_CHARACTER (0x01,1,'e');
LCD_DISPLAY_CHARACTER (0x02,1,'n');
LCD_DISPLAY_CHARACTER (0x03,1,'d');
LCD_DISPLAY_CHARACTER (0x04,1,'u');
LCD_DISPLAY_CHARACTER (0x05,1,':');
LCD_DISPLAY_CHARACTER (0x06,1,S2[0]+0x30);
LCD_DISPLAY_CHARACTER (0x07,1,S2[1]+0x30);
LCD_DISPLAY_CHARACTER (0x08,1,'.');
LCD_DISPLAY_CHARACTER (0x09,1,S2[2]+0x30);
LCD_DISPLAY_CHARACTER (0x0A,1,0xDF);
LCD_DISPLAY_CHARACTER (0x0B,1,'C');
}
//阈值设置函数
void THRESHOLD_SETTING(void)
{
S1[3]=(uchar)(0x30+HUMIDITY_THRESHOLD/10);
S1[4]=(uchar)(0x30+HUMIDITY_THRESHOLD%10);
S2[3]=(uchar)(0x30+TEMPERATURE_HRESHOLD/10);
S2[4]=(uchar)(0x30+TEMPERATURE_HRESHOLD%10);
if(MODE==0)
{
DELAY_MS(10); //放抖动
MODE_COUNT++;
}
if(MODE_COUNT==1) //模式1,选择调节湿度阈值
{
if(INCREASE==0)
{
DELAY_MS(10);
HUMIDITY_THRESHOLD++;
}
else if (DECREASE==0)
{
DELAY_MS(10);
HUMIDITY_THRESHOLD--;
}
//显示模式选择和阈值加减
LCD_DISPLAY_CHARACTER (13,1,' ');
LCD_DISPLAY_CHARACTER (13,2,' ');
LCD_DISPLAY_CHARACTER (14,1,' ');
LCD_DISPLAY_CHARACTER (14,2,' ');
S1[3]=HUMIDITY_THRESHOLD/10;
S1[4]=HUMIDITY_THRESHOLD%10;
S2[3]=TEMPERATURE_HRESHOLD/10;
S2[4]=TEMPERATURE_HRESHOLD%10;
LCD_DISPLAY_CHARACTER (13,1,S1[3]+0x30);
LCD_DISPLAY_CHARACTER (13,2,S1[4]+0x30);
LCD_DISPLAY_CHARACTER (14,1,S2[3]+0x30);
LCD_DISPLAY_CHARACTER (14,2,S2[4]+0x30);
}
else if(MODE_COUNT==2) //模式2,选择调节温度阈值
{
if(INCREASE==0)
{
DELAY_MS(10);
TEMPERATURE_HRESHOLD++;
}
else if (DECREASE==0)
{
DELAY_MS(10);
TEMPERATURE_HRESHOLD--;
}
//显示模式选择和阈值加减
LCD_DISPLAY_CHARACTER (14,1,' ');
LCD_DISPLAY_CHARACTER (14,2,' ');
LCD_DISPLAY_CHARACTER (15,1,' ');
LCD_DISPLAY_CHARACTER (15,2,' ');
S1[3]=HUMIDITY_THRESHOLD/10;
S1[4]=HUMIDITY_THRESHOLD%10;
S2[3]=TEMPERATURE_HRESHOLD/10;
S2[4]=TEMPERATURE_HRESHOLD%10;
LCD_DISPLAY_CHARACTER (14,1,S1[3]+0x30);
LCD_DISPLAY_CHARACTER (14,2,S1[4]+0x30);
LCD_DISPLAY_CHARACTER (15,1,S2[3]+0x30);
LCD_DISPLAY_CHARACTER (15,2,S2[4]+0x30);
}
else if (MODE_COUNT==3)
{
DELAY_MS(10);
LCD_DISPLAY_CHARACTER (14,1,' ');
LCD_DISPLAY_CHARACTER (14,2,' ');
LCD_DISPLAY_CHARACTER (15,1,' ');
LCD_DISPLAY_CHARACTER (15,2,' ');
MODE_COUNT=0;
}
}
//蜂鸣器报警函数
void BUZZER_ALARM(void)
{
if((RH_DATA_H>HUMIDITY_THRESHOLD)||(T_DATA_H>TEMPERATURE_HRESHOLD))
ALARM=0;
else
ALARM=1;
}
//主函数
void main()
{
DELAY_MS(15);
LCD_INITIALIZATION();
DELAY_MS(15);
while(1)
{
DELAY_MS(15);
DHT11_TCP();
LCD_DISPLAY();
BUZZER_ALARM();
THRESHOLD_SETTING();
}
}
//LCD显示一个字符函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT)
{
? ? ? ? uchar address;
? ? ? ? if(y==0)
? ? ? ? ? ? ? ? address=0x80+x;? ? ? ? ? ? ? ? //第一行显示
? ? ? ? else
? ? ? ? ? ? ? ? address=0xc0+x;? ? ? ? ? ? ? ? //第二行显示
? ? ? ? LCD_WRITE_DATA(DAT);
? ? ? ? DELAY_MS(15);
? ? ? ? LCD_WRITE_COMMAND(address);
? ? ? ? DELAY_MS(15);
}改成
//LCD显示一个字符函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT)
{
? ? ? ? uchar address;
? ? ? ? if(y==0)
? ? ? ? ? ? ? ? address=0x80+x;? ? ? ? ? ? ? ? //第一行显示
? ? ? ? else
? ? ? ? ? ? ? ? address=0xc0+x;? ? ? ? ? ? ? ? //第二行显示
? ? ? ?
? ? ? ? LCD_WRITE_COMMAND(address);
? ? ? ? DELAY_MS(15);//先写入命令再写内容
LCD_WRITE_DATA(DAT);
? ? ? ? DELAY_MS(15);
}
看看 的撒旦撒的撒打算的撒打算的
应该你的哪边设置有问题吧
《LCD显示一个字符》这个函数里的写命令和写数据语句的顺序反了。
不太了解 不过感觉4楼所说在理
我最后改成了以下。显示问题解决了。
得出的结论是:先写数据再写地址,数据写入的是上一个地址位的
谢谢豆子和heaton
//LCD显示一个字符函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT)
{
uchar address;
if(y==0)
address=0x80+x; //第一行显示
else
address=0xc0+x; //第二行显示
LCD_WRITE_DATA(DAT);
DELAY_MS(15);
LCD_WRITE_COMMAND(address);
DELAY_MS(15);
}改成
//LCD显示一个字符函数
void LCD_DISPLAY_CHARACTER(uchar x,uchar y,uchar DAT)
{
uchar address;
if(y==0)
address=0x80+x; //第一行显示
else
address=0xc0+x; //第二行显示
LCD_WRITE_COMMAND(address);//先写入命令再写内容
LCD_WRITE_DATA(DAT);
DELAY_MS(15);
}
先写数据,数据写入的是上一个地址位的