我用的STC10L08XE芯片和DS18B20做了个温度传感器,报警温度为42度,到42度,MCU的TXD脚发出一个0x31信号,为什么用下面程序发不出来呢!哪位高手帮看看怎么回事?我DS18B20没用寄生电源,谢谢!
#include <STC10L08XE.H>
#include <INTRINS.H>
#define uint unsigned int
#define uchar unsigned char
//#define SETA P1_5
//#define SETB P3_4
#define DQ P2_4
//#define BEEP P3_0
//uchar BEEP;
uchar ch;
uchar flag;
bit read_flag= 0 ;
bit DQ;
//bit SETA;
//bit SETB;
bit beep_st;
signed char m;uchar n;
uchar x=0;
uint temp;
signed char shangxian=10;
void Delay1us() [url=]//@11.0592MHz[/url]
{
_nop_();
}
void Delay7us() [url=]//@11.0592MHz[/url]
{
unsigned char i;
_nop_();
i = 16;
while (--i);
}
void Delay60us() [url=]//@11.0592MHz[/url]
{
unsigned char i, j;
_nop_();
_nop_();
i = 1;
j = 161;
do
{
while (--j);
} while (--i);
}
void Delay180us() [url=]//@11.0592MHz[/url]
{
unsigned char i, j;
_nop_();
i = 2;
j = 236;
do
{
while (--j);
} while (--i);
}
void Delay240us() [url=]//@11.0592MHz[/url]
{
unsigned char i, j;
i = 3;
j = 145;
do
{
while (--j);
} while (--i);
}
void Delay999ms() [url=]//@11.0592MHz[/url]
{
unsigned char i, j, k;
_nop_();
i = 42;
j = 252;
k = 9;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Init_Com(void)
{
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xFD; // 波特率9600
TL1 = 0xFD;
SCON = 0x50; // 设定串行口工作方式
PCON = 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
IE |= 0x90 ;
// TI=1;
}
Init_DS18B20(void)
{
CY=1;
while(CY)
{
DQ=0;
Delay240us();
Delay240us(); //480us
DQ=1;
Delay60us();
CY=DQ;
Delay240us(); //200us
Delay180us();
}
}
uchar tmpread(void) //read a byte date
{
uchar i = 0;
uchar dat = 0;
for(i=8;i>0;i--)
{
DQ = 0; //将总线拉低,要在1us之后释放总线
//单片机要在此下降沿后的15us内读数据才会有效。
Delay1us(); //至少维持了1us,表示读时序开始
dat >>= 1; //让从总线上读到的位数据,依次从高位移动到低位。
DQ = 1; //释放总线,此后DS18B20会控制总线,把数据传输到总线上
Delay7us(); //延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分
if(DQ) //控制器进行采样
{
dat |= 0x80; //若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0
}
Delay60us(); //此延时不能少,确保读时序的长度60us。
}
return (dat);
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{
uchar i = 0;
for(i=8;i>0;i--)
{
DQ = 0; //拉低总线
Delay1us(); //至少维持了1us,表示写时序(包括写0时序或写1时序)开始
DQ = dat&0x01; //从字节的最低位开始传输
//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,
//因为15us后DS18B20会对总线采样。
Delay60us(); //必须让写时序持续至少60us
DQ = 1; //写完后,必须释放总线,
dat >>= 1;
Delay1us();
}
}
uint tmp() //get the temperature
{
float tt;
uchar a,b;
Init_DS18B20();
tmpwritebyte(0xcc); // address all drivers on bus
tmpwritebyte(0x44); // initiates a single temperature conversionInit_DS18B20();
Init_DS18B20();
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
void send_char(unsigned char ch)
// 传送一个字符
{
SBUF = ch;
while(TI==0); //
TI = 0; // 清除数据传送标志
}
void serial () interrupt 4
{
if (RI){
RI = 0 ;
ch=SBUF;
read_flag= 1 ; //就置位取数标志
}
}
void Alarm()
{
//if(x>=10){beep_st=~beep_st;x=0;}
if(temp>shangxian)
{ch=0x31;
P1=0;
P3=0xef;
send_char(ch);
}
else
{
P1=1;
P3=0xff;
}
}
void main()
{
Init_Com();
do
{
tmp();
Alarm();
Delay999ms();
Delay999ms();
Delay999ms();
Delay999ms();
Delay999ms();
} while(1);
} |