打印
[Kinetis]

DS18B20温度采集+串口发送

[复制链接]
1164|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ideafor|  楼主 | 2016-1-23 21:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
FSL官方KSDK固件库编译出的lib过大,因此采用超核的固件库实现DS18B20温度采集和串口发送,超核库的有许多便捷的设置函数,如delay函数、GPIO位带操作等。
首先是创建基于超核固件库的keil project,加入必要的*.c和*.h文件:

然后确定DS18B20的data引脚接口为PTC16,编写DS18B20的相关函数:

DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。
这几个信号的时序如下:
1)复位脉冲和应答脉冲
单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,若为低电平,再延时480us。
2)写时序
写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。
3)读时序
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
DS18B20的温度读取过程一般为:复位->发SKIPROM命令(0XCC)->发开始转换命令(0X44)->延时->复位->发送SKIPROM命令(0XCC)->发读存储器命令(0XBE)->连续读出两个字节数据(即温度)->结束。
主函数中代码如下,实现了温度读取和串口发送,LED闪烁以表明程序运行:

相关帖子

沙发
ideafor|  楼主 | 2016-1-23 21:35 | 只看该作者


程序运行结果如下:


使用特权

评论回复
板凳
ideafor|  楼主 | 2016-1-23 21:38 | 只看该作者
#include "ds18b20.h"

//复位DS18B20
void DS18B20_Rst(void)     
{                 
CLR_DS18B20();    //拉低DQ
DelayUs(750);    //拉低750us
SET_DS18B20();;   //DQ=1
DelayUs(15);     //15US
}


//等待DS18B20的回应
//返回1:未检测到ds18b20的存在
//返回0:存在
uint8_t DS18B20_Check(void)        
{   
uint8_t retry=0;

while (DS18B20_DQ_IN&&retry<200)
{
    retry++;
    DelayUs(1);
};   
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
    retry++;
    DelayUs(1);
};
if(retry>=240)return 1;     
return 0;
}


//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void)           // read one bit
{
uint8_t data;

CLR_DS18B20();   //拉低DQ
DelayUs(2);
SET_DS18B20();;  //DQ=1
DelayUs(12);
if(DS18B20_DQ_IN)data=1;
else data=0;   
DelayUs(50);  

return data;
}


//从ds18b20读取一个字节
//返回值:读取到的数据
uint8_t DS18B20_Read_Byte(void)    // read one byte
{        
uint8_t i,j,dat;
dat=0;

for (i=1;i<=8;i++)
{
    j=DS18B20_Read_Bit();
    dat=(j<<7)|(dat>>1);
}                           
return dat;
}


//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(uint8_t dat)     
{            
uint8_t j;
uint8_t testb;

for (j=1;j<=8;j++)
{
    testb=dat&0x01;
    dat=dat>>1;
    if (testb)
    {
        CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 1
        DelayUs(2);                           
        SET_DS18B20(); //DS18B20_DQ_OUT=1;
        DelayUs(60);            
    }
    else
    {
        CLR_DS18B20(); //DS18B20_DQ_OUT=0;// Write 0
        DelayUs(60);            
        SET_DS18B20(); //DS18B20_DQ_OUT=1;
        DelayUs(2);                          
    }
}
}


//开始温度转换
void DS18B20_Start(void)// ds1820 start convert
{                                          
DS18B20_Rst();     
  DS18B20_Check();   
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0x44);// convert
}


//初始化DS18B20的IO口DQ同时检查DS的存在
//返回1:不存在
//返回0:存在         
uint8_t DS18B20_Init(void)
{
//配置PC16口   
GPIO_QuickInit(HW_GPIOC, 16, kGPIO_Mode_OPP);

SET_DS18B20();         //使PA2输出高电平

DS18B20_Rst();
return DS18B20_Check();
}


//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
float DS18B20_Get_Temp(void)
{
    uint8_t temp;
    uint8_t TL,TH;
                int16_t tem;
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();         
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert            
    TL=DS18B20_Read_Byte(); // LSB   
    TH=DS18B20_Read_Byte(); // MSB  
                      
    if(TH>7)
    {
        TH=~TH;
        TL=~TL;
        temp=0;//温度为负  
    }else temp=1;//温度为正                    
    tem=TH; //获得高八位
    tem<<=8;   
    tem+=TL;//获得低八位
    tem=(float)tem*0.625;//转换     
        if(temp)return tem/10.00; //返回温度值
        else return -tem/10.00;   
}

