📄 design.c
字号:
#include <AT89X51.H>
#include <INTRINS.H>
#define uchar unsigned char
bit Tflag;//温度正负标志
sbit DQ = P3^7; //定义DQ通信端口
#define uchar unsigned char //additional
#define uint unsigned int
uchar count; //设定阀值
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40}; //0x40 为负号
unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //
unsigned char dispbuf[8]={0,0,0,0,0,0,0,0};
void digitalshow(unsigned char a2,unsigned char a1,unsigned char a0){
unsigned char i;
dispbuf[0]=a0;
dispbuf[1]=a1;
dispbuf[2]=a2;
for(i=0;i<2;i++)
{
P2_0=1;P2_1=1; //关闭所有显示
//P2=0xff;
if (i==0) {P0=dispcode[dispbuf[i]];P2_0=0;P2_1=1;}
else {P0=dispcode[dispbuf[i]]; P2_0=1;P2_1=0;}
}
}
/********** 该程序为总线上只有一个器件 单总线**********/
//毫秒延时 晶振频率为11.0592 MHz
void delay_10ms() //10ms delay routine additional
{ uint i;
for(i = 0; i < 10000; i++);
}
uchar keyscan() //keyscan routine additional
{ uchar temp;
//P1 = 0xff;
temp = P1;
if( temp != 0xff)
{ delay_10ms();
temp = P1;
if( temp != 0xff)
{ if( P1_0 == 0) return 10;
else if (P1_1 == 0) return 20;
else if (P1_2 == 0) return 30;
else if (P1_3 == 0) return 40;
else if (P1_4 == 0) return 50;
else if (P1_5 == 0) return 60;
else if (P1_6 == 0) return 70;
else return 80;
}
}
else return 0xff;
}
void dmsec (unsigned int count){ // 1ms延时
unsigned int i;
while (count--)
{
for (i=0;i<125;i++){}
}
}
void Delay(unsigned int num){ // 延时函数
while( --num );
}
void tmreset (void) { //复位脉冲
DQ = 0;
Delay(90); // 精确延时 大于 480us
DQ = 1;
Delay(4); // 90,4 可以小范围变化
}
void tmpre (void) { //存在脉冲
while (DQ);
while (~DQ);
Delay(4);
}
bit tmrbit (void) { //读一个位
unsigned int i;
bit dat;
DQ = 0; i++; // i++;大概1us
DQ = 1; i++; i++;
dat = DQ;
Delay(8);
return (dat);
}
unsigned char tmrbyte (void) { //读一个比特
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
j = tmrbit();
dat = (j << 7) | (dat >> 1);
}
return (dat);
}
void tmwbyte (unsigned char dat){ //写一个比特
unsigned int i;
unsigned char j;
bit testb;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1; // 从低位开始?
if (testb)
{// Write 1
DQ = 0; // 先拉低
i++; i++; // >1us
DQ = 1;
Delay(4);
}
else
{// Write 0
DQ = 0;
Delay(4); // 大一点 没影响,但不能太大,写一个位在30us内
DQ = 1;
i++; i++; // 再拉高
}
}
}
void tmstart (void) { //ds1820开始转换
dmsec(1);
tmreset ();
tmpre ();
dmsec (1);
tmwbyte (0xcc); // skip rom
tmwbyte (0x44); // 转换
}
unsigned char tmrtemp (void) { //读取温度
unsigned char a,b,y1,y2,y3;
tmreset ();
tmpre ();
dmsec (1);
tmwbyte (0xcc); // skip rom
tmwbyte (0xbe); // 转换
a = tmrbyte (); // LSB低8位
b = tmrbyte (); // MSB高8位
if((b & 0x80)==0x80) //判断温度正负
{
b=~b;a=~a+1; //负温度处理(DS18B20的负温度是正的反码,即将它取反+1,就得到正的温度)
y1=a>>4; //降低精度(去掉小数点)
y2=b<<4; //减小测量范围(-55°C---99°C)
y3=y1 | y2;
Tflag=0;
}
else
{
y1=a>>4;
y2=b<<4;
y3=y1 | y2;
Tflag=1;
}
return(y3);
}
void done(void){
P2_5=0;
if (P2_4==1){
P2_5=1;
P2_7=0;
}
}
/********** MAIN **********/
void main (void){
uchar last;
uchar lsb,msb;
uchar i;
tmstart();
dmsec(450); // 初始化ds18b20
while(1){
count = keyscan(); //additional
tmstart(); // ds1820开始转换
dmsec(2);
last=tmrtemp(); // 读取温度
done();
if (last >= count) //达到设定阀值温度时在P2.7产生驱动信号
{
P2_7 = 1;P2_6=0;
dmsec(6000);
}
// else { P2_7 = 0;}
P2_6=1;
msb=last/10;
lsb=last%10;
for(i=255;i>0;i--){
if(Tflag==1)
{digitalshow(16,msb,lsb);} //
else
{digitalshow(17,msb,lsb);}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -