自己高度的温度显示#include<REGX51.H>
#include<INTRINS.h>
unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选区
unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00,0x40};//段选区共阴极
unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,
25,28,31,34,38,41,44,48,
50,53,56,59,63,66,69,72,
75,78,81,84,88,91,94,97};
unsigned char displaycount;
unsigned char presence;
unsigned char displaybuf[8]={16,16,16,16,16,16,16,16};//16对应的刚好是0x00
unsigned char timecount;
unsigned char readdata[8];
sbit DQ=P0^1;
bit sflag;//显示开关标记
bit resetpulse(void)
{
unsigned char i;
DQ=0;
for(i=255;i>0;i--); //主机通过拉底单总线至少480us产生TX复位脉冲。
//for(i=250;i>0;i--); //应该加上这一条吧?
DQ=1; //然后由主机进入RX接收模式,主机释放总路线时,会产生一由低电平跳变为高电平的升沿。
for(i=60;i>0;i--);// 单总路线检测到该上升沿后延迟15-60us
presence=DQ; //如果=0则初始化成功 =1则初始化失败
for(i=200;i>0;i--); //单总线通过拉低总路线60-240us来产生应答脉冲。
return(presence);//主机接收到从机的应答脉冲后,说明单总路线器件在线,然后主机就可以开始对从机进行ROM命令和功能命令操作。
}
void writecommandtods18b20(unsigned char command)
{
unsigned char i;
unsigned char j;
for(i=0;i<8;i++)
{
if((command&0x01)==0)//写0
{
DQ=0;
for(j=45;j>0;j--);//for(j=35;j>0;j--);
DQ=1;
}
else //写1
{
DQ=0;
for(j=2;j>0;j--);
DQ=1;
for(j=33;j>0;j--);
}
command=_cror_(command,1);//循环右移
}
}
unsigned char readdatafromds18b20(void)
{
unsigned char i;
unsigned char j;
unsigned char temp;
temp=0;
for(i=0;i<8;i++)
{
temp=_cror_(temp,1);
DQ=0;
_nop_(); //在程序中插入NOP指令;
_nop_();
DQ=1;
for(j=10;j>0;j--);
if(DQ==1)
{
temp=temp|0x80;
}
else
{
temp=temp|0x00;
}
for(j=200;j>0;j--);
}
return(temp);
}
void main(void)
{
TMOD=0x01;
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
ET0=1;
EA=1;
while(resetpulse());
writecommandtods18b20(0xcc); //跳过读序号列号的操作
writecommandtods18b20(0x44); //启动温度转换
TR0=1;
while(1)
{
;
}
}
void t0(void)interrupt 1 using 0
{
unsigned char x;
unsigned int result;
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
if(displaycount==2)
{
P0=displaycode[displaybuf[displaycount]]|0x80;//显示小数点
}
else
{
P0=displaycode[displaybuf[displaycount]];
}
P2=displaybit[displaycount];
displaycount++;
if(displaycount==8)
{
displaycount=0;
}
timecount++;
if(timecount==150) //中断150次(600ms)才运行以下的程序
{
timecount=0;
while(resetpulse());
writecommandtods18b20(0xcc);//跳过读序号列号的操作
writecommandtods18b20(0xbe);//读取温度寄存器
readdata[0]=readdatafromds18b20();//温度低8位
readdata[1]=readdatafromds18b20();//温度高8位
for(x=0;x<8;x++)
{
displaybuf[x]=16;
}
sflag=0;
if((readdata[1]&0xf8)!=0x00) //若温度为负的处理
{
sflag=1;
readdata[1]=~readdata[1];
readdata[0]=~readdata[0];
result=readdata[0]+1; //减去一个数等于加上这个数的补码(反码加一)
readdata[0]=result;
if(result>255)
{
readdata[1]++; //低位大于255高位加1
}
}
readdata[1]=readdata[1]<<4; //将高低温度合为一个字节,本方法避免了*0。0625,很简单,很准确????
readdata[1]=readdata[1]&0x70;
x=readdata[0];
x=x>>4;
x=x&0x0f;
readdata[1]=readdata[1]|x;
x=2;
result=readdata[1]; //拆分两路温度值送入显示单元
while(result/10)
{
displaybuf[x]=result%10;
result=result/10;
x++;
}
displaybuf[x]=result;
if(sflag==1) //如果是负数在数字的最前面加上-
{
displaybuf[x+1]=17;
}
x=readdata[0]&0x0f;
x=x<<1;
displaybuf[0]=(dotcode[x])%10;
displaybuf[1]=(dotcode[x])/10;
while(resetpulse());
writecommandtods18b20(0xcc);// 跳过读序号列号的操作
writecommandtods18b20(0x44);// 启动温度转换
}
}
怪童:抽中2007年12月01日,每天发主题帖中奖幸运会员。+100电阻