锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM8L 温度传感器DS18B20

时间:2022-08-03 17:19:00 sitemap stm8外接传感器

#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) //DS18B等待15-60,直到总线上升us
{
succ=0x00; /如果等待大于600us,报告复位失败
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
}

相关文章