• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

51单片机DS18B20温度传感器使用和数码管温度计、LCD1602温度显示代码

武飞扬头像
小小_扫地僧
帮助1

温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读中文手册,并且对照代码注释充分分析代码。请不要觉得中文手册内容繁多!如能静心分析,定能深有体会,获益匪浅!

一、DS18B20中文手册(节选)

学新通
学新通
学新通
学新通
主函数操作顺序(执行序列)
学新通
学新通
学新通

功能指令

学新通
学新通
学新通
学新通
学新通
学新通
学新通

数码管温度计详解代码如下:

  1.  
    #include <reg52.h>
  2.  
    #include <intrins.h>
  3.  
    #define MAIN_Fosc 11059200UL //宏定义主时钟HZ
  4.  
    /*====================================
  5.  
    自定义类型名
  6.  
    ====================================*/
  7.  
    typedef unsigned char INT8U;
  8.  
    typedef unsigned char uchar;
  9.  
     
  10.  
    typedef unsigned int INT16U;
  11.  
    typedef unsigned int uint;
  12.  
     
  13.  
    /*====================================
  14.  
    硬件接口位声明
  15.  
    ====================================*/
  16.  
    sbit DS = P2^2; //DS18B20单总线
  17.  
    sbit DU = P2^6; //数码管段选
  18.  
    sbit WE = P2^7; //数码管位选
  19.  
    /*====================================
  20.  
    共阴极数码管段选码
  21.  
    ====================================*/
  22.  
    uchar code table[]={
  23.  
    //0 1 2 3 4 5 6 7 8
  24.  
    0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
  25.  
    //9 A B C D E F - . 关显示
  26.  
    0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
  27.  
    };
  28.  
     
  29.  
    /*====================================
  30.  
    数码管位选码
  31.  
    ====================================*/
  32.  
    //第1位 2位 3位 4位 5位 6位 7位 8位
  33.  
    uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
  34.  
     
  35.  
    /*====================================
  36.  
    函数:void Delay_Ms(INT16U ms)
  37.  
    参数:ms,毫秒延时形参
  38.  
    描述:12T 51单片机自适应主时钟毫秒级延时函数
  39.  
    ====================================*/
  40.  
    void Delay_Ms(INT16U ms)
  41.  
    {
  42.  
    INT16U i;
  43.  
    do{
  44.  
    i = MAIN_Fosc / 96000;
  45.  
    while(--i); //96T per loop
  46.  
    }while(--ms);
  47.  
    }
  48.  
    /*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/
  49.  
    void Delay_us(uchar us)
  50.  
    {
  51.  
    while(us--);
  52.  
    }
  53.  
    /*====================================
  54.  
    函数:void Display(INT16U Value)
  55.  
    参数:Value,显示值 取值0-65535
  56.  
    描述:共阴极数码管显示函数可显示一个字节的数
  57.  
    ====================================*/
  58.  
    void Display(INT16U Value) //注意由于需要显示的数大于一个字节所有形参需为int型
  59.  
    {
  60.  
    //------------------------------
  61.  
    DU = 0; //关闭段选
  62.  
    P0 = table[Value/100]; //数码管显示百位
  63.  
    DU = 1; //打开段选
  64.  
    DU = 0; //关闭段选
  65.  
     
  66.  
    WE = 0; //关闭位选
  67.  
    P0 = T_COM[0]; //第一位数码管
  68.  
    WE = 1; //打开位选
  69.  
    WE = 0; //关闭位选
  70.  
    Delay_Ms(3);
  71.  
    //-------------------------------
  72.  
    DU = 0;
  73.  
    P0 = table[Value%100/10]|0x80; //显示十位
  74.  
    DU = 1;
  75.  
    DU = 0;
  76.  
     
  77.  
    WE = 0;
  78.  
    P0 = T_COM[1]; //第二位数码管
  79.  
    WE = 1;
  80.  
    WE = 0;
  81.  
    Delay_Ms(3);
  82.  
    //-------------------------------
  83.  
    DU = 0;
  84.  
    P0 = table[Value%10]; //显示个位
  85.  
    DU = 1;
  86.  
    DU = 0;
  87.  
     
  88.  
    WE = 0;
  89.  
    P0 = T_COM[2]; //第三位数码管
  90.  
    WE = 1;
  91.  
    WE = 0;
  92.  
    Delay_Ms(3);
  93.  
    }
  94.  
    /*单总线初始化时序*/
  95.  
    /*出始化时序里包含了复位DS18B20和接收DS18B20返回的存在信号*/
  96.  
    bit ds_init()
  97.  
    {
  98.  
    bit i;
  99.  
    DS = 1;
  100.  
    _nop_();
  101.  
    DS = 0;
  102.  
    Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
  103.  
    DS = 1; //释放总线(检测到上升沿)
  104.  
    Delay_us(4); //延时37.95us 等待18B20发回存在信号(存在脉冲)
  105.  
    i = DS;
  106.  
    Delay_us(20); //141.95us
  107.  
    DS = 1;
  108.  
    _nop_();
  109.  
    return (i); //返回一个存在信号
  110.  
    }
  111.  
    /*写一个字节*/
  112.  
    void write_byte(uchar dat)
  113.  
    {
  114.  
    uchar i;
  115.  
    for(i=0;i<8;i )
  116.  
    {
  117.  
    DS = 0;
  118.  
    _nop_();//产生些时序
  119.  
    DS = dat & 0x01; //0000 0001
  120.  
    Delay_us(10);//76.95us
  121.  
    DS = 1; //释放总线准备下一次数据写入
  122.  
    _nop_();
  123.  
    dat >>= 1;
  124.  
    }
  125.  
    }
  126.  
     
  127.  
    uchar read_byte()
  128.  
    {
  129.  
    uchar i, j, dat;
  130.  
    for(i=0;i<8;i )
  131.  
    {
  132.  
    DS = 0;
  133.  
    _nop_();//产生读时序 1us,延时一个指令周期,空指令
  134.  
    DS = 1; //释放总线
  135.  
    _nop_(); //延时时间可以通过单步调试来计算
  136.  
    j = DS;
  137.  
    Delay_us(10);//76.95us
  138.  
    DS = 1;
  139.  
    _nop_();
  140.  
    dat = (j<<7)|(dat>>1);
  141.  
    }
  142.  
    return (dat);
  143.  
    }
  144.  
    void main()
  145.  
    {
  146.  
    uint i;
  147.  
    uchar L, M;
  148.  
    while(1)
  149.  
    {
  150.  
    ds_init();//初始化DS18B20
  151.  
    write_byte(0xcc);//发送跳跃ROM指令
  152.  
    write_byte(0x44);//发送温度转换指令
  153.  
    ds_init();//初始化DS18B20
  154.  
    write_byte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,
  155.  
    //忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)
  156.  
    write_byte(0xbe);//读取DS18B20暂存器值,读取将从字节0开始,一直进行下去,直到第9字节(字节8,CRC)读完
  157.  
    L = read_byte();//总线控制器在发出温度转换指令之后进行读时序
  158.  
    M = read_byte();//总线控制器在发出温度转换指令之后进行读时序
  159.  
    i = M; //高速暂存器(共8位),详见中文手册
  160.  
    i <<= 8; //将最低位移至高位
  161.  
    i |= L;
  162.  
    i = i * 0.0625 * 10 0.5;
  163.  
    Display(i);
  164.  
    }
  165.  
    }
