PCA 发表于 2012-4-6 08:48:16

看不少网友说1-wire总线协议多点测温的,贴个自己写成功的

本帖最后由 PCA 于 2012-4-6 08:48 编辑

设计任务与要求
1、以52系列单片机为控制核心,读取DS18B20的ROM号,通过1-wire总线在一个IO上挂多个DS18B20,通过匹配ROM号读取相应温度传感器的温度值;
2、 通过单片机读取DS1302时间送往LCD12864显示时钟;
3、按键扫描,可在温度显示和时钟显示界面之间切换;
4、可设置是否开启过温报警,及单独设置每个温度点的上限温度报警值;
5、当某点温度超过设置温度时,液晶显示温度超过的温度采集点,并通过无线报警,使蜂鸣器鸣叫。

读ROM程序如下:
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DQ=P1^2;
uchar data RomCode[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar code num[]="0123456789";

/*****************************************************************************/
sbit LCD_cs   = P3^5;
sbit LCD_std= P3^6;
sbit LCD_sclk = P3^4;
sbit LCD_psb= P3^7;   //H=并口; L=串口;
sbit LCD_rst= P2^7;   //Reset Signal 低电平有效

/****************************************************************************/
//函数声明
void Delay(int num);
void LCD_WriteString(unsigned char *str) ;//写字符例:LCD_WriteString("您好!");
void LCD_WriteDatOrCom(bit ,unsigned char );//(0,指令) (1,数据)
void LCD_w_byte(unsigned char bbyte);//写一个字节给LCD
void delaynms(unsigned int di);//延时
void LCD_init(void); //LCD初始化
void LCD_clr(void);//清屏
/******************************************************************************/
void Delay(int num)//延时函数
{
        while(num--);
}
/****************************************************************************/
void delay_ms(uint x)
{
        uint i,j;
        for(i=0;i<x;i++)
                for(j=0;j<120;j++);
}
//初始化LCD
void LCD_init(void)       
{
        LCD_rst=1;
        LCD_psb=0;
        LCD_WriteDatOrCom (0,0x30);/*30---基本指令动作*/   
        LCD_WriteDatOrCom (0,0x01);/*清屏,地址指针指向00H*/
        Delay (100);
        LCD_WriteDatOrCom (0,0x06);/*光标的移动方向*/
        LCD_WriteDatOrCom(0,0x0c);/*开显示,关游标*/
}
/******************************************************************************/
//写指令或数据(0,指令) (1,数据)
void LCD_WriteDatOrCom(bit dat_comm,uchar content)
{
        uchar a,i,j;
        Delay(200);
        a=content;
        LCD_cs=1;
        LCD_sclk=0;
        LCD_std=1;
        for(i=0;i<5;i++)
        {
                LCD_sclk=1;
                LCD_sclk=0;
        }
        LCD_std=0;
        LCD_sclk=1;
        LCD_sclk=0;
        if(dat_comm)
        LCD_std=1;   //data
        else
        LCD_std=0;   //command
        LCD_sclk=1;
        LCD_sclk=0;
        LCD_std=0;
        LCD_sclk=1;
        LCD_sclk=0;
        for(j=0;j<2;j++)
        {
                for(i=0;i<4;i++)
                {
                        a=a<<1;
                        LCD_std=CY;
                        LCD_sclk=1;
                        LCD_sclk=0;
                }
                LCD_std=0;
                for(i=0;i<4;i++)
                {
                        LCD_sclk=1;
                        LCD_sclk=0;
                }
        }
}
/*********************************************************************************/
/*void chn_disp (uchar code *chn)
{
uchar i,j;
LCD_WriteDatOrCom(0,0x30);
LCD_WriteDatOrCom(0,0x80);
for (j=0;j<4;j++)
{
for (i=0;i<16;i++)
LCD_WriteDatOrCom(1,chn);
}
}


*/       
/*****************************************************************************/
//清屏函数
void LCD_clr(void)
{
        LCD_WriteDatOrCom (0,0x30);
        LCD_WriteDatOrCom (0,0x01);
        Delay (100);
}

/*****************************************************************************/
//向LCD发送一个字符串,长度64字符之内。
//应用:LCD_WriteString("您好!");
void LCD_WriteString(unsigned char *str)
{
        while(*str != '\0')
        {
                LCD_WriteDatOrCom(1,*str++);
        }
        *str = 0;
}
void delay_18B20(uint i)
{
        while(i--);
}

void Init_DS18B20(void)
{
        uchar x=0;
        DQ=1;//DQ复位
        delay_18B20(8);
        DQ=0;
        delay_18B20(80);
        DQ=1;
        delay_18B20(14);
        x=DQ;   //稍作延时后如果x=0则初始化成功 x=1则初始化失败
        delay_18B20(20);
}

uchar ReadOneChar(void)
{
        uchar i=0;
        uchar dat=0;
        for(i=8;i>0;i--)
        {
                DQ=0;//给脉冲信号
                dat>>=1;
                DQ=1;//给脉冲信号
                if(DQ)
                dat|=0x80;
                delay_18B20(4);
        }
        return(dat);
}

void WriteOneChar(uchar dat)
{
        uchar i=0;
        for(i=8;i>0;i--)
        {
                DQ=0;
                DQ=dat&0x01;
                delay_18B20(5);
                DQ=1;
                dat>>=1;
        }
}

/*void Set_DS18B20()
{
       
}*/
void Read_RomCord(void)
{
        uchar j;
        Init_DS18B20();
        WriteOneChar(0x33);
        for(j=0;j<8;j++)
        {
                RomCode=ReadOneChar();       
        }
}
/*
uchar CRC8()
{
        uchar i,x;
        uchar crcbuff;
        crc=0;
        for(x=0;x<8;x++)
        {
                crcbuff=RomCode;
                for(i=0;i<8;i++)
                {
                        if(((crc^crcbuff)&0x01)==0)
                                crc>>=1;
                        else
                                {
                                        crc^=0x18;//CRC=X8+X5+X4+1
                                        crc>>=1;
                                        crc|=0x80;
                                }
                                crcbuff>>=1
                }
        }
        return crc;
}        */

void main()
{        uint i;
        LCD_init();
       
        LCD_WriteDatOrCom (0,0x80);
        LCD_WriteString("丁孟飞,℃梦飞,梦航,梦扬,蓝玻璃");
        delay_ms(500);delay_ms(500);delay_ms(500);
        delay_ms(500);delay_ms(500);delay_ms(500);
        delay_ms(500);delay_ms(500);delay_ms(500);
        LCD_clr();
        Init_DS18B20();
        Read_RomCord();
        while(1)
        {
                LCD_WriteDatOrCom (0,0x80);
                for(i=0;i<8;i++)
                {
                        LCD_WriteDatOrCom (1,num/100]);
                        LCD_WriteDatOrCom (1,num%100/10]);
                        LCD_WriteDatOrCom (1,num%10]);
                        LCD_WriteString(" ");       
                }                       
        }       
}






