求大神修改,急急急急急急!

飞凫 2013-03-17 06:41:16
#include <reg51.h>
#include<intrins.h> //头文件
#define uint unsigned int //宏定义
#define uchar unsigned char
/*******定义端口******************/
sbit DQ = P3^7; //温度传送单总线
sbit led=P0^7; //小数点显示的控制数据线
sbit wx1=P2^0;
sbit wx2=P2^1;
sbit wx3=P2^2;
sbit wx4=P2^3;
/************共阳LED段码表*****************/
uchar code tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6};
/****************定义全局变量*******************/
float temperature;
uchar tempL=0; //临时变量低位
uchar tempH=0; //临时变量高位

/************DS18B20子程序************/
//DS18B20延迟子函数
void delay1us(uint k)
{
while(k--)
{;}
}
//数码管扫描延时函数
void delay1ms(uint m)
{
uint j;
while(m--)
{
for(j=125;j>0;j--);
{;}
}
}

//DS18B20初始化函数
void Init_DS18B20(void)
{
uchar j=0;
DQ = 1; //DQ置1
delay1us(10); //稍作延时
DQ = 0; //单片机将DQ拉低
delay1us(90); //精确延时大于480μs
DQ = 1; //拉高总线
delay1us(20);
}
//读一位数据
bit Readonebit()
{

bit bt;
DQ = 0;
delay1us(2);
DQ = 1;
delay1us(20);
bt = DQ;
delay1us(20);
return(bt);
}
//DS18B20读一个字节
uchar Read_DS18B20(void)
{ uchar i=0;
uint time;
uchar dat; //储存读出的一个字节数据
for (i=0;i<8;i++)
{ DQ =1; // 先将数据线拉高
_nop_(); //等待一个机器周期
DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
_nop_(); //等待一个机器周期
DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备
for(time=0;time<2;time++) ; //延时约6us,使主机在15us内采样
dat>>=1;
if(DQ==1)
dat|=0x80; //如果读到的数据是1,则将1存入dat
else
dat|=0x00;//如果读到的数据是0,则将0存入dat
for(time=0;time<8;time++); //延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat); //返回读出的十六进制数据
}

/*uchar Read_DS18B20(void)
{
uchar i=0,j=0; //定义无符号字符型变量
uchar bt = 0;
for (i=8;i>0;i--) //DS18B20读取一个字节
{
DQ = 1; //将单总线DQ拉高
delay1us(2);
DQ = 0; // 给脉冲信号
delay1us(6);
DQ = 1;
delay1us(4);
j = Readonebit();
bt = (j<<7)|(bt>>1); //循环右移1位
delay1us(30);
return(bt); //返回读取的数据
}
}*/
//DS18B20写一个字节
Write_DS18B20(uchar dat)
{ uchar i=0;
uint time;
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++)
; //稍作延时,给硬件一点反应时间
}

/*void Write_DS18B20(uchar bt)
{
uchar i=0;
bit testb;
for (i=8; i>0; i--)
{
DQ = 0; //拉低单总线DQ
DQ = bt&0x01; //将要写入的数据的1位传送到单总线上
delay1us(15); //延时一段时间
bt>>=1; //右移1位,传下1位数据

if(testb!=0)
{
DQ=0;
delay1us(4);
delay1us(4);
DQ=1;
delay1us(50);
}
else
{
DQ=0;
delay1us(50);
DQ=1;
delay1us(4);
delay1us(4);
}
}
DQ = 1; //释放单总线

delay1us(4);
}*/
//读取DS18B20当前温度
float ReadTemp(void)
{

Init_DS18B20(); //DS18B20芯片初始化
Write_DS18B20(0xCC); // 跳过读序列号的操作
Write_DS18B20(0x44); // 启动温度转换
delay1us(125); //延时等待温度转化完毕
Init_DS18B20(); //重新对DS18B20芯片进行初始化
Write_DS18B20(0xCC); //跳过读序列号的操作
Write_DS18B20(0xBE); //读取温度寄存器中的数据,前两个数据就是所要的温度
delay1us(100); //延时等待
tempL=Read_DS18B20(); //读取温度值低位
tempH=Read_DS18B20(); //读取温度值高位
temperature=((tempH*256)+tempL)*0.0625; //温度转换
delay1us(200);
return(temperature);
}


/************显示子程序************/

void display(int k)
{
wx1=1;
P0=tab[k/100];
delay1ms(1);
P2=0x00;

wx2=1;
P0=tab[k%100/10];
led = 0;
delay1ms(1);
P2=0x00;

wx3=1;
P0=tab[k%10];
delay1ms(1);
P2=0x00;

wx4=1;
P0=tab[12];
delay1ms(1);
P2=0x00;
}

/************主函数************/
void main()
{ float i;
// Init_DS18B20( ); //DS18B20初始化

while(1)
{
i=ReadTemp();
display(i);
}
}
...全文
139 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
chendu1986 2013-03-20
  • 打赏
  • 举报
回复
有可能是时序不对,查查DS18B20读写函数的延时看。
飞凫 2013-03-19
  • 打赏
  • 举报
回复
引用 3 楼 vc8fans 的回复:
这个网上太多例程了,直接下个试下就OK
网上下的仿真不能正常运行,好像是没有从DS18B20中读取到数据,现在就是怀疑时序不太对。
飞凫 2013-03-19
  • 打赏
  • 举报
回复
引用 4 楼 jingjingdeyu 的回复:
我有这个程序,需要吗?我可以发给你
请把你的程序发给我一下吧kyvenbng@sina.cn
飞凫 2013-03-19
  • 打赏
  • 举报
回复
#4请把你的程序发给我一下吧kyvenbng@sina.cn
vc8fans 2013-03-18
  • 打赏
  • 举报
回复
这个网上太多例程了,直接下个试下就OK
去远方成长 2013-03-18
  • 打赏
  • 举报
回复
我感觉上面的回答都不对啊。二进制码和十六进制码在这个应该是一样的。我想和你说的是,最后生成的二进制码并不是程序简单的准换成0和1码。过程是源码-->汇编——>二进制,汇编到二进制的转换是需要查询特定体系的码表的。如果是单片机的话,有软件能把二进制返成汇编,但是目前没有工具能汇编返成C,这个东西,我与原来搞过。。。呵呵,上述是个人愚见
jingjingdeyu 2013-03-18
  • 打赏
  • 举报
回复
我有这个程序,需要吗?我可以发给你
飞凫 2013-03-17
  • 打赏
  • 举报
回复
就是用51单片机控制DS18B20温度传感器做一个数字温度计,用4位数码管显示结果,我现在的程序好像是没有从ds18b20中读取到数据。
bsnow 2013-03-17
  • 打赏
  • 举报
回复
能说下问题,或者功能不? 慢慢看程序累啊

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