仿真线路确定没问题,是我的代码问题,目前的问题是,其他显示都可以实现,比如显示数组table[],table1[],table2[],开始仿真都显示正常,就是不显示温度,谢谢各位大佬指教了
/************************************************************/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNop(); {_nop_();_nop_();_nop_();_nop_();};
uchar code table[]=" ERROR!!! ";
uchar code table1[]="xianzaiwendu ";
uchar code table2[]="Temp= . Cent";
uchar code table3[10]="0123456789";
sbit lcd_rs=P1^0;
//sbit lcd_rw=P1^1;
sbit lcd_en=P2^5;
sbit DQ=P2^3;
uchar num,time;
void delay(uint t)
{
unsigned char n;
while(t--)
{
for(n = 0; n<250; n++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void write_com(uchar com) //写命令
{
////lcd_rw=0;
//delay(5);
lcd_rs=0;
lcd_en=0;
_nop_();
_nop_();
P0=com;
delayNop();
lcd_en=1;
delay(1);
lcd_en=0;
}
void write_date(uchar date) //写数据
{
//lcd_rw=0;
// delay(5);
lcd_rs=1;
lcd_en=0;
_nop_();
_nop_();
P0=date;
delayNop();
lcd_en=1;
delay(1);
lcd_en=0;
}
void init() //初始化函数
{
// dula=0;
// wela=0;
lcd_en=0; //可以试试不加这一句看结果怎样
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
uchar init_DS18bB20()
{
bit flag;
DQ=1; //人为拉高
for(time=0;time<2;time++); //稍微延时6US;
DQ=0; //认为拉低
for(time=0;time<200;time++); //延时600US给单片机检测
DQ=1; //被上拉电阻拉高 (仿真里面没有上拉,有没有都需要人为拉高)
for(time=0;time<20;time++); // 延时60US检测
flag=DQ; //这时又被DS18B20拉低,
for(time=0;time<200;time++); //延时600US检测时间
return flag; //返回0表示存在
}
void Write_Byte(uchar dat) //写一个字节,单片机向DS18B20写命令,确定DS18B20的工作方法之类的
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ=0; //将数据线从高拉低时即启动写时序
DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,
//并将其送到数据线上等待DS18B20采样
for(time=0;time<10;time++)
;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1; //释放数据线
for(time=0;time<1;time++)
;//延时3us,两个写时序间至少需要1us的恢复期
dat>>=1; //将dat中的各二进制位数据右移1位
}
for(time=0;time<4;time++)
; //稍作延时,给硬件一点反应时间
}
uchar Read_Byte()
{
uchar i=0;
uchar dat;//用来储存读出的一个字节,默认为0
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
DQ=0; //读命令一定得是低电平
dat>>=1; //读取数据是从高位开始读,dat默认是0,也就是0000 0000,
// 这是下标是指向最高位的,所以得先右移一位让出一个位置
_nop_(); //需要>1US;
DQ=1; //又被上拉电阻拉高
for(time=0;time<2;time++);
if(DQ==1) //由DQ发送的信号来决定,发送的是高电平还是低电平
dat|=0x80; //高电平就或0x80,1000 0000
else
dat|=0x00; //低电平就或,0x00
for(time=0;time<5;time++);//延时10US左右,因为需要在15US内完成读取
}
return dat;
}
void Readyread()//做好读温度准备。。。。可以加在主函数里面,但是分出来比较清晰明了
{
init_DS18bB20();
Write_Byte(0xcc); //跳过读序号
Write_Byte(0x44); //启动温度转换
for(time=0;time<100;time++);
init_DS18bB20(); //再初始化一下
Write_Byte(0xcc); //跳过读序号
Write_Byte(0xbe); //都温度寄存器,前两个分别是温度的,低,高位
}
void display() //显示第一行说明
{
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table[num]);
// delay(1);
}
while(1);
}
void display1() //显示第二行说明
{
write_com(0x80);
for(num=0;num<16;num++)
{
write_date(table1[num]);
// delay(1);
}
}
void display2()
{
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_date(table2[num]);
//delay(1);
}
}
void display_temp(uchar x) //显示温度整数部分
{
uchar bai,shi,ge;
bai=x/100;
shi=(x%100)/10;
ge=x%10;
write_com(0x46);
write_date(table3[bai]);
write_date(table3[shi]);
write_date(table3[ge]);
}
void display1_temp(uchar x) //显示温度小数部分
{
write_com(0x4a);
write_date(table3[x]);
}
void main()
{
uchar TL;//储存暂存器的温度最高位
uchar TH;//储存暂存器的温度最低位
uchar TN; //储存温度整数部分
uchar TD; //储存温度小数部分
init();
if(init_DS18bB20()==1)
display();
display1();
// display2();
while(1)
{
Readyread();
TL=Read_Byte();
TH=Read_Byte();
TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16
//这样得出的是温度的整数部分,小数部分被丢弃了
TD=(TL%16)*10/16; //计算温度的小数部分,将余数乘以10再除以16取整,
//这样得到的是温度小数部分的第一位数字(保留1位小数)
display_temp(TN);
display1_temp(TD);
_nop_(); _nop_();
}
}
|