打印
[AVR单片机]

AVR学习笔记七、基于DS18B20的温度测量实验

[复制链接]
4712|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tiankai001|  楼主 | 2008-12-4 15:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本实验包括3个例子,分别是:
    1、利用DS18B20实现简单的温度测量。在这个例子中主要是学习了DS18B20的基本操作时序,DS18B20的基本操作时序是十分严格的,如果不按照规定的时序操作,是读不出来数据的。而弄清了操作时序后,一切都会变得简单。
    2、利用寄生电源供电方式对DS18B20进行操作,不但实现了温度的读取,还实现了对DS18B20的RAM区的读写操作。利用寄生电源的优点在于可以不必给DS18B20单独配备电源,从而能够更好的实现远程测温。
    3、利用匹配指令实现多点测温。通过发送指定的DS18B20的ROM序列号,实现对连接的多个DS18B20中的一个进行读写。实现基本的多点测温试验。


相关链接:https://bbs.21ic.com/upfiles/img/200812/200812415237599.rar

相关帖子

沙发
linxiyiran| | 2008-12-5 06:18 | 只看该作者

顶一下

顶一下

使用特权

评论回复
板凳
smart_avr| | 2008-12-10 16:50 | 只看该作者

huifu

顶一下啊,学习了。时序不怎么十分明白啊!稍不对就读不出数据!!

使用特权

评论回复
地板
tiankai001|  楼主 | 2008-12-10 16:57 | 只看该作者

时序问题

这个时序要求是蛮严格的,不太好弄,我也费了好几天才弄出来的

使用特权

评论回复
5
myxj1984| | 2008-12-30 16:31 | 只看该作者

很好

顶啊,正在发愁呢,楼主做的不错,我看好你哦

使用特权

评论回复
6
风儿32600| | 2009-1-3 22:19 | 只看该作者

谢谢

好 啊
看看那

使用特权

评论回复
7
readlove1| | 2012-9-17 12:54 | 只看该作者
楼主大好人。支持。

使用特权

评论回复
8
1014603705| | 2012-9-21 12:03 | 只看该作者
这么慷慨,多谢!

使用特权

评论回复
9
zcchocolate| | 2012-9-23 09:03 | 只看该作者

使用特权

评论回复
10
shu_007| | 2012-11-4 21:11 | 只看该作者
请问是不是AVR GCC?

使用特权

评论回复
11
笑飞侠LFB| | 2013-7-10 16:25 | 只看该作者
我按照 你的程序用meg128写的   测不出来!
#include <avr/io.h>
#include<avr/interrupt.h>
#include <util/delay.h>
#include "LCD.h"
#define uchar unsigned char
#define uint unsigned int

uchar OK_Flag;

//××××××××××××引脚宏定义×××××××××××××
//18B20定义
#define SET_DQ (PORTA) |= (1 << (PA2))      // 18b20 高电平
#define CLR_DQ (PORTA) &=~(1 << (PA2))      // 18b20 低电平
#define DQ_IN  (PINA) & (1<<(PA2))            // 18b20信号输入

#define SET_OUT (DDRA)|= (1<<(PA2))         //PA2定义成输出
#define SET_IN  (DDRA)&=~(1<<(PA2))         //PA2定义成输入

uchar table[3]={0,0,0};


/**************************************/
void data_pro(uint temp)
{
uint a;
table[2] = temp/100;
a = temp%100;
table[1] = a/10;
table[0] = a%10;
}


//DS18B20初始化
unsigned char DS18B20_Init()
{       
        SET_OUT;   //PA2设置为输出口(相当于拉低数据线上的电平)       
        CLR_DQ;
        _delay_us(490);  //延时大于480us
       
        SET_IN;     //输入 释放数据线(相当于拉高数据线上的电平)
        SET_DQ;
        _delay_us(68);        //延时大于60US,
               
        //while(DQ_IN);            //可以用两个while()死循环来判断复位是否成功,当数据线被拉低,说明
        //while(!(DQ_IN));         //18b20开始复位应答,当数据线变高,说明应答完毕
       
        if(DQ_IN)   //判断DS18B20是否拉低数据线
        {
                OK_Flag = 0;                //        数据线是高?复位失败
        }
        else
        {
                OK_Flag = 1;        //        数据线是低?复位成功
        }
        _delay_us(422);        //有复位应答信号后,应当再延时一段时间(480-68),以等待应答完毕
       
        return OK_Flag;    //返回复位标志
}

//从DS18B20读取一个字节数据
unsigned char Read_18b20()
{
        unsigned char i;   
        unsigned char dat = 0;   // dat用于存储读到的数据,先清零       
       
        for(i = 0;i < 8;i++)   //共读8位数据,构成一个字节
        {               
                SET_OUT;    //定义为输出(拉低数据线)
                CLR_DQ;
                _delay_us(2);   //拉低2微秒               
               
                SET_IN;        //定义成输入,读入数据(同时也相当于拉高数据线)
                SET_DQ;       
                _delay_us(4);        //延时
                dat = dat >> 1;               //数据右移,读顺序:先低后高
                if(DQ_IN)       //读数据,
                {                       
                        dat |= 0x80;   //如果是高,置1,右移数据
                }
                _delay_us(62);                 //延时大于60us
        }       
        return dat;     //返回读到的1字节数据
}

//向DS18B20写1字节数据
void Write_18b20(unsigned char dat)
{
        unsigned char i;       
       
        for(i = 0;i < 8;i++)  //写8次,一次写1位,先写低字节
        {
                SET_OUT;         //拉低数据线2us,开始写数据
                CLR_DQ;
                _delay_us(2);      //
               
                if(dat & 0x01)   //写数据
                {
                        SET_IN;    //写1
                        SET_DQ;                       
                }
                else
                {
                        SET_OUT;   //写0
                        CLR_DQ;                       
                }
                dat >>= 1;      //数据右移1位,先写低位
                _delay_us(62);       //延时大于60us       
                       
                SET_IN;          //拉高数据线
                SET_DQ;
                _delay_us(2);   //写两位数据的时间间隔
               
        }       
}


/****************************************/
void main(void)
{
            uchar k;
                uchar i,j;
                uint temp;

               
                system_init();                            //系统初始化,设
                _delay_ms(100);                            //延时100ms
                LCD_init();                               //液晶参数初始化
                LCD_clear();



while(1)
{
  DS18B20_Init;
  Write_18b20(0xcc);
  Write_18b20(0x44);

  _delay_us(1000);
  
  DS18B20_Init;
  Write_18b20(0xcc);
  Write_18b20(0xbe);
  i = Read_18b20();//lsb
  j = Read_18b20();//msb
  temp = j*256 + i;  //26.8
  temp = temp*0.625;//268
  data_pro(temp);
  for(k=0; k<20; k++)
  {
          LCD_write_com(0xc6);
    LCD_write_data(table[2]+0x30);
          LCD_write_data(table[1]+0x30);
        LCD_write_data(table[0]+0x30);

   }
}
}

使用特权

评论回复
12
disguise21| | 2014-7-31 21:46 | 只看该作者
赞一个

使用特权

评论回复
13
gaojintao| | 2014-10-1 21:00 | 只看该作者
顶一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

72

帖子

2

粉丝