微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > LCD1602实际显示位置和程序设定位置不一致

LCD1602实际显示位置和程序设定位置不一致

时间:10-02 整理:3721RD 点击:


各位大神好:
       我程序设定的显示是:     
       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);
}

先写数据,数据写入的是上一个地址位的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top