本帖最后由 xichandoujigu 于 2018-3-5 15:12 编辑
改了下,现在结果是不断跳动,85、42、21,主要就这三个数之间跳动,显示最多是还是85
=====================================================================
#include <REG51.H>
typedef unsigned char uchar;
typedef unsigned int uint;
int shi_gao,shi_di,fen_gao,fen_di; // 时个位,十位、分个位、十位
unsigned char Tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳数码管显示用
int wendu_shi,wendu_ge,wendu_cnt,cnt_ge,cnt_shi,cnt_qian;//温度个位、十位
//数码管位选
sbit P11=P1^0;
sbit P12=P1^1;
sbit P13=P1^2;
sbit P14=P1^3;
sbit DQ=P3^7; /*与DS18B20温度传感器交换数据的端口*/
void init_ds18b20(); /*DS18B20的初始化程序*/
uchar readbyte(); /*读数据*/
uchar readtemp(); /*读温度*/
void delay_us(int a)
{
int i;
for(i=a;i>0;i--);
}
//10ms延时子程序(12MHZ)数码管显示用
void delay_ms(void)
{
int i,j,k;
for(i=5;i>0;i--)
for(j=4;j>0;j--)
for(k=248;k>0;k--);
}
//数码管显示函数
void display(int shi_gao,shi_di,fen_gao,fen_di)
{
P2 = 0X00;
P14=1;
P2=Tab[shi_gao];
delay_ms() ;
P14=0;
P2 = 0X00;
P13=1;
P2=Tab[shi_di];
delay_ms() ;
P13=0;
P2 = 0X00;
P12=1;
P2=Tab[fen_gao];
delay_ms() ;
P12=0;
P2 = 0X00;
P11=1;
P2=Tab[fen_di];
delay_ms() ;
P11=0;
}
void init_ds18b20()
{
uchar x=0;
DQ=1; /*首先先拉高电平,为复位做准备*/
delay_us(10) ; /*延迟一下*/
DQ=0; /*将电平拉低,延迟至少480us*/
delay_us(500) ; /*此处延迟480us*/
DQ=1; /*复位信号给出后,将电平拉高,等待获取存在脉冲*/
delay_us(40) ; /*延迟15~60us,此处延迟60us,给存在脉冲时间*/
x=DQ; /*读取存在脉冲*/
delay_us(500) ; /*读取存在脉冲,存在脉冲至少为60us到240us的低电平信号,这里给出480us*/
DQ=1; /*读取后,将信号复位,DS18B20初始化,数据交换协议生成*/
}
uchar readbyte() /*读数据操作*/
{
uchar i=0;
uchar date=0;
for(i=8;i>0;i--) /*读取数据时,是一位一位的读取,因为至少有8位,所以需要循环8次*/
{
DQ=0; /*数据线拉成低电平,表示读数据的开始*/
delay_us(10); //1 /*读数据时,需要低电平保持至少1us*/
DQ=1; /*释放数据总线*/
date>>=1; /*一位一位的保存读取到的数据,所以需要移位处理*/
if(DQ) /*读取数据的高电平*/
date|=0x80; /*与操作一下,得到我们需要的数据,读取数据需要在15us内读取,这样才能保证读取的数据是正确的*/
delay_us(40);
}
return(date); /*返回最终的结果*/
}
void writebyte(uchar dat)
{
int i=0;
for(i=8;i>0;i--) /*一位一位的发送数据,和串口通信类似,读取数据也是一位一位的读取*/
{
DQ=1;
delay_us(10);
DQ=0;
DQ=dat&0x01; /*移位指令用来发送数据,最低位为要发送的数据*/
delay_us(40); /*延迟,等待数据发送完毕,发送数据时间应该在45us内完成,我们延迟了50us*/
DQ=1;
dat>>=1;
delay_us(10);
}
}
uchar readtemp()
{
uchar templ,temph,tt;
uint t;
init_ds18b20(); /*读取数据时,先初始化设备*/
writebyte(0xCC); /*因为我们是一个单片机和一个DS18B20连接,故在对ROM指令操作时,选择0xCC跳过ROM指令,不对ROM编码作出反应*/
writebyte(0x44); /*RAM操作中的温度转换指令,将转换的温度存入RAM的1,2地址*/
init_ds18b20(); /*初始化*/
writebyte(0xCC); /*同上*/
writebyte(0xBE); /*从RAM中读取数据,从0地址读到9地址*/
templ=readbyte(); /*从DS18B20中读取温度数据中低八位*/
temph=readbyte(); /*从DS18B20中读取温度数据中的高八位,温度数据由16位数据组成*/
t=temph;
t<<=8;
t=t|templ;
tt=t*0.0625; /*真实温度的转换*/
return(tt); /*返回真实可用的温度给main函数,用于显示*/
}
/*********主程序********************/
void main()
{
uchar i;
uchar temp;
wendu_cnt=0;
temp=readtemp(); /*读取温度*/
delay_us(500);
while(1)
{
temp=readtemp(); /*再次读取温度*/
for(i=0;i<10;i++)
{
wendu_shi=temp/10; /*获取温度的十位信息*/
wendu_ge=temp%10;
display(wendu_shi,wendu_ge,0,0);
}
}
}
|