STM8L 温度传感器DS18B20
2017-11-27 11:14
357 查看
#define DS18B20_GPIO_PORT (GPIOC)
#define DS18B20_GPIO_PIN (GPIO_Pin_2)
#define DS18B20_PIN_SET_OUT() GPIO_Init(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN, GPIO_Mode_Out_PP_High_Fast)
#define DS18B20_PIN_SET_IN() GPIO_Init(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN, GPIO_Mode_In_PU_No_IT)
#define DS18B20_WR1() GPIO_SetBits(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
#define DS18B20_WR0() GPIO_ResetBits(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
#define R_DS18B20() GPIO_ReadInputDataBit(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
/* Private macro -------------------------------------------------------------*/
#define READ_ROM 0x33 //读取序列号
#define SKIP_ROM 0xCC //跳过ROM
#define MATCH_ROM 0x55 //匹配ROM
#define CONVERT_TEM 0x44 //转换温度
#define READ_RAM 0xBE //读暂存器
#define WRITE_RAM 0x4E //写暂存器
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void _delay_us(uint16_t nCount)
{
nCount *= 3;
while(--nCount);
}
/**
* @brief _delay_ms
* @param nCount
* @retval None
*/
void _delay_ms(uint16_t nCount)
{
while(nCount--)
{
_delay_us(1000);
}
}
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
void Alarm_for_No_DS18B20(void)
{
//单总线上没有发现DS18B20则报警,该动作据具体应用具体处理
}
//---------------------------------------------------------------------
unsigned char DS18B20_Start(void) //复位ds18b20芯片
{
unsigned char i,succ=0xff;
DS18B20_PIN_SET_OUT(); //置为输出口
DS18B20_WR0(); //总线产生下降沿,初始化开始
for(i=0; i<30; i++)_delay_us(25); //总线保持低电平在480 - 960微秒之间 ;i<20;(25us)
DS18B20_WR1(); //总线拉高
DS18B20_PIN_SET_IN(); //置为输入,主机释放总线,准备接收DS18B20的应答脉冲
i=0;
while(R_DS18B20()) //等待DS18B20发出应答脉冲
{
_delay_us(5); //5
if(++i>12) //DS18B20检测到总线上升沿后等待15-60us
{
succ=0x00; //如果等待大于约60us,报告复位失败
break;
}
}
i=0;
while(!R_DS18B20()) //DS18B20发出存在脉冲,持续60-240us
{
_delay_us(5); //5
if(++i>48) //如果等带大于约240us,报告复位失败
{
succ=0x00;
break;
}
}
_delay_us(20);
return succ;
}
//---------------------------------------------------------------------
void DS18B20_SendU8(unsigned char d8)//向DS18B20写一字节函数
{
unsigned char i;
DS18B20_PIN_SET_OUT(); //置为输出口
for(i=0; i<8; i++)
{
DS18B20_WR0(); //总线拉低,启动“写时间片”
_delay_us(2); //大于1微妙
if(d8&0x01)DS18B20_WR1();
_delay_us (32); //延时至少60微秒,使写入有效
_delay_us (30);
DS18B20_WR1(); //总线拉高,释放总线,准备启动下一个“写时间片”
d8>>=1;
_delay_us (1);
}
DS18B20_PIN_SET_IN(); //主机释放总线
}
//---------------------------------------------------------------------
unsigned char DS18B20_ReadU8(void)//从DS18B20读1个字节函数
{
unsigned char i,d8;
for(i=0; i<8; i++)
{
d8>>=1;
DS18B20_PIN_SET_OUT();//置为输出口
DS18B20_WR0(); //总线拉低,启动读“时间片”
_delay_us(2); //大于1微妙
DS18B20_WR1(); //主机释放总线,接下来(2~15)us内读有效
DS18B20_PIN_SET_IN(); //引脚设定为输入口,准备读取
_delay_us(2); //延时2个us后进行读
if(R_DS18B20())d8|=0x80;//从总线拉低时算起,约15微秒内读取总线数据
_delay_us(32); //60us后读完成
_delay_us(30);
DS18B20_WR1(); //总线拉高,主机释放总线,准备启动下一个“写时间片”
}
DS18B20_PIN_SET_IN(); //主机释放总线
return(d8);
}
//------------------------------------------------------------------------------------
void Init_DS18B20(void) //初始化DS18B20
{
unsigned char i;
i=DS18B20_Start(); //复位
if(!i) //单总线上没有发现DS18B20则报警
{
Alarm_for_No_DS18B20();
return;
}
DS18B20_SendU8 (SKIP_ROM); //跳过rom匹配
DS18B20_SendU8 (WRITE_RAM); //设置写模式
DS18B20_SendU8 (0x64); //设置温度上限100摄氏度
DS18B20_SendU8 (0x8a); //设置温度下线-10摄氏度
DS18B20_SendU8 (0x7f); //12bit(默认)
}
//--------------------------------------------------------------------------------------
unsigned int Read_DS18B20(void) //读取并计算要输出的温度
{
unsigned char i;
unsigned char tl;
unsigned int th;
i=DS18B20_Start(); //复位
if(!i) //单总线上没有发现DS18B20则报警
{
Alarm_for_No_DS18B20();
return 0;
}
_delay_ms(1);
DS18B20_SendU8(SKIP_ROM); //发跳过序列号检测命令
DS18B20_SendU8(CONVERT_TEM); //命令Ds18b20开始转换温度
i=0;
_delay_ms(1);
while(!R_DS18B20()) //当温度转换正在进行时,主机读总线将收到0,转换结束为1
{
_delay_ms(3);
if(++i>250) break; //至多转换时间为750ms
}
DS18B20_Start(); //初始化
_delay_ms(1);
DS18B20_SendU8(SKIP_ROM); //发跳过序列号检测命令
DS18B20_SendU8(READ_RAM); //发读取温度数据命令
tl=DS18B20_ReadU8(); //先读低8位温度数据
th=DS18B20_ReadU8()<<8; //再读高8位温度数据
return (th|tl)*10>>4; //温度放大了10倍,*0.0625=1/16=>>4
}
#define DS18B20_GPIO_PIN (GPIO_Pin_2)
#define DS18B20_PIN_SET_OUT() GPIO_Init(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN, GPIO_Mode_Out_PP_High_Fast)
#define DS18B20_PIN_SET_IN() GPIO_Init(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN, GPIO_Mode_In_PU_No_IT)
#define DS18B20_WR1() GPIO_SetBits(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
#define DS18B20_WR0() GPIO_ResetBits(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
#define R_DS18B20() GPIO_ReadInputDataBit(DS18B20_GPIO_PORT, (GPIO_Pin_TypeDef)DS18B20_GPIO_PIN)
/* Private macro -------------------------------------------------------------*/
#define READ_ROM 0x33 //读取序列号
#define SKIP_ROM 0xCC //跳过ROM
#define MATCH_ROM 0x55 //匹配ROM
#define CONVERT_TEM 0x44 //转换温度
#define READ_RAM 0xBE //读暂存器
#define WRITE_RAM 0x4E //写暂存器
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void _delay_us(uint16_t nCount)
{
nCount *= 3;
while(--nCount);
}
/**
* @brief _delay_ms
* @param nCount
* @retval None
*/
void _delay_ms(uint16_t nCount)
{
while(nCount--)
{
_delay_us(1000);
}
}
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
void Alarm_for_No_DS18B20(void)
{
//单总线上没有发现DS18B20则报警,该动作据具体应用具体处理
}
//---------------------------------------------------------------------
unsigned char DS18B20_Start(void) //复位ds18b20芯片
{
unsigned char i,succ=0xff;
DS18B20_PIN_SET_OUT(); //置为输出口
DS18B20_WR0(); //总线产生下降沿,初始化开始
for(i=0; i<30; i++)_delay_us(25); //总线保持低电平在480 - 960微秒之间 ;i<20;(25us)
DS18B20_WR1(); //总线拉高
DS18B20_PIN_SET_IN(); //置为输入,主机释放总线,准备接收DS18B20的应答脉冲
i=0;
while(R_DS18B20()) //等待DS18B20发出应答脉冲
{
_delay_us(5); //5
if(++i>12) //DS18B20检测到总线上升沿后等待15-60us
{
succ=0x00; //如果等待大于约60us,报告复位失败
break;
}
}
i=0;
while(!R_DS18B20()) //DS18B20发出存在脉冲,持续60-240us
{
_delay_us(5); //5
if(++i>48) //如果等带大于约240us,报告复位失败
{
succ=0x00;
break;
}
}
_delay_us(20);
return succ;
}
//---------------------------------------------------------------------
void DS18B20_SendU8(unsigned char d8)//向DS18B20写一字节函数
{
unsigned char i;
DS18B20_PIN_SET_OUT(); //置为输出口
for(i=0; i<8; i++)
{
DS18B20_WR0(); //总线拉低,启动“写时间片”
_delay_us(2); //大于1微妙
if(d8&0x01)DS18B20_WR1();
_delay_us (32); //延时至少60微秒,使写入有效
_delay_us (30);
DS18B20_WR1(); //总线拉高,释放总线,准备启动下一个“写时间片”
d8>>=1;
_delay_us (1);
}
DS18B20_PIN_SET_IN(); //主机释放总线
}
//---------------------------------------------------------------------
unsigned char DS18B20_ReadU8(void)//从DS18B20读1个字节函数
{
unsigned char i,d8;
for(i=0; i<8; i++)
{
d8>>=1;
DS18B20_PIN_SET_OUT();//置为输出口
DS18B20_WR0(); //总线拉低,启动读“时间片”
_delay_us(2); //大于1微妙
DS18B20_WR1(); //主机释放总线,接下来(2~15)us内读有效
DS18B20_PIN_SET_IN(); //引脚设定为输入口,准备读取
_delay_us(2); //延时2个us后进行读
if(R_DS18B20())d8|=0x80;//从总线拉低时算起,约15微秒内读取总线数据
_delay_us(32); //60us后读完成
_delay_us(30);
DS18B20_WR1(); //总线拉高,主机释放总线,准备启动下一个“写时间片”
}
DS18B20_PIN_SET_IN(); //主机释放总线
return(d8);
}
//------------------------------------------------------------------------------------
void Init_DS18B20(void) //初始化DS18B20
{
unsigned char i;
i=DS18B20_Start(); //复位
if(!i) //单总线上没有发现DS18B20则报警
{
Alarm_for_No_DS18B20();
return;
}
DS18B20_SendU8 (SKIP_ROM); //跳过rom匹配
DS18B20_SendU8 (WRITE_RAM); //设置写模式
DS18B20_SendU8 (0x64); //设置温度上限100摄氏度
DS18B20_SendU8 (0x8a); //设置温度下线-10摄氏度
DS18B20_SendU8 (0x7f); //12bit(默认)
}
//--------------------------------------------------------------------------------------
unsigned int Read_DS18B20(void) //读取并计算要输出的温度
{
unsigned char i;
unsigned char tl;
unsigned int th;
i=DS18B20_Start(); //复位
if(!i) //单总线上没有发现DS18B20则报警
{
Alarm_for_No_DS18B20();
return 0;
}
_delay_ms(1);
DS18B20_SendU8(SKIP_ROM); //发跳过序列号检测命令
DS18B20_SendU8(CONVERT_TEM); //命令Ds18b20开始转换温度
i=0;
_delay_ms(1);
while(!R_DS18B20()) //当温度转换正在进行时,主机读总线将收到0,转换结束为1
{
_delay_ms(3);
if(++i>250) break; //至多转换时间为750ms
}
DS18B20_Start(); //初始化
_delay_ms(1);
DS18B20_SendU8(SKIP_ROM); //发跳过序列号检测命令
DS18B20_SendU8(READ_RAM); //发读取温度数据命令
tl=DS18B20_ReadU8(); //先读低8位温度数据
th=DS18B20_ReadU8()<<8; //再读高8位温度数据
return (th|tl)*10>>4; //温度放大了10倍,*0.0625=1/16=>>4
}
相关文章推荐
- 总结:如何驱动DS18B20温度传感器
- 温度传感器--DS18B20的使用
- ds18b20温度传感器主程序
- S3C6410 DS18B20温度传感器驱动(四) --- 读取温度的应用程序
- 基于Linux的温度传感器DS18B20驱动程序设计
- ds18b20温度传感器应用实例
- stm8 ds18b20读温度代码
- 总结:如何驱动DS18B20温度传感器
- Dht11与Ds18b20温度传感器使用
- AVR单片机(ATmega16L)DS18B20温度传感器驱动程序
- DS18B20温度传感器测温显示在数码管上(29.9℃)
- tq2440连接到温度传感器DS18B20
- ds18b20温度传感器
- nodemcu 8266修改DS18B20温度传感器分辨率
- 温度传感器 DS18B20
- stm32 驱动DS18B20温度传感器
- 基于S3C2440的嵌入式Linux驱动——DS18B20温度传感器(添加使用platform总线机制)
- LPC213x ARM板子的DS18B20温度传感器模块添加
- 树莓派2代(RaspberryPi2)配合温度传感器DS18B20获取温度
- 51单片机(STC89C52)DS18B20温度传感器驱动程序