测温应用程序如下:六点测温,无限报警,设置没点上限报警温度,显示万年历
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

#define uint unsigned int
#define uchar unsigned char

uchar data RomCode={{0x28,0x1A,0xA7,0x14,0x02,0x00,0x00,0x91},        //ROM 1
                                              {0x28,0xCC,0x9D,0x14,0x02,0x00,0x00,0xDE},        //ROM 2
                                              {0x28,0xBD,0x70,0x14,0x02,0x00,0x00,0x47},        //ROM 3
                                              {0x28,0xC0,0x8A,0x14,0x02,0x00,0x00,0x8E},        //ROM 4
                                              {0x28,0x90,0x69,0xAF,0x01,0x00,0x00,0xD5},        //ROM 5
                                              {0x28,0x43,0x8C,0x14,0x02,0x00,0x00,0xA1}};   //ROM 6
uchar num[]="0123456789";
uint temp;
bit BJ=0;//是否超温报警
/********************************************************************
****按键位定义
********************************************************************/
sbit s1=P2^2;
sbit s2=P2^3;
sbit s3=P2^4;
#define S1 s1==0
#define S2 s2==0
#define S3 s3==0
/********************************************************************
****函数名称:delay_ms(uint x)
****函数功能:毫秒延时函数
****备注说明:
********************************************************************/
void delay_ms(uint x)
{
        uint i,j;
        for(j=0;j<x;j++)
                for(i=0;i<110;i++);
}
/********************************************************************
*********************************************************************
***************************LCD12864部分******************************
*********************************************************************
********************************************************************/
#define LCD_dataP0             //数据口
sbit LCD_RS=P1^5;            //寄存器选择输入
sbit LCD_RW=P1^6;            //液晶读/写控制
sbit LCD_EN=P1^7;            //液晶使能控制               
/********************************************************************
****函数名称:LCD_WriteCmd
****函数功能:向LCD12864写入命令
****备注说明:RS=L,RW=L,E=A上升沿,D0-D7=命令
********************************************************************/
void LCD_WriteCmd(uchar cmd)
{                        
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    LCD_data= cmd;
        delay_ms(5);
    LCD_EN = 1;
        delay_ms(5);
    LCD_EN = 0;
}
/********************************************************************
****函数名称:LCD_WriteDat
****函数功能:写显示数据到LCD
****备注说明:RS=H,RW=L,E=上升沿,D0-D7=数据
********************************************************************/
void LCD_WriteDat(uchar dat)
{                        
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    LCD_data= dat;
        delay_ms(5);
    LCD_EN = 1;
        delay_ms(5);
    LCD_EN = 0;
}
/********************************************************************
****函数名称:LCD_WriteString
****函数功能:写字符串到LCD
****备注说明:应用例如 LCD_WriteString("你好,梦航");
********************************************************************/
void LCD_WriteString(uchar *str)
{
        while(*str != '\0')
        {
                LCD_WriteDat(*str++);
                delay_ms(1);
        }
        *str = 0;
}
/********************************************************************
****函数名称:LCD_Init()
****函数功能:LCD初始化
****备注说明:
********************************************************************/
void LCD_Init()
{
    LCD_WriteCmd(0x30);      //基本指令操作
    delay_ms(5);
    LCD_WriteCmd(0x0C);      //显示开,关光标
    delay_ms(5);
    LCD_WriteCmd(0x01);      //清除LCD的显示内容
    delay_ms(5);
}
/********************************************************************
*********************************************************************
***************************DS1302部分********************************
*********************************************************************
*********************************************************************/
sbit DS1302_SCLK= P1^0;         //DS1302时钟口P1.0
sbit DS1302_IO= P1^1;         //DS1302数据口P1.1
sbit DS1302_RST = P1^2;         //DS1302片选口P1.2
uchar Year,Month,Day,Week,Hour,Minute,Second;
/********************************************************************
****函数名称:uchar DS1302_Readuchar()
****函数功能:从DS1302读1字节数据
****备注说明:
********************************************************************/
uchar DS1302_Readuchar()
{
    uchar i;
    uchar dat = 0;

    for (i=0; i<8; i++)             //8位计数器
    {
      DS1302_SCLK = 0;                   //时钟线拉低
      _nop_();                  //延时等待
      _nop_();
      dat >>= 1;                  //数据右移一位
      if (DS1302_IO) dat |= 0x80;      //读取数据
      DS1302_SCLK = 1;                   //时钟线拉高
      _nop_();                  //?óê±μè′y
      _nop_();
    }
    return dat;
}
/********************************************************************
****函数名称:DS1302_Writeuchar(uchar dat)
****函数功能:向DS1302写1字节数据
****备注说明:
********************************************************************/
void DS1302_Writeuchar(uchar dat)
{
    char i;

    for (i=0; i<8; i++)             //8位计数器
    {
      DS1302_SCLK = 0;                   //时钟线拉低
      _nop_();                  //延时等待
      _nop_();
      dat >>= 1;                  //移出数据
      DS1302_IO = CY;                  //送出到端口
      DS1302_SCLK = 1;                   //时钟线拉高
      _nop_();                  //延时等待
      _nop_();
    }
}
/********************************************************************
****函数名称:DS1302_Read(uchar addr)
****函数功能:读DS1302某地址的的数据
****备注说明:
********************************************************************/
uchar DS1302_Read(uchar addr)
{
    uchar dat;

    DS1302_RST = 0;
    _nop_();                        //延时等待
    _nop_();
    DS1302_SCLK = 0;
    _nop_();                        //延时等待
    _nop_();
    DS1302_RST = 1;
    _nop_();                        //延时等待
    _nop_();
    DS1302_Writeuchar(addr);         //写地址
    dat = DS1302_Readuchar();      //读数据
    DS1302_SCLK = 1;
    DS1302_RST = 0;

    return dat;
}
/********************************************************************
****函数名称:DS1302_Write(uchar addr, uchar dat)
****函数功能:往DS1302的某个地址写入数据
****备注说明:
********************************************************************/
void DS1302_Write(uchar addr, uchar dat)
{
    DS1302_RST = 0;
    _nop_();                        //延时等待
    _nop_();
    DS1302_SCLK = 0;
    _nop_();                        //延时等待
    _nop_();
    DS1302_RST = 1;
    _nop_();                        //延时等待
    _nop_();
    DS1302_Writeuchar(addr);         //写地址
    DS1302_Writeuchar(dat);          //写数据
    DS1302_SCLK = 1;
    DS1302_RST = 0;
}
/********************************************************************
****函数名称:DS1302_SetTime()
****函数功能:写入DS1302初始时间
****备注说明:
********************************************************************/
void DS1302_SetTime()
{
    DS1302_Write(0x8e, 0x00);   //允许写操作
        DS1302_Write(0x8c, 0x12);//年
        DS1302_Write(0x88, 0x03);//月
        DS1302_Write(0x86, 0x29);//日
        DS1302_Write(0x8a, 0x04);//周
        DS1302_Write(0x84, 0x09);//时
        DS1302_Write(0x82, 0x01);//分
        DS1302_Write(0x80, 0x40);//秒
    DS1302_Write(0x8e, 0x80);   //写保护
}
/********************************************************************
****函数名称:LCD_ShowTime()
****函数功能:读取当前时间
****备注说明:
********************************************************************/
void LCD_ShowTime()
{
        Year=DS1302_Read(0x8d);
        Month=DS1302_Read(0x89);
        Day=DS1302_Read(0x87);
        Week=DS1302_Read(0x8b);
        Hour=DS1302_Read(0x85);
        Minute=DS1302_Read(0x83);
        Second=DS1302_Read(0x81);

        LCD_WriteCmd(0x80);
        LCD_WriteString("20");
        LCD_WriteDat(Year/16+0x30);
        LCD_WriteDat(Year%16+0x30);
        LCD_WriteString("年");
        LCD_WriteDat(Month/16+0x30);
        LCD_WriteDat(Month%16+0x30);
        LCD_WriteString("月");
        LCD_WriteDat(Day/16+0x30);
        LCD_WriteDat(Day%16+0x30);
        LCD_WriteString("日");
               
        LCD_WriteCmd(0x90);
        LCD_WriteDat(Hour/16+0x30);
        LCD_WriteDat(Hour%16+0x30);
        LCD_WriteString(":");
        LCD_WriteDat(Minute/16+0x30);
        LCD_WriteDat(Minute%16+0x30);
        LCD_WriteString(":");
        LCD_WriteDat(Second/16+0x30);
        LCD_WriteDat(Second%16+0x30);
        LCD_WriteString("星期");
        switch(Week)
        {
                case 0x01:
                        LCD_WriteString("一");break;
                case 0x02:
                        LCD_WriteString("二");break;
                case 0x03:
                        LCD_WriteString("三");break;
                case 0x04:
                        LCD_WriteString("四");break;
                case 0x05:
                        LCD_WriteString("五");break;
                case 0x06:
                        LCD_WriteString("六");break;
                case 0x07:
                        LCD_WriteString("日");break;
        }

        if(BJ==0)
        {
                LCD_WriteCmd(0x88);
                LCD_WriteString("苦心人,天不负!");       
       
                LCD_WriteCmd(0x98);
                LCD_WriteString("有志者,事竞成!");       
        }
        if(BJ==1)
        {
                LCD_WriteCmd(0x88);
                LCD_WriteString("超温报警点:    ");               
        }
}
/********************************************************************
*********************************************************************
***************************DS18B20部分*******************************
*********************************************************************
*********************************************************************/
sbit DQ=P1^3;
/********************************************************************
****函数名称:delay_18B20()
****函数功能:DS18B20短延时
****备注说明:
********************************************************************/
void delay_18B20(uint i)
{
        while(i--);
}
/********************************************************************
****函数名称:DS18B20_Init()
****函数功能:DS18B20初始化
****备注说明:
********************************************************************/
void DS18B20_Init(void)
{
        uchar x=0;
        DQ=1;//DQ复位
        delay_18B20(8);
        DQ=0;
        delay_18B20(80);
        DQ=1;
        delay_18B20(14);
        x=DQ;   //稍作延时后如果x=0则初始化成功 x=1则初始化失败
        delay_18B20(20);
}
/********************************************************************
****函数名称:ReadOneChar(void)
****函数功能:DS18B20读一个字节数据
****备注说明:
********************************************************************/
uchar ReadOneChar(void)
{
        uchar i=0;
        uchar dat=0;
        for(i=8;i>0;i--)
        {
                DQ=0;//给脉冲信号
                dat>>=1;
                DQ=1;//给脉冲信号
                if(DQ)//如果DQ为1则初始化成功
                dat|=0x80;
                delay_18B20(4);
        }
        return(dat);
}
/********************************************************************
****函数名称:WriteOneChar(void)
****函数功能:DS18B20写一个字节数据
****备注说明:
********************************************************************/
void WriteOneChar(uchar dat)
{
        uchar i=0;
        for(i=8;i>0;i--)
        {
                DQ=0;
                DQ=dat&0x01;
                delay_18B20(5);
                DQ=1;
                dat>>=1;
        }
}
/********************************************************************
****函数名称:ReadTemp(uchar x)
****函数功能:读取X通道数据
****备注说明:X范围1-6,温度值放大十倍输出
********************************************************************/
int ReadTemp(uchar x)//读取通道x的温度值
{
        uchar i,temp_H,temp_L;
        int WEN;
        DS18B20_Init();
        delay_18B20(80);
        WriteOneChar(0xcc);//跳过读ROM号
        WriteOneChar(0x44);//所有的传感器开始转换温度
        delay_ms(50);
        DS18B20_Init();
        WriteOneChar(0x55);        //发送ROM匹配命令
        for(i=0;i<8;i++)
        WriteOneChar(RomCode);
        WriteOneChar(0xBE);        //读温度寄存器(共可读9个寄存器)前两个是温度
        delay_18B20(80);
        temp_L=ReadOneChar();//读取温度的低位
        temp_H=ReadOneChar();//读取温度的高位
        WEN=(int)((temp_H*256+temp_L)*0.625);//温度放大十倍输出
        return(WEN);
}
/********************************************************************
****函数名称:LCD_ShowTemp()
****函数功能:向LCD写入温度
****备注说明:
********************************************************************/
void LCD_ShowTemp()
{
        temp=ReadTemp(1);
        temp=ReadTemp(2);
        temp=ReadTemp(3);
        temp=ReadTemp(4);
        temp=ReadTemp(5);
        temp=ReadTemp(6);

        LCD_WriteCmd(0x80);
        LCD_WriteString("温度检测中………");
        LCD_WriteCmd(0x90);
        LCD_WriteString("①");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");
        LCD_WriteString("②");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");

        LCD_WriteCmd(0x88);
        LCD_WriteString("③");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");
        LCD_WriteString("④");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");

        LCD_WriteCmd(0x98);
        LCD_WriteString("⑤");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");
        LCD_WriteString("⑥");
        LCD_WriteDat(num/100]);//十位
        LCD_WriteDat(num%100/10]);//个位
        LCD_WriteString(".");
        LCD_WriteDat(num%10]);//十分位
        LCD_WriteString("℃");
}
/********************************************************************
****函数名称:LCD_ShowWelcome()
****函数功能:向LCD写入开机欢迎界面
****备注说明:按下S1键显示下一页
********************************************************************/
void LCD_ShowWelcome()
{
        LCD_WriteCmd(0x80);
        LCD_WriteString("基于1-wire总线的");       
        LCD_WriteString("作者:丁孟飞    ");
        LCD_WriteString("多点测温报警系统");
        LCD_WriteString("学号:2009041507");
        while((s1!=0)&&(s2!=0)&&(s3!=0)); //按下任意键,进入下一页显示
        LCD_WriteCmd(0x01);
        LCD_WriteCmd(0x80);
        LCD_WriteString("    操作说明    ");       
        LCD_WriteString("时间,短按S1显示");
        LCD_WriteString("1.初始化界面显示");
        LCD_WriteString("温度检测界面,再");
        while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
        LCD_WriteCmd(0x01);
        LCD_WriteCmd(0x80);
        LCD_WriteString("按返回时间界面显");       
        LCD_WriteString("2.长按S1进入温度");
        LCD_WriteString("示,循环之。    ");
        LCD_WriteString("报警设置,可以设");
        while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
        LCD_WriteCmd(0x01);
        LCD_WriteCmd(0x80);
        LCD_WriteString("置是否开启过温报");       
        LCD_WriteString("点的报警温度。");
        LCD_WriteString("警功能及设置每个");
        LCD_WriteString("在使用过程中有好");
        while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
        LCD_WriteCmd(0x01);
        LCD_WriteCmd(0x80);
        LCD_WriteString("的建议请不吝赐教");       
        LCD_WriteString("权归本人所有,再");
        LCD_WriteString("。本作品最终解释");
        LCD_WriteString("次谢谢使用!    ");
        while((s1!=0)&&(s2!=0)&&(s3!=0));//按下任意键,进入下一页显示
        LCD_WriteCmd(0x01);
        LCD_WriteCmd(0x80);
        LCD_WriteString("                ");       
        LCD_WriteString("                ");
        LCD_WriteString("请输入开机密码:");
        LCD_WriteString("                ");
}
/********************************************************************
****函数名称:KeyScan()
****函数功能:案件处理程序,也是最复杂的啊
****备注说明:开机后显示欢迎界面,按下S1翻页,欢迎界面后显示时钟界面,
                          短按S1显示六点温度检测界面,再按显示时钟界面,再按循环,
                          长按S1键进入温度报警设置界面,可设置是否允许过温报警及
                          设置每一点的高温报警温度。
********************************************************************/
bit chang=0,//长按及短按标志位
        TorW=0, //显示温度设定或者始终欢迎界面,0显示失踪接界面,1显示温度检测界面
        ENABLE_BJ=0;        //是否开启过温报警功能