学新通
学新通

LCD1602温度显示

  1.  
    #include <reg52.H>
  2.  
    #include <intrins.H>
  3.  
    #include <math.H>
  4.  
     
  5.  
    #define uchar unsigned char
  6.  
    #define uint unsigned int
  7.  
    sbit dula = P2^6;//数码管段选
  8.  
    sbit wela = P2^7;//数码管位选
  9.  
    sbit rw = P3^6; //LCD1602读/写选择端
  10.  
    sbit RS = P3^5;//LCD1602数据/命令选择端
  11.  
     
  12.  
    sbit LCDEN = P3^4; //LCD1602使能端
  13.  
     
  14.  
    void delayUs()
  15.  
    {
  16.  
    _nop_(); //空指令,延时一个指令周期
  17.  
    }
  18.  
     
  19.  
    void delayMs(uint a)
  20.  
    {
  21.  
    uint i, j;
  22.  
    for(i = a; i > 0; i--)
  23.  
    for(j = 100; j > 0; j--);
  24.  
    }
  25.  
     
  26.  
     
  27.  
    void writeComm(uchar comm) //写指令
  28.  
    {
  29.  
    RS = 0;
  30.  
    P0 = comm;
  31.  
    LCDEN = 1;
  32.  
    delayUs();
  33.  
    LCDEN = 0;
  34.  
    delayMs(1);
  35.  
    }
  36.  
     
  37.  
    //写数据:RS=1, RW=0;
  38.  
    void writeData(uchar dat)
  39.  
    {
  40.  
    RS = 1;
  41.  
    P0 = dat;
  42.  
    LCDEN = 1;
  43.  
    delayUs();
  44.  
    LCDEN = 0;
  45.  
    delayMs(1);
  46.  
    }
  47.  
     
  48.  
     
  49.  
    void init() //LCD1602初始化函数
  50.  
    {
  51.  
    rw = 0; //LCD1602读/写选择端
  52.  
    dula = wela = 0;
  53.  
    writeComm(0x38);//LCD1602显示设置
  54.  
    writeComm(0x0c);//开显示
  55.  
    writeComm(0x06);//当读或写一个字符后地址指针加一,且光标加一
  56.  
    writeComm(0x01);//清屏指令
  57.  
    }
  58.  
     
  59.  
    void writeString(uchar * str, uchar length)//LCD1602写字符串
  60.  
    {
  61.  
    uchar i;
  62.  
    for(i = 0; i < length; i )
  63.  
    {
  64.  
    writeData(str[i]);
  65.  
    }
  66.  
    }
  67.  
     
  68.  
    /**//*****************************DS18B20*******************************/
  69.  
     
  70.  
    /*温馨提示:读者若要彻底理解并会灵活使用DS18B20温度传感器,请详细阅读
  71.  
    中文手册,并且对照代码注释充分分析代码。如能静心分析,定能深有体会,获
  72.  
    益匪浅!*/
  73.  
    sbit ds = P2^2;
  74.  
    void dsInit()//初始化,详见中文手册
  75.  
    {
  76.  
     
  77.  
    unsigned int i;
  78.  
    ds = 0;
  79.  
    i = 100;
  80.  
    while(i>0) i--; //用于延时(严格按照时序来写)
  81.  
    ds = 1;
  82.  
    i = 4;
  83.  
    while(i>0) i--;
  84.  
    }
  85.  
     
  86.  
    void dsWait()//等待信号
  87.  
    {
  88.  
    unsigned int i;
  89.  
    while(ds);
  90.  
    while(~ds);
  91.  
    i = 4;
  92.  
    while(i > 0) i--;
  93.  
    }
  94.  
     
  95.  
     
  96.  
    bit readBit()//读一个bit位,一节数据共8个bit位,故后面会连续读到8次来实现读一个字节的数据
  97.  
    {
  98.  
    unsigned int i;
  99.  
    bit b;
  100.  
    ds = 0;
  101.  
    i ;
  102.  
    ds = 1;
  103.  
    i ; i ;
  104.  
    b = ds;
  105.  
    i = 8;
  106.  
    while(i>0) i--;
  107.  
    return b;//返回数据
  108.  
    }
  109.  
     
  110.  
    unsigned char readByte() //读一个字节的数据
  111.  
    {
  112.  
    unsigned int i;
  113.  
    unsigned char j, dat;
  114.  
    dat = 0;
  115.  
    for(i=0; i<8; i )//每一次读一位,一节数据共8位,读8次
  116.  
    {
  117.  
    j = readBit();
  118.  
     
  119.  
    dat = (j << 7) | (dat >> 1);
  120.  
    }
  121.  
    return dat;
  122.  
    }
  123.  
     
  124.  
     
  125.  
    void writeByte(unsigned char dat)//写一节数据
  126.  
    {
  127.  
    unsigned int i;
  128.  
    unsigned char j;
  129.  
    bit b;
  130.  
    for(j = 0; j < 8; j )//每次写一位,写8次
  131.  
    {
  132.  
    b = dat & 0x01;//取最低位,从最低位泄气
  133.  
    dat >>= 1; //右移一位
  134.  
    if(b)
  135.  
    {
  136.  
    ds = 0;
  137.  
    i ; i ;//延时以产生时序
  138.  
    ds = 1;
  139.  
    i = 8;
  140.  
    while(i>0) i--; //延时以产生时序
  141.  
    }
  142.  
    else
  143.  
    {
  144.  
    ds = 0;
  145.  
    i = 8;
  146.  
    while(i>0) i--;//延时以产生时序
  147.  
    ds = 1;
  148.  
    i ; i ;//延时以产生时序
  149.  
    }
  150.  
    }
  151.  
    }
  152.  
     
  153.  
     
  154.  
    void sendChangeCmd()//发送指令
  155.  
    {
  156.  
    dsInit();
  157.  
    dsWait();
  158.  
    delayMs(1);
  159.  
    writeByte(0xcc);//发送跳跃ROM指令(注意:当只有一只从机在总线上时,无论如何,
  160.  
    //忽略ROM指令之后只能跟着发出一条暂存器指令【BEh】)
  161.  
    writeByte(0x44);//发送温度转换指令
  162.  
    }
  163.  
     
  164.  
    void sendReadCmd()//读操作
  165.  
    {
  166.  
    dsInit();
  167.  
    dsWait();
  168.  
    delayMs(1);
  169.  
    writeByte(0xcc);//发送跳跃ROM指令
  170.  
    writeByte(0xbe);//发送温度转换指令
  171.  
    }
  172.  
     
  173.  
     
  174.  
    int getTmpValue() //获取温度值
  175.  
    {
  176.  
    unsigned int tmpvalue;
  177.  
    int value;
  178.  
    float t;
  179.  
    unsigned char low, high;
  180.  
    sendReadCmd();
  181.  
     
  182.  
    low = readByte();
  183.  
    high = readByte();
  184.  
     
  185.  
    tmpvalue = high;
  186.  
    tmpvalue <<= 8;
  187.  
    tmpvalue |= low;
  188.  
    value = tmpvalue;
  189.  
     
  190.  
    t = value * 0.0625;
  191.  
     
  192.  
    value = t * 100 (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
  193.  
    return value;
  194.  
    }
  195.  
     
  196.  
    void display(int v) //LCD1602显示内容设置
  197.  
    {
  198.  
    unsigned char count;
  199.  
    unsigned char datas[] = {0, 0, 0, 0, 0};
  200.  
    unsigned int tmp = abs(v);
  201.  
    datas[0] = tmp / 10000;
  202.  
    datas[1] = tmp % 10000 / 1000;
  203.  
    datas[2] = tmp % 1000 / 100;
  204.  
    datas[3] = tmp % 100 / 10;
  205.  
    datas[4] = tmp % 10;
  206.  
    writeComm(0xc0 3);
  207.  
    if(v < 0)
  208.  
    {
  209.  
    writeString("- ", 2);
  210.  
    }
  211.  
    else
  212.  
    {
  213.  
    writeString(" ", 2);
  214.  
    }
  215.  
    if(datas[0] != 0)
  216.  
    {
  217.  
    writeData('0' datas[0]);
  218.  
    }
  219.  
    for(count = 1; count != 5; count )
  220.  
    {
  221.  
    writeData('0' datas[count]);
  222.  
    if(count == 2)
  223.  
    {
  224.  
    writeData('.');
  225.  
    }
  226.  
    }
  227.  
    }
  228.  
    /**//*****************************DS18B20*******************************/
  229.  
     
  230.  
    void main()
  231.  
    {
  232.  
    uchar table[] = " xianzaiwendu: ";
  233.  
    sendChangeCmd();
  234.  
    init();
  235.  
    writeComm(0x80);
  236.  
    writeString(table, 16);//发送" xianzaiwendu: "
  237.  
    while(1)
  238.  
    {
  239.  
    delayMs(1000); //温度转换时间需要750ms以上
  240.  
    writeComm(0xc0);
  241.  
    display(getTmpValue());//通过LCD1602显示温度转换值
  242.  
    sendChangeCmd();//发送转换指令
  243.  
    }
  244.  
    }
学新通
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggghhi
系列文章
更多 icon
同类精品
更多 icon
继续加载