搜索
bottom↓
回复: 15

Maxim 1-Wire器件和DS18B20数字温度传感器操作示例 + 在AvrX下操作示例

[复制链接]

出0入0汤圆

发表于 2009-4-21 22:04:04 | 显示全部楼层 |阅读模式
以下是Maxim 1-Wire器件和DS18B20数字温度传感器操作示例:
/*
*  main.c : Demo prog & driver for Maxim 1-Wire device & DS18B20.
*  Copyright (C) 2009 Zhao Huabing
*  www.ursastudio.com.cn
*        History:        2009-03-10 Zhao Huabing created
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

#include <stdio.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "uart.h"

//1-Wire通信基本操作宏
//切换到写模式
#define OW_W_MODE() (DDRD |= _BV(PD3))
//切换到读模式
#define OW_R_MODE() (DDRD &= ~_BV(PD3))
#define OW_SET() (PORTD |= _BV(PD3))
#define OW_CLR() (PORTD &= ~_BV(PD3))
#define OW_STA() ((PIND & _BV(PD3))>>PD3)

//1-Wire通信标准速度时间常数
#define A 6
#define B 64
#define C 60
#define D 10
#define E 9
#define F 55
#define G 0
#define H 480
#define I 70
#define J 410

//1-Wire复位 没有检测到设备返回1否则返回0
uint8_t OWReset(void)
{
        uint8_t result;

        OW_W_MODE();
        _delay_us(G);
        OW_CLR();
        _delay_us(H);
        OW_SET();
        _delay_us(I);
        OW_R_MODE();
        result = OW_STA();
        _delay_us(J);
       
        return result;
}

//从1-Wire设备读一位
uint8_t OWReadBit(void)
{
        uint8_t result;
       
        OW_W_MODE();
        OW_CLR();
        _delay_us(A);
        OW_SET();
        _delay_us(E);
        OW_R_MODE();
        result = OW_STA();
        _delay_us(F);

        return result;
}

//从1-Wire设备读一个字节
uint8_t OWReadByte(void)
{
        uint8_t result = 0;

        for(uint8_t loop=0; loop<8; loop++)
        {
                result >>= 1;
                if (OWReadBit())
                        result |= 0x80;
        }
        return result;
}

//向1-Wire设备写一位
void OWWriteBit(uint8_t bit)
{
        OW_W_MODE();
        if (bit)
        {
                OW_CLR();
                _delay_us(A);
                OW_SET();
                _delay_us(B);
        }
        else
        {
                OW_CLR();
                _delay_us(C);
                OW_SET();
                _delay_us(D);       
        }
}

//向1-Wire设备写一个字节
void OWWriteByte(uint8_t data)
{
        for(uint8_t loop = 0; loop < 8; loop++)
        {
                OWWriteBit(data & 0x01);
                data >>= 1;
        }
}

//读取DS18B20温度
double TemperatureQuery(void)
{
        if(OWReset())                //总线复位
                return 0;
        OWWriteByte(0xCC);        //跳过ROM
        OWWriteByte(0x44);        //启动转换指令
       
        _delay_ms(750);                //等待12位最大转换时间
       
        if(OWReset())                //总线复位
                return 0;
        OWWriteByte(0xCC);        //跳过ROM
        OWWriteByte(0xBE);        //读数据指令
        uint8_t tempL= OWReadByte();        //读取低字节
        uint8_t tempH = OWReadByte();        //读取高字节

        //寄存器数据转化为摄氏温度
        return ((tempH>>3) ? -1 : 1) * ((0x7&tempH)<<8 | tempL) / 16.0;
}

int main(void)
{
        UartInit(19200);  //UART初始化
       
        //定义UART流文件
        FILE UartStream = FDEV_SETUP_STREAM(UartPutchar, UartGetchar, _FDEV_SETUP_RW);
        //绑定标准输入输出到流文件
        stdout = stdin = &UartStream;
       
        while(1)
        {
                //温度通过RS232发送到超级终端上
                printf_P(PSTR("Current temperature is: %8.4f\r\n"), TemperatureQuery());
                _delay_ms(1000);
        }
}

Makefile修改:
PRINTF_LIB = $(PRINTF_LIB_FLOAT)

部分参考Maxim公司网站资料“1-Wire&#174; Communication Through Software”,在以下附件中可以看到。
程序源码 ourdev_438571.zip(文件大小:45K) (原文件名:08-temp.zip)

以下是为了在AvrX下使用所做的部分修改,以防止在多任务环境下高优先级任务和中断对1-Wire通信的影响,并避免本函数执行时间过长对其他任务的阻塞。

#include "avrx.h"
//读取DS18B20温度
TimerControlBlock timer0;
double TemperatureQuery(void)
{
        BeginCritical();  //进入原子操作区域
        if(OWReset())  //总线复位
                return 0;
        OWWriteByte(0xCC);        //跳过ROM
        OWWriteByte(0x44);        //启动转换指令
        EndCritical();  //退出原子操作区域
       
        AvrXDelay(&timer0, 750);
        //_delay_ms(750);        //等待12位最大转换时间
       
        BeginCritical();  //进入原子操作区域
        if(OWReset())  //总线复位
                return 0;
        OWWriteByte(0xCC);        //跳过ROM
        OWWriteByte(0xBE);        //读数据指令
        uint8_t tempL= OWReadByte();        //读取低字节
        uint8_t tempH = OWReadByte();        //读取高字节
        EndCritical();  //退出原子操作区域

        //寄存器数据转化为摄氏温度
        return ((tempH>>3) ? -1 : 1) * ((0x7&tempH)<<8 | tempL) / 16.0;
}

出0入0汤圆

发表于 2009-4-21 22:42:43 | 显示全部楼层
DING!

出0入0汤圆

发表于 2009-4-21 22:44:34 | 显示全部楼层
DING

出0入0汤圆

发表于 2009-4-21 23:48:20 | 显示全部楼层
这个不顶不行!

出0入0汤圆

发表于 2009-4-22 09:16:01 | 显示全部楼层
BeginCritical();  关中断。
EndCritical(); 开中断。

出0入0汤圆

发表于 2009-4-22 09:59:21 | 显示全部楼层
谢谢

出0入0汤圆

 楼主| 发表于 2009-4-22 10:02:40 | 显示全部楼层
#define BeginCritical() asm volatile ("cli\n")  //关闭全局中断
#define EndCritical()    asm volatile ("sei\n")  //打开全局中断
在AvrX里是这样定义的,在别的操作系统中可能会有更合适的操作。

出0入0汤圆

发表于 2009-4-22 10:06:14 | 显示全部楼层
Size after:
AVR Memory Usage
----------------
Device: atmega16

Program:    5294 bytes (32.3% Full)
(.text + .data + .bootloader)

Data:          6 bytes (0.6% Full)
(.data + .bss + .noinit)


浮点库实在是太占用Flash啦.

出0入0汤圆

 楼主| 发表于 2009-4-22 10:39:21 | 显示全部楼层
在这里浮点库大概消耗1.5K的空间,这对16K空间来说也还好吧。
    如果Flash空间不是那么紧张的话,我想用用浮点库也无妨,毕竟它使程序简化不少,通常我会更加关注SRAM的消耗。

出0入0汤圆

发表于 2010-8-8 17:12:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-24 20:25:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-15 13:11:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-15 13:25:10 | 显示全部楼层
看到AvrX就进来了

出0入0汤圆

发表于 2011-1-15 17:57:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2020-5-22 17:09:06 | 显示全部楼层
顶一下,学习学习!

出0入147汤圆

发表于 2020-5-22 17:19:13 | 显示全部楼层
这千年古坟都被挖出来了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 15:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表