Maxim 1-Wire器件和DS18B20数字温度传感器操作示例 + 在AvrX下操作示例
以下是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® 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;
} DING! DING 这个不顶不行! BeginCritical();关中断。
EndCritical(); 开中断。 谢谢 #define BeginCritical() asm volatile ("cli\n")//关闭全局中断
#define EndCritical() asm volatile ("sei\n")//打开全局中断
在AvrX里是这样定义的,在别的操作系统中可能会有更合适的操作。 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啦. 在这里浮点库大概消耗1.5K的空间,这对16K空间来说也还好吧。
如果Flash空间不是那么紧张的话,我想用用浮点库也无妨,毕竟它使程序简化不少,通常我会更加关注SRAM的消耗。 mark mark mark 看到AvrX就进来了 mark 顶一下,学习学习! 这千年古坟都被挖出来了
页:
[1]