uint press_num=0;//记录按键S1按下的时间
uint BJT0=350,BJT1=350,BJT2=350,BJT3=350,BJT4=350,BJT5=350,//六个报警温度
          s1num=0;           //记录按键S1长按再次按下的次数
void KeyScan()
{
/*******************************************************************
*************************按键S1处理程序*****************************
*******************************************************************/
        if(S1)
        {
                delay_ms(20);           //z延时消抖动
                if(S1)
                {
                        while(S1)
                        {
                                press_num++;
                                delay_ms(20);//20ms延时
                                if(press_num==150)
                                        break;                                                                                               
                        }
                        if(press_num>140)            //按下时间大于3秒为长按
                        {
                                press_num=0;
                                chang=1;

                                LCD_WriteCmd(0x01);//清屏
                                LCD_WriteCmd(0x80);
                                LCD_WriteString("是否开启报警:否");//设置是否开启过温报警功能

                                LCD_WriteCmd(0x90);
                                LCD_WriteString("①");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位
                                LCD_WriteString("℃");
                                LCD_WriteString("②");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位
                                LCD_WriteString("℃");
                       
                                LCD_WriteCmd(0x88);
                                LCD_WriteString("③");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位
                                LCD_WriteString("℃");
                                LCD_WriteString("④");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位
                                LCD_WriteString("℃");
                       
                                LCD_WriteCmd(0x98);
                                LCD_WriteString("⑤");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位
                                LCD_WriteString("℃");
                                LCD_WriteString("⑥");
                                LCD_WriteDat(num);//十位
                                LCD_WriteDat(num);//个位
                                LCD_WriteString(".");
                                LCD_WriteDat(num);//十分位       
                        }                       
                        if((press_num<=100)&&(chang==0))//按下时间小于等于2秒为短按
                        {
                                press_num=0;
                                chang=0;
                                TorW=~TorW;       
                        }                                               
                        if(press_num<=100&&(chang==1))        //在调整报警温度时短按进入下一项调整
                        {
                                s1num++;
                                switch(s1num)
                                {        //光标闪烁点定位
                                        case 1: LCD_WriteCmd(0x87);
                                                        LCD_WriteCmd(0x0f);
                                                        break;
                                        case 2: LCD_WriteCmd(0x90);
                                                        break;
                                        case 3: LCD_WriteCmd(0x94);
                                                        break;
                                        case 4: LCD_WriteCmd(0x88);
                                                        break;
                                        case 5: LCD_WriteCmd(0x8c);
                                                        break;
                                        case 6: LCD_WriteCmd(0x98);
                                                        break;
                                        case 7: LCD_WriteCmd(0x9c);
                                                        break;
                                        case 8: chang=0;
                                                        s1num=0;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x01);//清屏
                                                        LCD_ShowTime();//返回时钟显示界面
                                                        break;
                                }
                        }
                }
        }
