 2017-03-15 23:16

# 1602液晶屏一排方格，新手上路求指教

#include
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^0; //ds18b20 与单片机连接口
sbit RS=P1^1;
sbit RW=P1^2;
sbit EN=P1^3;
sbit p37=P3^6; //流量正常运行接口
sbit p36=P3^7; //温度报警接口
sbit p14=P1^4; //功能按键接口
sbit p15=P1^5;
sbit p16=P1^6;
uchar code table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x20}; //0-9

unsigned long int a;
float f,zong;
uint tvalue;
uchar n1,n2,n3,n4,n5,n6,n7,n8,n9;
uchar tflag,d,g,kai,j,j1,j2,b;
/************************延时子程序**************************/
void delay (uint z)
{ int x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--) ;
}
/***************延时 1us 子程序**********************/
void delay_18B20(unsigned int i)//延时 1 微秒
{
while(i--);
}
/***************液晶显示写指令*******************************/
void wr_com(unsigned char com) //写指令
{
delay(1); //延时 1ms
RS=0; //写命令设置
RW=0; //并行数据的读写
EN=0; //使能为 0
P2=com; //输入命令
delay(1); //延时 1ms
EN=1; //使能为 1
delay(1); //延时 1ms
EN=0; //使能为 0
}
/************液晶显示写数据**************************/
void wr_dat(unsigned char dat)//写数据
{
delay(1); //延时 1ms
RS=1; //写数据设置
RW=0; //并行数据的读写
EN=0; //使能为 0
P2=dat; //输入数据
delay(1); //延时 1ms
EN=1; //使能为 1
delay(1); //延时 1ms
EN=0; //使能为 0
}
/***********水流量计算程序与数据转换程序******************/
void loop ()
{
uint zong1;
if(g==0) //判断时间是否到
{
zong=(b/100.0)+zong; //得出总流量的后三位
}
g=1; //将标志为为 1
if(zong>=1000) //判断总流量后三位是否大于 1000
{
a++; //总流量前六位加 1
zong=0; //后三位清零
}
if(a>=1000000) //总流量前六位大于 1 百万
{
a=0; //总流量前六位清零
}
zong1=(int)zong ; //总流量后三位转换为整形
n9=a/100000; //总流量 9 位全部分配
n8=a%100000/10000;
n7=a%10000/1000;
n6=a%1000/100;
n5=a%100/10;
n4=a%10;
n3=zong1%1000/100;
n2=zong1%100/10;
n1=zong1%10;
}
/*********************水费计算与数据转换************************/
void shuifei()
{
uchar h1,h2,h3,h4;
h4=(j*a)/1000000; //水费显示
h3=(j*a)%1000000/100000;
h2=(j*a)%100000/10000;
h1=(j*a)%10000/1000;
wr_com(0x80+10); //水费显示
wr_dat(0x5c);
wr_dat(table[h4]);
wr_dat(table[h3]);
wr_dat(table[h2]);
wr_dat(0x2e); //显示小数点
wr_dat(table[h1]);
}
/**********************ds1820 复位子程序*****************/
void ds1820rst()
{
unsigned char x=0;
DQ = 1; //DQ 复位
delay_18B20(4); //延时
DQ = 0; //DQ 拉低
delay_18B20(100); //精确延时大于 480us
DQ = 1; //拉高
delay_18B20(40); //延时
}
/***********ds1820 读数据子程序********************/
uchar ds1820rd() //读数据
{
unsigned char i=0;
unsigned char dat=0;

• 42 - for (i=8;i>0;i--) //读温度 2 进制 8 次 { DQ = 0; //给脉冲信号 dat>>=1; //将温度数据转移到 dat DQ = 1; //给脉冲信号 if(DQ) //数据转换 dat|=0x80; delay_18B20(10); } return(dat); } /**************ds1820 写数据子程序********************/ void ds1820wr(uchar wdata) { unsigned char i=0; for (i=8; i>0; i--) //写数据 2 进制 8 次 { DQ = 0; //给脉冲信号 DQ = wdata&0x01; //数据传送 delay_18B20(10); //延时 DQ = 1; //给脉冲信号 wdata>>=1; //数据移位 } } /*****************ds1820 温度转换程序****************************/ uint read_temp() { uchar a,b; ds1820rst(); //ds1820 复位 ds1820wr(0xcc); //跳过读序列号
• 43 - ds1820wr(0x44); //启动温度转换 ds1820rst(); //ds1820 复位 ds1820wr(0xcc); //跳过读序列号 ds1820wr(0xbe); //读取温度 a=ds1820rd(); //将温度数据给 a b=ds1820rd(); //将温度数据给 b tvalue=b; //将温度数据转移 tvalue<<=8; tvalue=tvalue|a; if(tvalue=4) p37=0; else p37=1; if(tflag==1) { p37=0; //负温度显示负号:- } if(t3==0) { t3=10; //如果百位为 0，不显示 if(t2==0) { t2=10; //如果百位为 0，十位为 0 也不显示 } } wr_dat(table[t3]);//显示百位 wr_com(0x80+3); wr_dat(table[t2]);//显示十位 wr_dat(table[t1]);//显示个位 wr_dat(0x2e); //显示小数点 wr_dat(table[t4]);//显示小数位 } /**********************流量程序*******************************/ void liuliang() { while(d>=2) //时间到？ { d=0; //d 清零 b=TH0*256+TL0; //读取频率 TH0=0x00; //计数器清零 TL0=0x00; g=0; //时间标志位 } loop(); //水流量计算程序与数据转换程序 } /**************第一页显示子程序***************************/ void display1() { wr_com(0x80); //温度显示 wr_dat(0x54); //显示 T wr_dat(0x3a); //显示： read_temp(); //读取温度 ds1820disp( ); //温度显示 wr_dat(0x00); //显示° wr_dat(0x43); //显示 C shuifei(); wr_com(0x80+0x40); //水流量（t）显示 wr_dat(0x46); wr_dat(0x4c); wr_dat(0x4f); wr_dat(0x57); wr_dat(0x3a); wr_dat(0x20); wr_dat(table[n9]); wr_dat(table[n8]); wr_dat(table[n7]); wr_dat(0x2e); //显示小数点 wr_dat(table[n6]); wr_dat(table[n5]); wr_dat(table[n4]); wr_dat(0x20); //显示小数点 wr_dat(0x74); wr_dat(0x20); } /**************第二页显示子程序**********************/ void display2() { wr_com(0x80); //温度显示 wr_dat(0x54); //显示 T wr_dat(0x3a); //显示： read_temp(); //读取温度 ds1820disp( ); //温度显示 wr_dat(0x00); //显示° wr_dat(0x43); //显示 C wr_com(0x80+10); //水价显示 wr_dat(table[j2]); wr_dat(0x2e); wr_dat(table[j1]); wr_dat(0x5c); wr_dat(0x2f); wr_dat(0x74); wr_dat(0x20); wr_com(0x80+0x40+5);//水流量（kg）显示 wr_dat(0x20); wr_dat(0x20); wr_dat(table[n4]); wr_dat(0x2e); //显示小数点 wr_dat(table[n3]); wr_dat(table[n2]); wr_dat(table[n1]); wr_dat(0x20); wr_dat(0x6b); wr_dat(0x67); } /*****************控制流量测量的开关程序***********************/ void kaiguan1() { if(p14==0) //按键按下？ {delay(2); if(p14==0) { delay(2); p36=~p36; //P3.6 取反 TR0=~TR0; //TR0 取反 while(p14==0);//按键松开 } } } /**************界面切换开关程序********************/ void kaiguan2() { if(p15==0) //按键按下？ { delay(2); if(p15==0) { delay(2); kai=~kai; //P3.6 取反 while(p15==0);//按键松开？ } } } /*****************水的单价控制开关程序************************/ void kaiguan3() { if(p16==0) //按键按下？ {delay(2); if(p16==0) { delay(2); j++; //水价加一 if(j>40) //水价大于 40 j=0; //水价清零 j2=j/10; //水价分位 j1=j%10; while(p16==0);//按键松开？ } } } /**********************程序初始化******************************/ void lcd_init () { TMOD=0x15; //设定定时器 0 为计数功能，定时器为 1 为定时功能 TH1=(65536-50000)/256;//定时器 1 赋出值 50ms TL1=(65536-50000)%256; TH0=0x00; //定时器 0 赋初值 0 次 TL0=0x00; EN=0; //液晶使能端为 0 wr_com(0x38); //液晶初始设置 wr_com(0x0c); wr_com(0x06); wr_com(0x01); wr_com(0x40); wr_dat(0x06); //写 CGRAM 写字模 wr_dat(0x09); wr_dat(0x09); wr_dat(0x06); wr_dat(0x00); wr_dat(0x00); wr_dat(0x00); wr_dat(0x00); zong=0; //总流量（带小数点） EA=1; //开启总中断 ET1=1; //开启定时器 1 中断 TR1=1; //开启定时器 1 TR0=0; //开启计数器 0 p16=1; //p16 为 1 p15=1 ; //p15 为 1 p14=1; //p14 为 1 zong=995; //总流量的后三位赋初值
• 50 - a=199999; //总流量的前六位赋初值 j=20; //水价赋初值 j2=2; //水价个位赋初值 j1=0; //水价小数位赋初值 kai=0; } /********************主程序****************************/ void main() { lcd_init(); //初始化显示 while(1) { kaiguan1(); //控制水流量的测量 kaiguan2(); //控制显示界面 liuliang(); //流量测量 if(kai==0) //判断界面开关是否按下 display1(); //显示第一页界面 else { kaiguan3(); //判断水价开关是否按下 display2(); //显示第二页界面 } } } /******************定时器 1 中断**********************/ void time1() interrupt 3 { TH1=(65536-50000)/256;//定时器 1 初值定时 50ms TL1=(65536-50000)%256; d++; //20ms 后 d 加 1 }
• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享
• 邀请回答

#### 2条回答

• 这么一大堆没人看的。上学期我也碰到过类似情况，多半是硬件线路的问题，多检查检查。另外有可能是写命令或者数据后延时不够

点赞 评论 复制链接分享