C51单片机,12MHZ晶振
#include<reg52.h>
#include <intrins.h>
sbit DQ=P3^7;
sbit led0=P1^3;
sbit led1=P1^2;
sbit led2=P1^1;
sbit led3=P1^0;
typedef unsigned char uchar;
typedef unsigned int uint;
#define NOP() _nop_()
uchar T_data[2]={0x00,0x00},dis[6]={0};
uchar seg[10]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
uchar seg1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//数码管段码
void delay(uint t)//11*t+17us延时,12MHZ晶振时
{
int s;
for(s=0;s<t;s++);
}
uchar reset(void)//复位
{
uchar presence;
DQ=1;
_nop_();
DQ=0;
delay(50);//570us
DQ=1;
delay(5);//72us
presence=DQ;
delay(40);//450us
DQ=1;
return(presence);
}
uchar read_bit(void)//读位
{
uchar i,b;
DQ=0;
_nop_();
DQ=1;
for(i=0;i<3;i++);//延时11us
b=DQ;
delay(4);//60us
return(b);
}
void write_bit(char bitval)//写位
{
DQ=0;
_nop_();
DQ=bitval&0x01;
delay(4);//60us
DQ=1;
}
uchar read_byte(void)//读字节
{
uchar i;
uchar value=0;
for(i=0;i<8;i++)
{
if(read_bit()) value|=(0x01<<i);
}
return(value);
}
void write_byte(uchar val)//写字节
{
uchar i;
uchar temp;
for(i=0;i<8;i++)
{
temp=((val>>i)&0x01);
write_bit(temp);
}
}
void read_T_data()//读温度
{
while(reset());
write_byte(0xCC);
write_byte(0x44);
while(reset());
write_byte(0xCC);
write_byte(0xBE);
T_data[0]=read_byte;
T_data[1]=read_byte;
}
void work_T_data()//温度处理
{
uchar n=0;
if(T_data[1]>127)
{
T_data[1]=256-T_data[1];
T_data[0]=256-T_data[0];
n=1;
}
dis[5]=((T_data[1]&0x0F)<<4)|((T_data[0]&0xF0)>>4);//整数部分
dis[4]=dis[5]/100;//百位
dis[3]=dis[5]%100;
dis[2]=dis[3]/10;//十位
dis[1]=dis[3]%10;//个位
switch (T_data[0]&0x0f) //小数位
{
case 0x0f:dis[0]=9;break;
case 0x0e:dis[0]=9;break;
case 0x0d:dis[0]=8;break;
case 0x0c:dis[0]=8;break;
case 0x0b:dis[0]=7;break;
case 0x0a:dis[0]=6;break;
case 0x09:dis[0]=6;break;
case 0x08:dis[0]=5;break;
case 0x07:dis[0]=4;break;
case 0x06:dis[0]=4;break;
case 0x05:dis[0]=3;break;
case 0x04:dis[0]=3;break;
case 0x03:dis[0]=2;break;
case 0x02:dis[0]=1;break;
case 0x01:dis[0]=1;break;
case 0x00:dis[0]=0;break;
default:break;
}
}
void display()//温度显示
{
P2=0x39;
led0=0;
delay(40);
led0=1;
P2=seg[dis[0]];
led1=0;
delay(40);
led1=1;
P2=seg1[dis[1]];
led2=0;
delay(40);
led2=1;
P2=seg[dis[2]];
led3=0;
delay(40);
led3=1;
}
void main()
{
uchar i=0;
while(reset());
write_byte(0xCC);
write_byte(0x44);
while(1)
{
if(i==100)
{
i=0;
read_T_data();
work_T_data();
}
i++;
display();
}
}
我想知道自己这个程序问题的所在,希望高手最好能把这个程序硬件试验一下,再次感谢!(调整了好多次,唯一有的变化就是显示数值较先前一个程序发生了变化,但仍然不随温度改变,即仍为定值)
reset()函数最后我已经拉高了电平,而且经过测试,加上之后,还是不成功
追答又发现两处,你改了后再试试.
1:少了存在脉冲判断
void read_T_data()//读温度
{
while(reset());
delay(200); //存在脉冲
write_byte(0xCC);
write_byte(0x44);
while(reset());
delay(1); //存在脉冲
write_byte(0xCC);
write_byte(0xBE);
T_data[0]=read_byte;
T_data[1]=read_byte;
}
2:负温度时的处理
if(T_data[1]>125) //高字节为高5位为1时,温度为负。0000 0111 1111 0000 取 125
{ T_data[1]=255-T_data[1]; //低字节向高字节借了一位,256要减去1
T_data[0]=256-T_data[0];
}
看下这个网页的18B20的说明文档,可能你会有收获:
http://wenku.baidu.com/view/acf0412e453610661ed9f4d6.html 17页
http://wenku.baidu.com/view/d92d3ec75fbfc77da269b1c1.html 18页
还是不行,存在脉冲其实我也已经加在reset函数中了,delay(5)+delay(40)的时间已经大于480us
至于负温度的处理,我没有多加考虑,因为温度是零上,应该不是主要问题的所在
还是说声谢谢!
led是位选,seg是段选,数码管这块是不会错的
硬件调试,而且用一个正确的测温程序试验时可以成功
DS18B20测温C程序:数码管显示不随温度变化,且不正确,求高手解答,万分感 ...
在mian函数while(reset())的下一行加上DQ=1;(拉高电平)。
我现在写了DS18B20的c程序还有用定时器输出的PWM波程序,用数码管显示...
DS18B20这种对时序有严格要求的单总线通讯,在发送和接收数据时被定时器中断扰乱了时序,所以无法通讯。要解决此问题建议你采用带硬件PWM的MCU,或者将18B20通讯代码放在中断服务程序内部,如果采用后一种方式,PWM计时时间请算上18B20通讯的时间。
DS18B20程序,keil c编译报错error C208: 'ReadDs': too many actual p...
Reads函数的实体中是没有参数的,而你在调用时传入了参数,所以编译报错。应该是你的实体有问题吧,一般都有参数的。