/*******************************************************************
*************************按键S2处理程序*****************************
*******************************************************************/
        if(s1num!=0)//只有S1长按下后才检测S2
        {
                if(S2)
                {
                        delay_ms(20);
                        if(S2)
                        {
                                while(S2);//等待S2松开
                                switch(s1num)
                                {
                                        case 1:
                                                        ENABLE_BJ=~ENABLE_BJ;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        if(ENABLE_BJ==0)
                                                        {
                                                                LCD_WriteCmd(0x87);
                                                                LCD_WriteString("否");//设置是否开启过温报警功能
                                                        }
                                                        else
                                                        {
                                                                LCD_WriteCmd(0x87);
                                                                LCD_WriteString("是");//设置是否开启过温报警功能       
                                                        }
                                                        LCD_WriteCmd(0x87);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 2:
                                                        BJT0=BJT0+5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x91);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x90);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 3:
                                                        BJT1=BJT1+5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x95);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x94);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 4:
                                                        BJT2=BJT2+5;
                                                        LCD_WriteCmd(0x89);
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 5:
                                                        BJT3=BJT3+5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x8D);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x8C);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 6:
                                                        BJT4=BJT4+5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x99);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x98);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                        case 7:
                                                        BJT5=BJT5+5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x9D);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x9C);
                                                        LCD_WriteCmd(0x0F);
                                                        break;
                                }
                        }
                }
        }
