各位高手,这是我的温度传感器的复位初始化函数
void start(void)
{
unsigned char i;
ds = 0; //ds为数据I/O口
for(i=100;i>0;i--);
ds = 1;
for(i=5;i>0;i--);
}
始终不明白为什么我将延时变量 i 定义为 unsigned char 后 温度显示一直为5.9
后面有几个函数中也有同样的问题 只有定义为unsigned int 后 温度显示才正常
明明没有超出范围啊。。害我调了一天。。太难发现了!
原因可能是:for循环的反汇编代码就是一些加法运算和跳转指令的集合,而51是8位单片机,它做8位(unsigned char)加法运算的速率和16位(unsigned int)加法运算的速率是不一样的,这些可以从反汇编代码中看出来,所以,同样是一句for循环,对于不同类型的循环变量来说,执行时间是完全不一样的。
void Init_DS18B20(void)
{
EA = 0; //关中断
DQ = 1; //DQ复位
delay(16); //稍做延时
DQ = 0; //拉低DQ总线
delay(160); //精确延时,时间范围可以从480到960微秒
DQ = 1; //拉高DQ总线
EA = 1; //开中断
delay(24); //15到60毫秒之内返回低电平
}
unsigned char ReadOneChar(void)
{
unsigned char i = 0;
unsigned char dat = 0;
EA = 0; //关中断
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1; // 数据右移一位
DQ = 1; // 给脉冲信号
if(DQ) // DQ为1
dat|=0x80; // 读出数据
delay(8); // 延时
}
EA = 1; //开中断
return(dat);
}
void WriteOneChar(unsigned char dat)
{
unsigned char i, j;
bit testb;
EA = 0; //关中断
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
DQ=0;
if(testb)
{ //写入 1
i++;i++;i++;i++; //先短延时"0"
DQ=1;
i=16;while(i>0)i--; //再长延时"1"
}else
{ //写入 0
i=16;while(i>0)i--; //先长延时"0"
DQ=1;
i++;i++;i++;i++; //再短延时"1"
}
}
EA = 1; //开中断
}
void Read_DS18B20_ID(void)
{
Init_DS18B20();
WriteOneChar(READ_ROM);
serial[0]=ReadOneChar();
serial[1]=ReadOneChar();
serial[2]=ReadOneChar();
serial[3]=ReadOneChar();
serial[4]=ReadOneChar();
serial[5]=ReadOneChar();
serial[6]=ReadOneChar();
serial[7]=ReadOneChar();
}
void MatchRom(unsigned char *rom)
{
unsigned char i;
Init_DS18B20();
WriteOneChar(MATCH_ROM); //匹配ROM
for(i=0;i<8;i++)
{
WriteOneChar(rom[i]);
}
}
void TemperatureConversion(void)
{
Init_DS18B20(); // 初始化DS18B20
delay(1); // 延时
WriteOneChar(SKIP_ROM); // 跳过序列号命令
WriteOneChar(CONV_TEM); // 发送温度转换命令
}
void DataTreatment(unsigned char *rom)
{
unsigned char a1,a2;
unsigned int temp;
Init_DS18B20(); // 初始化ds18b2
delay(1);
if(*rom==0x28) MatchRom(rom); // 匹配ROM
else WriteOneChar(SKIP_ROM); // 跳过ROM命令
WriteOneChar(READ_REG); // 发送读取数据命令
a1=ReadOneChar();
a2=ReadOneChar(); // 连续读两个字节数据
temp=a2;
temp<<=8;
temp|=a1; // 两字节合成一个整型变量。
if(temp>0x18CC) // 温度值正负判断 0001 1000 1100 1100
{
temp=~temp+1; // 负温度求补码 temp=65536-temp;
Dis_play[5]=1; // 标记温度负,1为负,0为正
}else Dis_play[5]=0;
Dis_play[0]=ditab[temp&0x0f]; // 取小数部分转换为十进制数
Dis_play[4]=temp>>4; // 整数部分的绝对值,可调用
Dis_play[3]=Dis_play[4]/100; // 获得百位数据
Dis_play[1]=Dis_play[4]%100; // 后两位数据暂存
Dis_play[2]=Dis_play[1]/10; // 获得十位数据
Dis_play[1]=Dis_play[1]%10; // 获得个位数据
Dis_play[0] += 48;
Dis_play[1] += 48;
Dis_play[2] += 48;
Dis_play[3] += 48;
if(Dis_play[5])
Dis_play[3]='-'; // 为负数时,百位显示 "-" 11
if(Dis_play[3]==48) // 最高位为0则不显示
{
Dis_play[3]=' '; // 先判断百位是否为0 10
if(Dis_play[2]==48)
Dis_play[2]=' '; // 再判断十位是否为0 10
}
}