使用特权

评论回复
地板
ideafor|  楼主 | 2016-1-23 21:39 | 只看该作者
#include "gpio.h"
#include "common.h"
#include "uart.h"
#include "ds18b20.h"

/* CH Kinetis固件库 V2.50 版本 */
/* 修改主频 请使用 CMSIS标准文件 system_MKxxxx.c 中的 CLOCK_SETUP 宏 */

/* UART 快速初始化结构所支持的引脚* 使用时还是推荐标准初始化 */
/*
UART1_RX_PE01_TX_PE00   
UART0_RX_PF17_TX_PF18   
UART3_RX_PE05_TX_PE04   
UART5_RX_PF19_TX_PF20   
UART5_RX_PE09_TX_PE08   
UART2_RX_PE17_TX_PE16   
UART4_RX_PE25_TX_PE24   
UART0_RX_PA01_TX_PA02   
UART0_RX_PA15_TX_PA14   
UART3_RX_PB10_TX_PB11   
UART0_RX_PB16_TX_PB17   
UART1_RX_PC03_TX_PC04   
UART4_RX_PC14_TX_PC15   
UART3_RX_PC16_TX_PC17   
UART2_RX_PD02_TX_PD03   
UART0_RX_PD06_TX_PD07   
UART2_RX_PF13_TX_PF14   
UART5_RX_PD08_TX_PD09   
*/


int main(void)
{
                float temp;
    DelayInit();
    /* 初始化一个引脚 设置为推挽输出 */
    GPIO_QuickInit(HW_GPIOE, 26, kGPIO_Mode_OPP);
    /* 初始化一个串口 使用UART0端口的PTD6引脚和PTD7引脚作为接收和发送,默认设置 baud 115200 */
    UART_QuickInit(UART0_RX_PB16_TX_PB17, 115200);
                printf("DS18B20 DEMO:\r\n");
                while(DS18B20_Init()){;}
    while(1)
    {
                temp=DS18B20_Get_Temp();
                printf("Temperate:%4.2f \r\n",temp);
    GPIO_ToggleBit(HW_GPIOE, 26);
    DelayMs(1000);
    }
}


使用特权

评论回复
5
ideafor|  楼主 | 2016-1-23 21:40 | 只看该作者
#ifndef __DS18B20_H
#define __DS18B20_H
#include "gpio.h"
#include "common.h"

#define CLR_DS18B20()   PCout(16)=0
#define SET_DS18B20()   PCout(16)=1
#define DS18B20_DQ_IN   PCin(16)

uint8_t DS18B20_Init(void);          //初始化DS18B20
float DS18B20_Get_Temp(void);   //获取温度
void DS18B20_Start(void);       //开始温度转换
void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
uint8_t DS18B20_Read_Byte(void);     //读出一个字节
uint8_t DS18B20_Read_Bit(void);      //读出一个位
uint8_t DS18B20_Check(void);         //检测是否存在DS18b20
void DS18B20_Rst(void);         //复位DS18B20   

#endif

使用特权

评论回复
6
MJM_WSY| | 2016-1-24 12:40 | 只看该作者
不错!好东西啊

使用特权

评论回复
7
ljqdsj| | 2016-1-24 17:23 | 只看该作者
谢谢分享啊

使用特权

评论回复
8
wg3613| | 2016-1-24 21:52 | 只看该作者
好资料,比较详细,最好被整个工程文件上传一下

使用特权

评论回复
9
64xiaodian| | 2016-1-25 00:29 | 只看该作者
赞一个:)

使用特权

评论回复
10
justinlin2015| | 2016-1-25 16:43 | 只看该作者

谢谢分享啊

使用特权

评论回复
11
Thethree| | 2016-1-25 20:25 | 只看该作者
DS18B20应该是I2C接口吧,那读取速率最快能达到多少呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

149

帖子

1

粉丝