/*******************************************************************
*************************按键S3处理程序*****************************
*******************************************************************/
        if(s1num!=0)//只有S1长按下后才检测S3
        {
                if(S3)
                {
                        delay_ms(20);
                        if(S3)
                        {
                                while(S3);//等待S3松开
                                switch(s1num)
                                {
                                        case 1:
                                                        ENABLE_BJ=~ENABLE_BJ;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        if(ENABLE_BJ==0)
                                                        {
                                                                LCD_WriteCmd(0x87);
                                                                LCD_WriteString("否");//关闭过温报警功能
                                                        }
                                                        else
                                                        {
                                                                LCD_WriteCmd(0x87);
                                                                LCD_WriteString("是");//开启过温报警功能       
                                                        }
                                                        LCD_WriteCmd(0x87);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 2:
                                                        BJT0=BJT0-5;
                                                        LCD_WriteCmd(0x91);
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x90);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 3:
                                                        BJT1=BJT1-5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x95);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x94);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 4:
                                                        BJT2=BJT2-5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x89);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 5:
                                                        BJT3=BJT3-5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x8D);                                                       
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x8C);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 6:
                                                        BJT4=BJT4-5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x99);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x98);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                        case 7:
                                                        BJT5=BJT5-5;
                                                        LCD_WriteCmd(0x0C);//光标不闪烁
                                                        LCD_WriteCmd(0x9D);
                                                        LCD_WriteDat(num);//十位
                                                        LCD_WriteDat(num);//个位
                                                        LCD_WriteString(".");
                                                        LCD_WriteDat(num);//十分位
                                                        LCD_WriteCmd(0x9C);
                                                        LCD_WriteCmd(0x0F);//光标闪烁
                                                        break;
                                }
                        }
                }
        }
}
/********************************************************************
*********************************************************************
***************************蜂鸣器报警部分****************************
*********************************************************************
*********************************************************************/
sbit set_beep=P3^4;
sbit clr_beep=P3^0;
#define Set_Beep set_beep=0
#define Clr_Beep clr_beep=0
/********************************************************************
****函数名称:baojing()
****函数功能:检测温度,超过设置的上限温度时报警,并液晶显示相应的报警点
****备注说明:
********************************************************************/
void baojing()
{
        uint i;
        if(BJ==0)
        {
                Clr_Beep;       
        }               
        if(BJ==1)//只有在报警允许情况下才比较温度,超过设定的温度时提示
        {
                temp=ReadTemp(1);
                temp=ReadTemp(2);
                temp=ReadTemp(3);
                temp=ReadTemp(4);
                temp=ReadTemp(5);
                temp=ReadTemp(6);

                if(temp>=BJT0)//第一点温度超过设置温度
                {
                        if((TorW==0)&&(chang==0))
                        {
                                LCD_WriteCmd(0x98);
                                LCD_WriteString("①");       
                        }
                        if((TorW==1)&&(chang==0))
                        {
                                LCD_WriteCmd(0x0C);
                                LCD_WriteCmd(0x90);
                                LCD_WriteCmd(0x0F);               
                        }                       
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }
                if(temp>=BJT1)//第二点温度超过设置温度
                {
                        if((TorW==0)&&(chang==0))
                        {
                                LCD_WriteCmd(0x99);
                                LCD_WriteString("②");       
                        }
                        if((TorW==1)&&(chang==0))
                        {
                                LCD_WriteCmd(0x94);
                                LCD_WriteCmd(0x0f);               
                        }
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }
                if(temp>=BJT2)//第三点温度超过设置温度
                {
                        if((TorW==0)&&(chang==0))
                        {
                                LCD_WriteCmd(0x9a);
                                LCD_WriteString("③");       
                        }
                        if((TorW==1)&&(chang==0))
                        {
                                LCD_WriteCmd(0x88);
                                LCD_WriteCmd(0x0f);               
                        }
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }
                if(temp>=BJT3)//第四点温度超过设置温度
                {
                        if((TorW==0)&&(chang==0))
                        {
                                LCD_WriteCmd(0x9b);
                                LCD_WriteString("④");       
                        }
                        if((TorW==1)&&(chang==0))
                        {
                                LCD_WriteCmd(0x8c);
                                LCD_WriteCmd(0x0f);               
                        }
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }
                if(temp>=BJT4)//第五点温度超过设置温度
                {
                        if(TorW==0)
                        {
                                LCD_WriteCmd(0x9c);
                                LCD_WriteString("⑤");       
                        }
                        if(TorW==1)
                        {
                                LCD_WriteCmd(0x98);
                                LCD_WriteCmd(0x0f);               
                        }
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }
                if(temp>=BJT5)//第六点温度超过设置温度
                {
                        if((TorW==0)&&(chang==0))
                        {
                                LCD_WriteCmd(0x9d);
                                LCD_WriteString("⑥");       
                        }
                        if((TorW==1)&&(chang==0))
                        {
                                LCD_WriteCmd(0x9c);
                                LCD_WriteCmd(0x0f);               
                        }
                        for(i=0;i<5;i++)
                        {
                                Set_Beep;
                                delay_ms(200);
                                Clr_Beep;
                                delay_ms(200);
                        }
                                               
                }               
        }
}
uchar i,m1=0,m2=0,m3=0,m4=0,bijiao=0,s1_count=0;
uchar MM={1,5,0,7};//初始密码
uchar mima;//密码存储数组
void main()
{       
        LCD_Init();
        DS18B20_Init();
//        DS1302_SetTime();
        LCD_ShowWelcome();
        while(s1_count!=6)
        {
                if(S1)
                {
                        delay_ms(30);
                        if(S1)
                        {
                                while(!s1);
                                s1_count++;
                                switch(s1_count)
                                {
                                        case 1:
                                                LCD_WriteCmd(0x88);
                                                LCD_WriteString("                ");
                                                LCD_WriteCmd(0x8A);
                                                LCD_WriteCmd(0x0F);//闪烁
                                                break;
                                        case 2:
                                                LCD_WriteCmd(0x8B);
                                                mima=m1;
                                                break;
                                        case 3:
                                                LCD_WriteCmd(0x8C);
                                                mima=m2;
                                                break;
                                        case 4:
                                                LCD_WriteCmd(0x8D);
                                                mima=m3;
                                                break;
                                        case 5:
                                                LCD_WriteCmd(0x0c);//取消闪烁
                                                mima=m4;
                                                delay_ms(100);
                                                for(i=0;i<4;i++)
                                                {
                                                        if(MM==mima)
                                                                bijiao++;       
                                                }
                                                if(bijiao==4)
                                                {
                                                        LCD_WriteCmd(0x0C);
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteString("    密码正确    ");
                                                        delay_ms(1000);
                                                        LCD_WriteCmd(0x01);
                                                        LCD_WriteCmd(0x90);
                                                        LCD_WriteString("系统正在启动……");
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);
                                                        LCD_WriteString("■");
                                                        delay_ms(400);

                                                        s1_count=6;                       
                                                }
                                                else
                                                {
                                                        LCD_WriteCmd(0x0C);
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteString("    密码错误    ");
                                                        delay_ms(1000);
                                                        LCD_WriteCmd(0x90);
                                                        LCD_WriteString("请重新输入密码:");
                                                        LCD_WriteCmd(0x88);
                                                        LCD_WriteString("                ");
                                                        /*LCD_WriteCmd(0x8A);
                                                        LCD_WriteCmd(0x0F);//闪烁*/
                                                        m1=0,m2=0,m3=0,m4=0;
                                                        s1_count=0;
                                                        bijiao=0;               
                                                }
                                                break;                                                                               
                                }

                        }
                }
                if(S2)
                {
                        delay_ms(50);
                        if(S2)
                        {
                                while(!s2);
                               switch(s1_count)
                                {
                                        case 1:m1++;
                                                if(m1==10)
                                                        m1=0;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8A);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8A);
                                                break;
                                        case 2:m2++;
                                                if(m2==10)
                                                        m2=0;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8B);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8B);
                                                break;
                                        case 3:m3++;
                                                if(m3==10)
                                                                m3=0;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8C);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8C);
                                                break;
                                        case 4:m4++;
                                                if(m4==10)
                                                        m4=0;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8D);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8D);
                                                break;       
                                }       
                        }
                }
                if(S3)
                {
                        delay_ms(50);
                        if(S3)
                        {
                                while(!s3);
                               switch(s1_count)
                                {
                                        case 1:m1--;
                                                if(m1<0)
                                                        m1=9;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8A);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8A);
                                                break;
                                        case 2:m2--;
                                                if(m2<0)
                                                        m2=9;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8B);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8B);
                                                break;
                                        case 3:m3--;
                                                if(m3<0)
                                                        m3=9;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8C);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8C);
                                                break;
                                        case 4:m4--;
                                                if(m4<0)
                                                        m4=9;
                                                LCD_WriteCmd(0x0C);
                                                LCD_WriteCmd(0x8D);
                                                LCD_WriteDat(num);
                                                LCD_WriteCmd(0x0F);
                                                LCD_WriteCmd(0x8D);
                                                break;       
                                }       
                        }
                }       
       
        }       
        while(1)
        {
                if((TorW==0)&&(chang==0))
                {
                        LCD_ShowTime();       
                }
                if((TorW==1)&&(chang==0))
                {
                        LCD_ShowTemp();       
                }       
                KeyScan();
                baojing();
        }                                       
}

