与DS18B20有关的代码:
DS18B20.c
/*==============================================================================
* File Name : DS18B20.c
* Author : Puppyh
* Version : V0.1
* Date : 10/15/2008
* Description :
==============================================================================*/
#include "stm32f10x_lib.h"
#include "ds18b20.h"
u8 Flag;
void us_Delay (u16 us)
{
while(us--);
}
void ms_Delay(u16 count) //延时子函数
{
u8 i;
while(count) {
i = 255;
while(i --);
count --;
}
}
/*==============================================================================
名称: DS18B20_Reset
输入:无
输出:Flag --- 指示线上是否有DS18B20存在。
描述:
发送一个复位脉冲(最少保持480μs的低电平信号),然后释放总线,MCU进入接收状态,DS1820
在探测到引脚上的上升沿后,延时15~60μs后,DS1820发出存在脉冲(60~240μs的低电平信号)。
==============================================================================*/
u8 DS18B20_Reset(void)
{
DS18B20_PIN = 1;
us_Delay(10);
DS18B20_PIN = 0;
us_Delay(3500); // 延时约480us,保持总线电平为低,总线上的器件将被复位。
DS18B20_PIN = 1; // 发送复位脉冲后,释放总线,让总线处于空闲状态
us_Delay(110); // 释放总线后,以便从机DS18B20通过拉低总线来指示其是否在线,存在检测高电平时间:15~60us,
us_Delay(110); // 两段延时是为了保证延时精确
if(DS18B20_PIN_IN == 0)
Flag = TRUE; // 检测到DS18B20
else
Flag = FALSE; // 未检测到DS18B20
us_Delay(1000); // 存在检测低电平时间:60~240us,延时约140us
DS18B20_PIN = 1; // 释放总线
return Flag;
}
/*==============================================================================
读/写时间隙:
DS1820 的数据读写是通过时间隙处理位和命令字来确认信息交换。
读一字节
==============================================================================*/
u8 DS18B20_Read_Byte(void )
{
u8 c_value, i;
u8 c_dat;
value = 0; // 设定初值为0
for(i = 0; i < 8; i ++) {
DS18B20_PIN = 0; // 将总线拉低
us_Delay(10); // 延时1us~
DS18B20_PIN = 1; // 拉低总线后再释放总线,让DS18B20能够控制总线,以便输出有效数据
us_Delay(80); // MCU延时一段时间,读取DS18B20的数据,因为从DS18b20上输出的数据在读"时间隙"下降沿出现15us内有效
c_dat = DS18B20_PIN_IN; // 主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效
c_value = (u16)c_dat << 7) | (c_value >> 1); //
us_Delay(333); // 所有读"时间隙"必须60us,这里56us
us_Delay(10); // 至少延时1us,才产生写"时间隙"
}
return value; // 返回一个字节的数据
}
/*==============================================================================
读/写时间隙:
DS1820 的数据读写是通过时间隙处理位和命令字来确认信息交换。
//写一个字节
==============================================================================*/
void DS18B20_Write_Byte(u8 cDat)
{
u8 i, one_bit;
for(i = 0; i < 8; i ++) {
one_bit = cDat & 0x01;
cDat = cDat >> 1;
DS18B20_PIN = 0;
if(one_bit) { //写 1
us_Delay(10); // 至少延时1us,才产生写"时间隙"
DS18B20_PIN = 1; // 写时间隙开始后的15μs内允许数据线拉到高电平
us_Delay(445); // 所有写时间隙必须最少持续60us
}
else { //写 0
us_Delay(460); // 必须把数据线拉到低电平并保持至少60μs,这里64us
}
DS18B20_PIN = 1;
us_Delay(10); // 至少延时1us,才产生写"时间隙"
}
}
/*==============================================================================
主机(单片机)控制18B20完成温度转换要经过三个步骤:
每一次读写之前都要18B20进行复位操作,复位成功后发送
一条ROM指令,最后发送RAM指令,这样才能对DS18b20进行
预定的操作。
复位要求主CPU将数据线下拉500us,然后释放,当DS18B20
受到信号后等待16~60us,后发出60~240us的存在低脉冲,
主CPU收到此信号表示复位成功
==============================================================================*/
/*==============================================================================
进行温度转换:
先初始化
然后跳过ROM:跳过64位ROM地址,直接向DS18B20发温度转换命令,适合单片工作
发送温度转换命令
==============================================================================*/
void Temperature_Convert(void)
{
DS18B20_Reset();
DS18B20_Write_Byte(0xCC);
DS18B20_Write_Byte(0x44);
}
/*==============================================================================
获得温度:
==============================================================================*/
u16 Get_Temperature(void)
{
u8 a, b;
u16 temp;
DS18B20_Reset();
DS18B20_Write_Byte(0xCC);
DS18B20_Write_Byte(0xBE);
a = DS18B20_Read_Byte();
b = DS18B20_Read_Byte();
temp = (u16)b << 8 | a;
return temp;
}
/*==============================================================================
读ROM
==============================================================================*/
u16 DS18B20_Read_ROM(void) // 这里没有用到
{
u8 a,b;
u16 temp;
DS18B20_Reset();
us_Delay(30);
DS18B20_Write_Byte(0x33);
a = DS18B20_Read_Byte();
b = DS18B20_Read_Byte();
temp = b;
temp <<= 8;
temp = temp | a;
return (u16)a << 8 | b;
}
/*==============================================================================
读ROM
==============================================================================*/
void Initialize_DS18B20(void)
{
u8 temp;
do {
Temperature_Convert();
ms_Delay(6180);
temp = Get_Temperature();
} while (temp == 85);
Temperature_Convert();
}
DS18B20.h
/*==============================================================================
* File Name : DS18B20.h
* Author : Puppyh
* Version : V0.1
* Date : 10/15/2008
* Description :
==============================================================================*/
#ifndef _DS18B20_H
#define _DS18B20_H
#define GPIOC_OFFSET (GPIOC_BASE - PERIPH_BASE) // GPIOC offset
#define GPIOC_ODR_OFFSET (GPIOC_OFFSET + 0x0C) // GPIOC ODR offset
#define GPIOC_IDR_OFFSET (GPIOC_OFFSET + 0x08) // GPIOC IDR offset
#define GPIOx_ODR_OFFSET GPIOC_ODR_OFFSET // GPIOC ODR offset
#define GPIOx_IDR_OFFSET GPIOC_IDR_OFFSET // GPIOC IDR offset
#define GPIOx_PIN 12
#define DS18B20_PIN *(vu32 *)(PERIPH_BB_BASE + (GPIOx_ODR_OFFSET * 32) + (GPIOx_PIN * 4)) // PC 12
#define DS18B20_PIN_IN *(vu32 *)(PERIPH_BB_BASE + (GPIOx_IDR_OFFSET * 32) + (GPIOx_PIN * 4)) // PC 12
#define NOP() asm("nop");
void us_Delay(u16 us);
void ms_Delay(u16 count); //延时子函数
u8 DS18B20_Reset(void);
u8 DS18B20_Read_Byte(void); //读一字节
void DS18B20_Write_Byte(u8 dat); //写一个字节
void Temperature_Convert(void);
u16 Get_Temperature(void);
u16 DS18B20_Read_ROM(void); //这里没有用到
void Initialize_DS18B20(void);
#endif
|