关于#单片机#的问题:设计了一个基于adc0808,lcd1602和at89c52的数字电压表,但是lcd在仿真的时候出现的数据是乱码

设计了一个基于adc0808,lcd1602和at89c52的数字电压表,但是lcd在仿真的时候出现的数据是乱码;
以下是仿真图片:

img

以下是主函数图片:

img


以下是adc0809转换的代码:

img

img


以下是lcd1602的代码:

#include <REGX52.H>
#include <LCD1602.H>
//引脚配置:
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
    
void delay_us(unsigned char us)
{
    while(us--);
}
    
void delay_ms(unsigned char ms)
{
    while(ms--)
    {
        delay_us(248);
        delay_us(248);
    }
}
void LCD_Delay()
{
    unsigned char i, j;

    i = 2;
    j = 239;
    do
    {
        while (--j);
    } while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void write_con(unsigned char con)
{
    LCD_RS=0;
    LCD_RW=0;
    LCD_DataPort=con;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void write_dat(unsigned char dat)
{
    LCD_RS=1;
    LCD_RW=0;
    LCD_DataPort=dat;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
    write_con(0x01);//清屏
    write_con(0x38);//设置16*2显示,配置8位数据接口
  write_con(0x38);//设置16*2显示,配置8位数据接口
    write_con(0x0C);//开显示,光标关,闪烁关,去黑块
    write_con(0x06);//写数据时光标右移,画面不动

}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */

void LcdDisplay(unsigned char x,unsigned char y,unsigned char *str)
{
   LcdSetCursor(x,y); //设置起始地址  
     while(*str !='\0')  //连续写入字符串数据,直到检测到结束符
     {
         
        write_dat(*str++);  //先取str指向的数据,然后str自加1
        delay_us(100);
        
     }
}

void LcdSetCursor(unsigned char x,unsigned char y)
{
    unsigned char addr;
    if(y==0)    //由输入的屏幕坐标计算显示RAM的地址
        addr=0x00+x;    //第一行字符地址从0x00起始
    else
        addr=0x40+x;    //第二行字符地址从0x40起始
    write_con(addr|0x80);   //设置RAM地址
        
}

void LcdStar()
{
    unsigned char code str[]="Voltage measure";
    unsigned char tab[]="Voltage=";
    LCD_Init();                    //初始化1602液晶  
    LcdDisplay(1,0,str);
    LcdDisplay(1,1,tab);
    LcdDisplay(9,1,".");        //默认初始化温度00
    LcdDisplay(13,1,"V");         //添加V电压
}
#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LcdStar();
void write_con(unsigned char con);
void write_dat(unsigned char con);
void LcdDisplay(unsigned char x,unsigned char y,unsigned char *str);
void LcdSetCursor(unsigned char x,unsigned char y);
#endif


出现的结果:

img

main 代码有些问题
第7行代码改成
unsigned char Display_Buffer[5];
在 21 行代码后面加上这行
Display_Buffer[4] = 0;
另外 ad_show 是 8位的,你最多能测量 2.55 V 的电压
建议将 ad_show 改成 16 位的

main.c,把display_buffer定义为5字节,并且最后一个字节写0, 因为LcdDisplay函数是把它当字符串处理的,遇不到字符串结尾会一直往后写。

【相关推荐】



  • 这篇博客: 从51开始的单片机之旅(二)----LCD1602液晶、ADC0809、DAC0832中的 七、最后找了两张实物图 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    (前一个的图没找到、、、)

    在这里插入图片描述
    在这里插入图片描述

    下一篇就总结模电的几个实验,能写得这么多是当时做的准备工作和课后总结的效果,我们每一次实验结束都要自己进行总结和讨论,我觉得这是一个很好的学习方式,看千遍不如做一遍,这个是真理,如果感觉这文章对你有所帮助,请在评论区留个爪


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^