chenyuqiu 发表于 2012-4-6 08:52:27

沙发,收藏起来。

anxiangbo 发表于 2012-4-6 08:55:27

这个厉害!谢楼主

jssd 发表于 2012-4-6 09:01:13

不错,先收藏着。问下楼主,你的圆盘是怎么样弄出来的?

xyz2008 发表于 2012-4-6 09:19:03

楼主,是哪个52单片机,是89S52 , 89C52 , 还是STC的89C52,晶振频率是多少,KEIL的版本是多少,想自己弄给玩玩

jetli 发表于 2012-4-6 09:46:12

不错很有参考价值。。。建议lz再来个动态接入ds18h20,能自动搜索并读写温度的方法,,,

PCA 发表于 2012-4-6 11:58:33

jssd 发表于 2012-4-6 09:01 static/image/common/back.gif
不错,先收藏着。问下楼主,你的圆盘是怎么样弄出来的?

AD9里画的圆盘边界,剪刀剪出个大概,后用锉刀或者砂轮机磨下就OK了{:smile:}

PCA 发表于 2012-4-6 11:59:16

jetli 发表于 2012-4-6 09:46 static/image/common/back.gif
不错很有参考价值。。。建议lz再来个动态接入ds18h20,能自动搜索并读写温度的方法,,, ...

继续研究中,完善中

PCA 发表于 2012-4-6 12:36:29

xyz2008 发表于 2012-4-6 09:19 static/image/common/back.gif
楼主,是哪个52单片机,是89S52 , 89C52 , 还是STC的89C52,晶振频率是多少,KEIL的版本是多少,想自己弄给 ...

STC89C52,晶振12M,keil4编译的

dory_m 发表于 2012-4-6 13:36:31

学习!!!{:biggrin:}{:biggrin:}{:biggrin:}

lvwenjie 发表于 2012-4-8 16:35:42

正在做呢,太好了!拿走!

walton_smith 发表于 2012-4-8 16:57:59

( ^_^ )不错嘛,楼主给力

kupica 发表于 2012-4-8 17:02:21

代码写的很完善,支持楼主

yang1010 发表于 2012-4-8 17:29:22

{:3_52:}谢谢分享

PCA 发表于 2012-4-8 20:12:07

kupica 发表于 2012-4-8 17:02 static/image/common/back.gif
代码写的很完善,支持楼主

多谢夸奖,还有不少完善的地方,要进一步学习,有什么好的建议请不吝赐教

PCA 发表于 2012-4-8 21:41:11

RE: 看不少网友说1-wire总线协议多点测温的,贴个自己写成功

大家反映这么好,求精啊

liuruoshui 发表于 2012-4-8 21:53:19

呵呵!楼主做的挺不错,支持加精!可以用于工程中了!

GUANLU 发表于 2012-4-9 09:59:21

LZ牛啊

Zhhu218 发表于 2012-4-9 12:29:30

下载学习,很有用啊

3050311118 发表于 2012-4-10 20:51:25

标记一下以后用到的时候慢慢看

haffman1 发表于 2012-4-10 21:32:32

多点测温,MARK

airfex 发表于 2012-4-10 22:11:17

楼主的程序完善啊,产品也做的漂亮。

smfox10 发表于 2012-4-10 23:32:56

lz写得很好,上次我做了很笨的,多个IO口控制多个18B...学习你的总线控制{:lol:}

无非 发表于 2012-4-10 23:37:49

好东西必须MARK

zlqzxl126 发表于 2012-4-11 22:51:10

l楼主有没有测试能都测试多远呢?还有就是又没有试过驱动8个?理论上最多驱动8个的。以前用430做过无线发送的单总线测温只是用了4个之后也没调试了

tangwei039 发表于 2012-4-11 22:54:36

mark{:smile:}{:smile:}

PCA 发表于 2012-4-12 13:05:43

