本帖最后由 jing105768 于 2016-1-22 10:15 编辑
我想将DS18B20读出来的数据一方面显示在数码管上,同时通过串口发送给电脑,下面的程序只能保证数码管上有数据,但是串口调试助手上没有数据,求指导,哪里有错误,万分感激。
#include<reg52.h>
#include"delay.h"
sbit DQ=P3^7;
uchar data temp_data[2]={0x00,0x00};
uchar data display[5]={0x00,0x00,0x00,0x00,0x00};
unsigned char code ditab[16] ={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09} ;
//共阴数码管
uchar code table[11] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};// 0,1,2,3,4,5 ,6,7,8,9,百位或当最高位十位为0时不显示
uchar code table1[10]= {0xcf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};// 0.,1.,2.,3.,4.,5.,6.,7.,8.,9.各位带有小数点的显示
uchar flag,a;
uint value;
//初始化函数
Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18b20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18b20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18b20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18b20(20);
}
ReadOneChar(void)
{
unsigned char i = 0 ;
unsigned char dat = 0 ;
for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ; // 给脉冲信号
dat >>= 1 ;
DQ = 1 ; // 给脉冲信号
if(DQ)
dat |= 0x80 ;
delay_18b20(4) ;
}
return (dat) ;
}
WriteOneChar(unsigned char dat)
{
unsigned char i = 0 ;
for (i = 8 ; i > 0 ; i--)
{
DQ = 0 ;
DQ = dat&0x01 ;
delay_18b20(5) ;
DQ = 1 ;
dat>>=1 ;
}
}
Read_Temperature(void)
{
// uint value; //存放温度数值
float t;
Init_DS18B20();
WriteOneChar(0xCC) ; // 跳过读序号列号的操作
WriteOneChar(0x44) ; // 启动温度转换
Init_DS18B20() ;
WriteOneChar(0xCC) ; //跳过读序号列号的操作
WriteOneChar(0xBE) ; //读取温度寄存器
temp_data[0] = ReadOneChar() ; //温度低8位
temp_data[1] = ReadOneChar() ; //温度高8位
//将高低两个字节合成一个整形变量
value= temp_data[1];
value<<=8;
value|=temp_data[0];
//DS18B20的精确度为0.0625度,即读回数据的最低位代表0.0625度
t=value*0.0625;
//将它放大10倍,使显示时可显示小数点后一位,并对小数点后第二位进行四舍五入,如t=11.0625,进行计数后,得到value=111,即11.1度
value=t*10+0.5;
}
Disp_Temperature()
{
display[4]=temp_data[0]&0x0f ;
display[0]=ditab[display[4]] ; //查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;
display[3]=display[4]/100 ;
display[1]=display[4]%100 ;
display[2]=display[1]/10;
display[1]=display[1]%10;
if(display[3]==0) //高位为0,不显示
{
display[3]=10 ;
if(display[2]==0) //次高位为0,不显示
display[2]=10 ;
}
}
void init()
{
TMOD=0x20;//设置定时器1为工作方式2
TH1=0xfd; //波特率为9600,标准波特率
TL1=0xfd;
TR1=1; //启动定时器1
REN=1;//接受使能
SM0=0;
SM1=1; //设置串口为方式1
EA=1; //打开总中断
ES=1; //打开串口中断开关
}
void serial() interrupt 4
{
a=SBUF;
RI=0;
flag=1;
}
void main()
{
init();
while(1)
{
Read_Temperature();
Disp_Temperature();
P2=0xf7; //P2口低四位位选
P0=table[display[3]]; //P0口数码管段选
delay_18b20(50);
P2=0xfb;
P0=table[display[2]];
delay_18b20(50);
P2=0xfd;
P0=table1[display[1]];
delay_18b20(50);
P2=0xfe;
P0=table[display[0]];
if(flag==1)
{
ES=0;
flag=0;
SBUF=value;
while(!TI);
TI=0;
ES=1;
}
}
} |