DS18B20+串口通信???(200分)

  • 主题发起人 主题发起人 qiyafei
  • 开始时间 开始时间
Q

qiyafei

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个数字温度计,想通过串口把数据发送到电脑,可接受到的确实空值,数码管也显示的是00,我是一个初学者,有很多东西还不知道,不知道是哪里写的不对,还请各位富翁多多指点啊,我的分也不是很多,都贡献出来吧~~
程序如下:(我的实验板用的是KT800)如需要图,我可以发过去 我的邮箱qiyafei715@163.com

#include <reg51.h>
#include <intrins.h>
#include <math.h>
sbit DQ = P3^3;
sbit wela = P2^7;
//数码管位选
sbit dula = P2^6;
//0-f数码管的段选码,共阳极(不带小数点)
unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
//0-9数码管的段选码,共阳极(带小数点)
unsigned char code tableWidthDot[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x22, 0x02,0x78, 0x00, 0x10};
void ComInit();
//串口初始化
void Reset_18B20(); //18B20复位函数
void sendCmd(unsigned char cmd);
//向18B20发送命令
unsigned char ReadData();
int GetTmpValue();
void sendData(unsigned char Data);
void delay(unsigned char ms);
void display(int v);
void main()
{
unsigned char i;
int tempValue;
ComInit();
while(1)
{
Reset_18B20();
sendCmd(0xcc);
//跳过ROM匹配
sendCmd(0x44);
//发出温度转换命令
tempValue=GetTmpValue();
//sendData(tempValue);
for(i = 0;
i < 40;
i++)
{
display(tempValue);
}

}
}
void Reset_18B20()
{
unsigned int i;
DQ=0; //数据线下拉
i=80;
while(i>0) i--;//延时约640μs(要求500μs)
DQ=1;
//数据线拉高
i=4;
while(i>0) i--;//进入等待状态
while(DQ);//检测到应答脉冲
i=4;
while(i>0) i--;//等待约32μs (要求16μs-60μs)
while(~DQ); //发出存在低脉冲
delay(1); //延时1ms(要求60μs-240μs)
}
void sendCmd(unsigned char cmd)
{
unsigned int i;
unsigned char j;
bit b;
Reset_18B20();
for(j=0;j<8;j++)
{
b=cmd &amp;
0x01;
cmd >>= 1;
if(b) //写1过程 : 将DQ拉低15μs后,在15μs-60μs内将DQ拉高
{
DQ = 0; //拉低约16μs(要求15μs-60μs)
i++;
i++;
DQ = 1; //释放
i=10;
while(i>0) i--;//延时约80,要求写时隙不低于60μs
}
else
//写0过程 : 将DQ拉低约60μs-120μs
{
DQ = 0;

i=10;
while(i>0) i--;
DQ = 1;
i++;
i++;
}
}
}
int GetTmpValue()
{
unsigned int tempValue;
int Value;
unsigned char low,high;
sendCmd(0xcc);
//跳过序列号匹配
sendCmd(0xBE);
//发出读取暂存器内数据命令
low = ReadData();
sendData(low);
//串口发送
high = ReadData();
sendData(high);
tempValue = high;
tempValue <<= 8;
tempValue |= low;
Value = tempValue;
return Value;
}
void sendData(unsigned char Data)
{

TR1 = 1;
//启动定时器1
SBUF=Data;
while(!TI);
TI=0;
}
unsigned char ReadData()
{
unsigned char i;
unsigned char j, dat;
dat = 0;
for(i=0;i<8;i++)
{
unsigned int k;
bit b;
DQ = 0;
k++;
//延时约8μs(要求至少保持1μs )
DQ = 1;
k++;
k++;
//延时约16μs(要求至少保持15μs )
b = DQ;
k=10;
while(k>0) k--;
//延时约80μs(要求读时隙不低于60μs )
j = b;
dat = (j << 7) | (dat >> 1);
}
return dat;
}
void ComInit()
{
TMOD = 0x20;
//设置定时器1工作于8位自动重载模式,用于产生波特率
TH1 = 0xFD;
//设置波特率为9600b/s
TL1 = 0xFD;
SCON = 0x50;
//设定串口工作方式为方式1,10位异步收发(SCON为串口控制寄存器)
PCON &amp;= 0xef;
//波特率不倍增
}
void delay(unsigned char ms)
{
unsigned char i;
while(ms--)
for(i=0;i<120;i++); //对于晶振频率为11.0592MHz延时1ms
}

unsigned char const timeCount = 3;
//动态扫描的时间间隔
//显示当前温度值, 精确到小数点后一位
//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码
void display(int v)
{
int value;
float t;
unsigned char count;
unsigned char datas[] = {0, 0, 0, 0, 0};
unsigned int tmp;

value = v;
t = v * 0.0625;
v = t * 100 + (value>0 ? 0.5 : -0.5);
tmp = abs(v);
datas[0] = tmp / 10000;
datas[1] = tmp % 10000 / 1000;
datas[2] = tmp % 1000 / 100;
datas[3] = tmp % 100 / 10;
datas[4] = tmp % 10;
if(v < 0)
{
//关位选, 去除对上一位的影响
P0 = 0xff;
wela = 1;
//打开锁存, 给它一个下降沿量
wela = 0;
//段选
P0 = 0x40;
//显示"-"号
dula = 1;
//打开锁存, 给它一个下降沿量
dula = 0;
//位选
P0 = 0xfe;
wela = 1;
//打开锁存, 给它一个下降沿量
wela = 0;
delay(timeCount);
}
for(count = 0;
count != 5;
count++)
{
//关位选, 去除对上一位的影响
P0 = 0xff;
wela = 1;
//打开锁存, 给它一个下降沿量
wela = 0;
//段选
if(count != 2)
{ P0 = table[datas[count]];
} //显示数字
else
{P0 = tableWidthDot[datas[count]];
}//显示带小数点数字
dula = 1;
//打开锁存, 给它一个下降沿量
dula = 0;
//位选
P0 = _crol_(0xfd, count);
//选择第(count + 1) 个数码管
wela = 1;
//打开锁存, 给它一个下降沿量
wela = 0;
delay(timeCount);
}
}
 
空值?
你不是用的 串口模块
而是 自己 控制 数据线?
 
不太明白你说的
 
怎么没人帮帮我啊???
 
1. 先确定你做的数字温度计输出正常
2. 确定温度计输出正确的传给了电脑
3. 电脑收到的数据经过了正确的处理
找个串口调试助手看看收到的是什么数
---------------------------------------------------------
你的程序是和收发数据有关的全部程序吗?
我怎么没找到串口初始化的代码?
不知道你怎么实现的
 
void ComInit()
{
TMOD = 0x20;
//设置定时器1工作于8位自动重载模式,用于产生波特率
TH1 = 0xFD;
//设置波特率为9600b/s
TL1 = 0xFD;
SCON = 0x50;
//设定串口工作方式为方式1,10位异步收发(SCON为串口控制寄存器)
PCON &amp;= 0xef;
//波特率不倍增
}
这是串口初始化函数
用串口调试助手接收数据 十六进制就是FF
字符格式就是空格
而且数码管也显示两个00
我不知道是不是i/o口的问题,
还望多指教啊
 
怎么没有大大富翁来指导我一下啊
 
你是齐亚飞?
 
是啊,你是谁呵?
 
问题已经基本解决
多谢各位了
 
后退
顶部