zlqzxl126 发表于 2012-4-11 22:51 static/image/common/back.gif
l楼主有没有测试能都测试多远呢?还有就是又没有试过驱动8个?理论上最多驱动8个的。以前用430做过无线发送 ...

十个的都成功了

sdf159372008 发表于 2012-4-12 18:15:28

强帖留名……
我用一种非常愚蠢的方式做了一个4路的温度采集。就是写4段不同的程序用4个IO分别读取4个18B20.

lionsg 发表于 2012-4-17 12:18:22

mark,参考一下

zhenglu891028 发表于 2012-4-17 13:32:07

楼主的程序完善啊

haohai 发表于 2012-4-20 15:57:35

前面定义
uchar data RomCode=
后面这样用可以吗?      
for(i=0;i<8;i++)
      WriteOneChar(RomCode);
二维变一维了

armok 发表于 2012-4-21 03:09:39

cool !

hamipeter 发表于 2012-4-21 14:05:28

谢谢分享

wangshaosh123 发表于 2012-4-21 14:12:06

不错学习一下原理啊啊啊啊

wkman 发表于 2012-4-21 23:22:56

有没有成功的开机后搜索算法查找rom,存储到ram或eeprom{:sweat:},然后再。。。。

dz20062008 发表于 2012-4-22 07:04:25

楼主厉害!代码看起来写的好整齐

jacky2011 发表于 2012-4-22 09:33:54

楼主精神可嘉!

xixi222 发表于 2012-4-25 09:37:36

不错,正学这个,支持下、

lryxr2507 发表于 2012-4-26 13:16:14

自己学习了,还推荐给需用的人了.

cndavy 发表于 2012-4-26 13:58:55

转帖一个动态的
uinttemp;
uchar snn;
uchar sensor_count;

/* 以下是对ds18b20的单总线操作子程序 11.0592MHz */
bit ds1820_init()       /* 单总线初始化,成功返回1,失败返回0 */
{
uchar i;
ds_1wire=0;
for(i=0;i<57;i++);    //delay 500us
ds_1wire=1;
i=0;
while(ds_1wire==1)    /* 最多延时70us,此期间若总线拉低(ds_1wire=0)则结束延时 */
{
    i++;
    if(i>=8) return 0;
}
for(i=0;i<54;i++);    //delay 480us;
if(ds_1wire==0) return 0;
return 1;
}

void ds1820_wr(uchar dat)
{
uchar i,j;
bit b;
for(i=0;i<8;i++)
{
    ds_1wire=0;
    b=dat & 0x01;
    dat=dat>>1;
    ds_1wire=b;
    for(j=0;j<6;j++);    //delay 51us
    ds_1wire=1;
}
}

uchar ds1820_rd(void)
{
uchar i,j;
uchar c;
bit b;
c=0;
for(i=0;i<8;i++)
{
    ds_1wire=0;
    c=c>>1;             //delay 4.3us
    ds_1wire=1;
    if(ds_1wire==1) c |= 0x80;
    for(j=0;j<6;j++);    //delay 59us
}
return c;
}

void get_temp(void)   /* 默认在750ms之前已经启动温度转换 */
{
uchar i,j,lo,hi;
EA=0;
for(i=0;i<sensor_count;i++)
{
    if(ds1820_init()==0) return;
    ds1820_wr(0x55);          /* 匹配rom命令 */
    for(j=0;j<8;j++) ds1820_wr(snn);    /* 写64位序列号 */
    ds1820_wr(0xbe);          /* 读温度命令 */
    lo = ds1820_rd();         /* 读温度低字节 */
    hi = ds1820_rd();         /* 读温度高字节 */
    temp=hi*256+lo;
}
if(ds1820_init()==0) return;
ds1820_wr(0xcc);          /* 跳过rom命令 */
ds1820_wr(0x44);          /* 启动温度转换 */
EA=1;
}

void scan_all_sensor()
{
unsigned char i,j,c;
unsigned char tag_old,tag_new;
bit scan_over,b;
unsigned char temp_sensor_addr;

sensor_count=0;
scan_over=0;
tag_old=0;
for(;scan_over==0;)
{
   tag_new=0;
   //scan_start
   if(ds1820_init()==0) return;
   ds1820_wr(0xf0);            /* 搜索rom命令 */
   for (i=1;i<=64;i++)
   {
       //get c
       c=0;
       ds_1wire=0;
       j=j>>1;                     //delay 4.3us
       ds_1wire=1;
       if(ds_1wire==1) c|=0x02;
       for(j=0;j<6;j++);         //delay 51us
       ds_1wire=0;
       j=j>>1;                     //delay 4.3us
       ds_1wire=1;
       if(ds_1wire==1) c|=0x01;
       for(j=0;j<6;j++);         //delay 51us
       switch (c)
       {
       case 0x00:                /* 此位冲突 */
            if(i<tag_old)      /*未到达标TAG_OLD,向TAG_OLD走,如果是向左则标记新的TAG_NEW*/
            {
            if ((temp_sensor_addr[(i-1)>>3] & 0x01) == 0x00) {b=0;tag_new=i;} else b=1;
            }
            if(i==tag_old) b=1;/*到达TAG_OLD,固定向右走*/
            if(i>tag_old)      /*超过TAG_OLD,先选择向左走出,标记新的TAG_NEW */
            {
            b=0;
            tag_new=i;
            }
            break;
       case 0x01:                /* 此位为0 */
            b=0;
            break;
       case 0x02:                /* 此位为1 */
            b=1;
            break;
       case 0x03:                /* 无传感器 */
            scan_over=1;
            i=64;
            break;
       default: break;
       }
       temp_sensor_addr[(i-1)>>3]=temp_sensor_addr[(i-1)>>3] >> 1;
       if (b==1) temp_sensor_addr[(i-1)>>3] |= 0x80;
       //out bit b
       ds_1wire=0;
       j=j>>1;            //delay 4.3us
       ds_1wire=b;
       for(j=0;j<6;j++);    //delay 59us
       ds_1wire=1;
   }
   tag_old=tag_new;
   //reord sensor addr
   if (sensor_count<=7)
       for(j=0;j<8;j++) snn=temp_sensor_addr;
   sensor_count++;
   if (tag_new==0) scan_over=1;
}
}

javinekuang 发表于 2012-4-26 14:30:50

haohai 发表于 2012-4-20 15:57 static/image/common/back.gif
前面定义
uchar data RomCode=
后面这样用可以吗?      


还没好好的去看程序,大胆回复了。
WriteOneChar()函数的形参是个指针类型就OK啦...

excuse 发表于 2012-5-1 15:44:27

thanks for sharing

yxzt 发表于 2012-5-1 15:54:53

好贴,楼主是高手{:victory:}

PCA 发表于 2012-5-1 15:56:33

yxzt 发表于 2012-5-1 15:54 static/image/common/back.gif
好贴,楼主是高手

