显示屏只能显示一个功能,在主函数中改变显示的顺序,哪个在前面只显示哪个,下面是源程序,麻烦帮忙看一下是哪里有问题,谢谢
单片机源程序如下:
#include<reg51.h>
#include < intrins.h >
#define GapValue 1960
#define uchar unsigned char
#define uint unsigned int
uchar m;
sbit HX711_DOUT=P2^1; //HX711AD模块IO端口设置
sbit HX711_SCK=P2^0;
unsigned long Weight_shuibei =0;
unsigned int t;
unsigned char *p,c;
long Weight_shui = 0;
bit Flag_ERROR = 0;
void Delay__hx711_us(void); //函数或者变量声明
unsigned long HX711_Read(void);
void Get_shuibei();
void Get_Weight();
#define lcddata P0
sbit LCDRS = P2^7 ; // 命令/数据选择端 0为写命令 1为写数据
sbit LCDRW = P2^6 ; // lcd读写端
sbit LCDEN = P2^5 ; //lcd使能端
void write_com(uchar com);
unsigned char code mytab[8] = {0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00} ;//lcd自定义字符
sbit DQ = P1^3; //定义DS18B20端口DQ
bit presence; //ds18b20 DQ被拉低 信号0允许,1禁止
uint cc,cc2; //变量cc中保存读出的温度值
float cc1;
uchar flag; //flag为温度值正负标志位,“1”表示温度为负值,“0”表示为正值
unsigned char data temp_data[2] = {0x00,0x00} ; //存储16位温度
uchar code cdis0[ ] = "CHECKING...";
uchar code cdis1[ ] = " DS18B20 OK " ;
uchar code cdis5[ ] = "Temp: ";
uchar cdis2[ ] = "+00.00";
uchar code cdis3[ ] = " DS18B20 ERR0R " ;
uchar code cdis6[ ] = "Volume:";
uchar cdis7[ ] = "0000";
uchar code cdis8[ ] = "Volume: over ml";
uchar code cdis9[ ] = " HX711 OK " ;
/*ms级别延时 */
void ddelay(uint ms)
{
uint i;
uchar j;
for(i=0;i<ms;i++)
for(j=0;j<250;j++)
{
_nop_(); //一个机器周期,1us
_nop_(); //适用于精度高的
_nop_();
_nop_();
}
}
/**********************************lcd1602********************************************/
void delaylcd(uint z)
{uchar x,y;
for(x=z;x>0;x--)
{for(y=110;y>0;y--);
}
}
/*lcd1602初始化 */
/**********************************/
void lcd_init(void)
{
LCDRW=0; //低电平为写
LCDEN=0;
write_com(0x38); //使用8位数据开关,显示两行,使用5*7字形
write_com(0x0c); //显示器开,光标关,字符不闪烁 0x0e 光标开
write_com(0x06); //字符不动,光标自动右移动一位
write_com(0x01); //清屏
}
/*写命令to lcd */
/**********************************/
void write_com(uchar com)//写命令
{
LCDRW=0; //低电平为写
LCDRS=0; //低电平为命令选择
lcddata=com;
delaylcd(5);
LCDEN=1;
delaylcd(5);
LCDEN=0;
}
/*写数据to lcd */
/**********************************/
void write_data(uchar date)
{
LCDRW=0; //低电平为写
LCDRS=1; //高电平为数据选择
lcddata=date;
delaylcd(5);
LCDEN=1;
delaylcd(5);
LCDEN=0;
}
/*设定显示位置 */
/********************************/
void lcd_pos(uchar pos)
{ //第一行第几列直接写pos为几,第二行pos从0x40开始
write_com(pos | 0x80) ; //数据指针=80+地址变量
}
/*******************************ds18b20*******************************************/
/*us级延时,延时时间约4+2*i*/
void Delayus(uchar i)
{
while(--i);
}
/*复位,每次读写之前都要进行复位*/
/**********************************/
bit ds_reset(void)
{
DQ = 1 ; //DQ复位
Delayus(8) ; //稍做延时
DQ = 0; //拉低约600us
Delayus(150);
Delayus(150);
DQ = 1;//产生上升沿,延时约15~60us
Delayus(30);
if(DQ==0) {presence=0;}
else presence=1;
return(presence); //等待应答信号 0允许,1禁止
}
/*读取数据一位 */
//---------------------------------
bit Read_bit()
{
uint i = 0;
bit b = 0;
DQ = 0; //产生读时隙
i++; //维持低电平至少1us
DQ = 1; //1us以上后拉高
Delayus(2); //延时8us,DO下降沿15内ds18b20输出的数据才有效
b = DQ; //读取数据
Delayus(40); //每个读时隙至少持续60us
return(b);
}
/*读取一个字节 */
//------------------------------------
uchar Read_byte()
{
uchar byte_read = 0;
uchar i, j;
for(i=0; i<8; i++)
{
j = Read_bit();
byte_read = (j<<i) | byte_read; //低位读起
}
return(byte_read);
}
//-----------------------------------------
/*写一个字节 */
void Write_byte(uchar byte_to_write)
{
uchar i = 0;
uchar j = 0;
bit write_bit = 0;
for(j=0; j<8; j++)
{
write_bit = (byte_to_write & 0x01);
if(write_bit == 1) //写1
{
DQ = 0; //产生写时隙
Delayus(3); //延时15us
DQ = 1; //写1
Delayus(40); //延时,写时隙不得低于60us
}
else
{
DQ = 0; //产生写时隙
Delayus(50); //延时,保持低约60us~120us
DQ = 1;
i++;
}
byte_to_write = byte_to_write >> 1;
}
}
//-----------------------------------
/*读取温度,启动温度转换*/
/*启动温度转换*/
void start_convert()
{
ds_reset(); // 发出复位脉冲,每次操作都从复位开始
ddelay(1);
Write_byte(0xcc); //skip room命令,跳过序列号命令字
Write_byte(0x44); //启动温度转换命令
}
/*读取温度值*/
void read_tempreture()
{
ds_reset(); // 发出复位脉冲,每次操作都从复位开始
ddelay(1);
Write_byte(0xcc); //skip room命令
Write_byte(0xbe); //读取暂存器命令
temp_data[0] = Read_byte(); //存储温度低字节值 (整数部分低四位和小数部分) 先从低字节读取
temp_data[1] = Read_byte(); //存储温度高字节值 (其中高五位为符号位)
}
//--------------------------------------
/* CHECKING...显示 */
void lcd_display()
{
uchar m ;
lcd_init() ; //初始化LCD
lcd_pos(0) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis0[m] != '\0')
{ //显示字符
write_data(cdis0[m]) ;
m++ ;
}
}
//--------------------------------------
/* DS18B20 OK 显示菜单 */
void Ook_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD
lcd_pos(0) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis1[m] != '\0')
{ //显示字符
write_data(cdis1[m]) ;
m++ ;
}
}
//-----------------------------------
/*DS18B20 ERR0R 显示 */
void Error_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD
lcd_pos(0) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis3[m] != '\0')
{
write_data(cdis3[m]) ; //显示字符
m++ ;
}
}
//------------------------------------
/*Temp: ℃显示 */
/*Volume of water: ml显示 */
void temp_c()
{
uchar m;
lcd_init() ;
lcd_pos(0);
m=0;
while(cdis5[m]!='\0')
{
write_data(cdis5[m]);
m++;
}
lcd_pos(13);
write_data(0xDF); //°
write_data(0x43);
lcd_pos(0x40);
m=0;
while(cdis6[m]!='\0')
{
write_data(cdis6[m]);
m++;
}
lcd_pos(0x40+14);
write_data(0x6D); //M
write_data(0x6C);
}
//------------------------------------
/*温度显示 */
void temperature_display()
{
uchar m;
flag=0;
while(1)
{
ddelay(2);
EA=0; //DS18B20读写数据按照严格的时序,最好不要被打断,故把所有中断关闭
start_convert(); //启动温度转换
ddelay(250);
read_tempreture(); //读取温度
EA=1;
cc=temp_data[1]*256.0+temp_data[0];
if(temp_data[1]>0xF8)
{flag=1;
cc=~cc+1;
}
else flag=0;
cc1=cc*0.0625;
cc2=cc1*100;
cdis2[1]=cc2/1000+0x30;
if(cdis2[1]==0x30)
{cdis2[1]=0x30;}
cdis2[2]=cc2/100%10+0x30;
cdis2[4]=cc2%100/10+0x30;
cdis2[5]=cc2%10+0x30;
if(flag==1)
cdis2[0]='-';
else
cdis2[0]='+';
lcd_pos(6) ; //设置显示位置为第一行的第6个字符
m=0;
while(cdis2[m]!='\0')
{ //显示字符
write_data(cdis2[m]) ;
m++;
}
}
}
//****************************************************
//HX711延时函数
//****************************************************
void Delay__hx711_us(void)
{
_nop_(); //空操作
_nop_();
}
//****************************************************
//获取水杯重量
//****************************************************
void Get_shuibei()
{
Weight_shuibei = HX711_Read();
}
//HX711 ok 显示
void ok_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD
lcd_pos(0x40) ;
m = 0 ;
while(cdis9[m] != '\0')
{ //显示字符
write_data(cdis9[m]) ;
m++ ;
}
}
/*HX711 overweight 显示 */
void ov_Menu ()
{
uchar m ;
lcd_init() ; //初始化LCD
lcd_pos(0x40) ; //设置显示位置为第一行的第1个字符
m = 0 ;
while(cdis8[m] != '\0')
{ //显示字符
write_data(cdis8[m]) ;
m++ ;
}
lcd_pos(0);
m=0;
while(cdis5[m]!='\0')
{
write_data(cdis5[m]);
m++;
}
lcd_pos(13);
write_data(0xDF); //°
write_data(0x43);
}
//****************************************************
//读取HX711
//****************************************************
unsigned long HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
HX711_DOUT=1;
Delay__hx711_us();
HX711_SCK=0;
count=0;
EA = 1;
while(HX711_DOUT);
EA = 0;
for(i=0;i<24;i++)
{
HX711_SCK=1;
count=count<<1;
HX711_SCK=0;
if(HX711_DOUT)
count++;
}
HX711_SCK=1;
count=count^0x800000;//第25个脉冲下降沿来时,转换数据
Delay__hx711_us();
HX711_SCK=0;
return(count);
}
//****************************************************
//称重
//****************************************************
void Get_Weight()
{
Weight_shui = HX711_Read();
Weight_shui = Weight_shui - Weight_shuibei; //获取净重
if(Weight_shui > 1)
{
Weight_shui = (unsigned int)((float)Weight_shui/GapValue); //计算水的实际重量
if(Weight_shui > 1000) //超重报警
{
Flag_ERROR = 1;
}
else
{
Flag_ERROR = 0;
}
}
else
{
Weight_shui = 0;
}
}
//压力显示
void Volume_display()
{
uchar m;
Get_shuibei(); //称水杯重量
while(1)
{
EA = 0;
Get_Weight(); //称重
EA = 1;
//显示当前重量
if( Flag_ERROR ==0) //超重或者负重情况下输出error
{
cdis7[0]=Weight_shui/1000 + 0X30;
cdis7[1]=Weight_shui%1000/100 + 0X30;
cdis7[2]=Weight_shui%100/10 + 0X30;
cdis7[3]=Weight_shui%10 + 0X30;
}
else //以下是重量显示各个位对应值进行换算
{
ov_Menu ();
ddelay(150);
if( Flag_ERROR ==0)
{
cdis7[0]=Weight_shui/1000 + 0X30;
cdis7[1]=Weight_shui%1000/100 + 0X30;
cdis7[2]=Weight_shui%100/10 + 0X30;
cdis7[3]=Weight_shui%10 + 0X30;
}
}
lcd_pos(0x40+9) ; //设置显示位置为第一行的第6个字符
m=0;
while(cdis7[m]!='\0')
{ //显示字符
write_data(cdis7[m]) ;
m++;
}
}
}
//****************************************************
//主函数
//****************************************************
void main()
{
lcd_display();
ddelay(1000); //延时,等待传感器稳定
ok_Menu (); //hx711 ok
ds_reset(); //ds18b20 初始化
ddelay(1000);
if(presence==0)
{
Ook_Menu (); //ds18b20 ok
ddelay(1000);
temp_c();
Volume_display(); //体积数据
ddelay(1000);
temperature_display(); //温度数据
}
else
{
Error_Menu ();
}
}
|