哪里哪里,还有很多要完善的

thisjoy 发表于 2012-5-4 15:37:24

单线总线啊,以前也搞过

zuceyige 发表于 2012-5-9 17:53:34

这个代码挺完整,而且象我这等菜鸟易读懂啊,谢谢楼主分享!

PCA 发表于 2012-5-9 18:33:16

zuceyige 发表于 2012-5-9 17:53 static/image/common/back.gif
这个代码挺完整,而且象我这等菜鸟易读懂啊,谢谢楼主分享!

因为我也是菜鸟啊,写程序比较老实,菜鸟和菜鸟好沟通啊{:smile:}

ljmddnok 发表于 2012-5-9 18:58:27

mark一下

xiaoyigechaos 发表于 2012-5-9 19:52:30

顶一个   

zhikai_wu 发表于 2012-5-9 20:15:43

这个好.收藏了

jetli 发表于 2012-6-19 09:33:30

cndavy 发表于 2012-4-26 13:58 static/image/common/back.gif
转帖一个动态的
uinttemp;
uchar snn;


问一下,你用的是stc89c还是at89、还是stc12c系列的mcu?这涉及到delay的调整,{:sweat:}

mcuprogram 发表于 2012-6-19 09:35:08

果断MARK                        

usartcodeed 发表于 2012-6-19 09:58:40

很好啊,学习了

gallle 发表于 2012-6-19 10:39:11

自动搜索是好,但是怎么与实际的传感器对应上是个问题

lookthesame 发表于 2012-6-19 10:44:42

学习了!

jetli 发表于 2012-6-19 10:57:14

gallle 发表于 2012-6-19 10:39 static/image/common/back.gif
自动搜索是好,但是怎么与实际的传感器对应上是个问题

自动搜索对于io少的情况、位置要求不必要的情况合适。

如果出现损坏的更换、是个麻烦。
{:sweat:}

Super_C 发表于 2012-6-19 12:23:34

MARK..!!

creativedream 发表于 2012-6-19 22:56:29

必须要顶!

zengdz 发表于 2012-6-28 21:12:01

那个无线的还不如做成无线传输温度到电脑终端

tonyone 发表于 2012-6-28 21:35:41

很好很强大

hys357202567 发表于 2012-6-28 22:27:20

同样是学生,咋个差别这么大呢{:cry:}

kiwiwang 发表于 2012-7-6 23:22:45

刚刚接触1-wire总线协议,不知道LZ对DS2431有没有研究

nongxiaoming 发表于 2012-7-6 23:24:36

呵呵,我老师叫我帮他出实习设计题目的时候我就出有这么一题,没用DS1302~

ts19891230 发表于 2012-7-7 08:23:24

顶起 顶起!!{:3_48:}

wtiechen1969 发表于 2012-7-10 10:27:17

多谢楼主分享,学习了

PCA 发表于 2012-7-22 19:52:52

kiwiwang 发表于 2012-7-6 23:22 static/image/common/back.gif
刚刚接触1-wire总线协议,不知道LZ对DS2431有没有研究

这个木有

yzhu 发表于 2012-7-22 21:18:07

请问楼主,有没有用于远程测温,有的话,距离是多元?有没有用总线窃电?

电子蔡鸟 发表于 2012-7-22 22:03:44

{:victory:}

jianchangd 发表于 2012-7-23 03:18:19

学习一下。

c475301174 发表于 2012-7-29 17:35:16

谢谢,正在学习

沉月归巢 发表于 2012-7-29 18:05:45

超赞!!!!

wkman 发表于 2012-8-3 19:21:54

本帖最后由 wkman 于 2012-8-3 19:25 编辑

转帖一个动态的
uinttemp;
uchar snn;


40楼的程序ok!{:handshake:}
用stc89c58、11。0592Mhz通过!
改了改测了10个ds18b20温度

chengtina 发表于 2012-8-4 14:33:10

这个强大哦,我先留一下

龙道行 发表于 2012-8-18 15:12:00

太牛啦{:lol:}

stely 发表于 2012-8-18 17:55:52

支持楼主分享

beijinggood2008 发表于 2012-8-18 22:59:55

还在学单个的,果断MARK先!

tonyone 发表于 2012-8-19 10:54:39

强大,代码好工整。没有12864,不然就可以测试下了

akion78 发表于 2012-8-23 22:22:25

这个不错,mark

hengjng_t 发表于 2012-8-29 11:54:22

顶一个!!

hclin 发表于 2012-8-30 13:31:18

good job !!!

hclin 发表于 2012-8-30 13:34:05

cndavy 发表于 2012-4-26 13:58 static/image/common/back.gif
转帖一个动态的
uinttemp;
uchar snn;


Your code is very good for me.
Thank you a lot !!!

KongQuan 发表于 2012-8-31 10:34:07

自动侦测的方法不错!

michael1517 发表于 2012-11-12 22:36:34

不错的资料

dongqihong 发表于 2012-11-13 15:22:08

多谢楼主分享

qiushui_007 发表于 2013-3-5 21:18:15

集中转换温度?

hamipeter 发表于 2013-3-5 21:39:55

不错支持下

咱厝人 发表于 2013-3-5 23:11:58

{:hug:}谢谢分享啊

pxq8410 发表于 2013-4-3 14:46:10


谢谢分享

Jmhh247 发表于 2013-4-3 17:33:04

强贴,留名。

yao2013lin 发表于 2013-4-29 07:52:57

mark{:handshake:}

wxty 发表于 2013-4-29 20:24:50

通过Id识别的方法,扫描一遍的话估计得数秒时间。楼主可以考虑通过并行总线同时操作多个传感器,一次即可查询所有通道温度!

HeP028 发表于 2013-4-30 15:28:10

里面有搜索。留名

l769109884 发表于 2013-4-30 17:31:21

哈哈,,不错,,,谢谢LZ分享,,收藏以后参考,,

clarkewayne 发表于 2013-5-7 15:12:38

强大。。。!!

喜羊羊 发表于 2013-5-8 15:14:22

经典,支持楼主!

jqbkl007 发表于 2013-6-2 16:55:37

感谢楼主   学习了

大米饭 发表于 2013-6-3 19:35:37

看着之前自己发的帖子,之前的号被举报,看着之前的精华贴,感概万千啊

sogalufei 发表于 2013-6-20 10:50:47

学习了。。。。。。

tam2907 发表于 2013-6-20 15:32:54

大家讲讲18B20优势有哪些,实际项目中有多少是用18B20的?

Andrewz 发表于 2013-6-28 15:35:59

太长了,肯定在哪里有用,我先顶一下.以后再看.
页: [1] 2
查看完整版本: 看不少网友说1-wire总线协议多点测温的,贴个自己写成功的