美文网首页
单片机小白学习之路(三十二.5)---温度计全部代码

单片机小白学习之路(三十二.5)---温度计全部代码

作者: 飞向深空 | 来源:发表于2018-10-12 21:33 被阅读0次

    温度计全部代码:


    ds18b20.c

    #include "ds18b20.h"
    
    void delay_1ms(uint y)  //输入1就 是延时1ms
    { 
        uint x;
        for( ; y>0; y--)
        {
            for(x=110; x>0; x--);
        }
    
    }
    
    
    void delay_10tus(uint t) //延时(t*10)us
    {
        do{
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();    
        }
        while(--t);  //当while里面的值有效,那么do里面的程序一直执行
    }
    
    
    uchar Ds18b20Init()  //ds18b20的初始化
    {
        uchar i;
        DSPORT = 0;
        delay_10tus(65); //延时约640us(实粗线)    
        DSPORT = 1; //单片机释放总线就是给其高电平
        delay_10tus(6); //延时是60us(细弧线)
        i=0;
        while(DSPORT)  //当总线是高电平时
        {
            delay_1ms(1);
            i++;
            if(i>5){
                return 0; //又等了5us DSPROT还是高电平则返回0表示初始化失败
            }
        }
        return 1; //DSPROT是低电平(虚粗线)表示初始化成功
    }
    
    void Ds18b20WriteByte(uchar dat) //单片机向ds18b20输入一字节数据
    {
    
        uint i,j;
        for(j=0;j<8;j++){
            DSPORT = 0;
            _nop_();
            _nop_();       //写入1时最少1us所以直接延时2us
            DSPORT = dat&0x01;   //判断数值最后一位是0还是1
            i=6;
            while(i--);
            delay_10tus(6); //延时60us************************************************
            DSPORT = 1;     //释放总线,至少1us给总线恢复时间才能接着写入第二个数值
            dat >>= 1;      //数值向右移一位为下次判断最后一位是0还是1做准备
        }
    }
    
    uchar Ds18b20ReadByte() //单片机读取ds18b20的数据
    {
        uchar byte,bi;
        uint i,j;
        for(j=0;j<8;j++){
            DSPORT = 0;     //先拉低总线
            _nop_();
            _nop_();        //延时2us
            DSPORT = 1;     //释放总线
            _nop_();
            _nop_();; //延时2us等待数据稳定
            bi = DSPORT;    //读取数据,从最低位开始读取
            byte = (byte>>1) | (bi<<7);
            i=4;
            while(i--);
            delay_10tus(5);  //读取完之后等待60us再接着读取下一个数
        }
        return byte;            
    }
    
    void Ds18b20ChangeTemp()  //发送读取温度命令--转换
    {
        Ds18b20Init();  //18b20初始化
        delay_1ms(1);
        Ds18b20WriteByte(0xcc); //跳过ROM操作命令
        Ds18b20WriteByte(0x44); //发送读取温度的转换命令
        //Delay1ms(100);    //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
    }
    
    void Ds18b20ReadTempCom()  //发送读取温度命令--发送读取温度指令
    {
        Ds18b20Init();
        delay_1ms(1);
        Ds18b20WriteByte(0xcc);  //跳过ROM操作命令
        Ds18b20WriteByte(0xbe);  //发送读取温度的读取存储器命令
    }
    
    int Ds18b20ReadTemp()   //读取温度
    {
        int temp = 0;    //int类型占2个字节,共16位
        uchar tmh,tml;
        Ds18b20ChangeTemp();      //先写入转换命令
        Ds18b20ReadTempCom();  //然后等待转换完成后发送读取温度命令
        tml = Ds18b20ReadByte();//先读出低字节
        tmh = Ds18b20ReadByte();//再读出高字节
        temp = tmh;
        temp <<= 8;   //相当于在低8位的温度高8位向左移8位到正确位置
        temp |= tml;   //再把tml放到低8位储存
        return temp;
    
    }
    
    

    ds18b20.h

    #ifndef _ds18b20_H_
    #define _ds18b20_H_
    
    #include<reg52.h>
    #include<intrins.h>
    
    #ifndef uchar
    #define uchar unsigned char
    #endif
    
    #ifndef uint 
    #define uint unsigned int
    #endif
    
    
    sbit DSPORT = P3^7;
    
    void delay_1ms(uint );
    void delay_10tus(uint );
    uchar Ds18b20Init();
    void Ds18b20WriteByte(uchar );
    uchar Ds18b20ReadByte();
    void Ds18b20ChangeTemp();
    void Ds18b20ReadTempCom();
    int Ds18b20ReadTemp();
    
    #endif
    

    main.c

    /*
    实现现象:下载程序后,在DS18B20温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示
                检测的温度值,
    注意事项:将LED点阵模块的J1短接片短接到VCC端          
    */
    
    #include "reg52.h"
    #include "ds18b20.h"
    
    typedef unsigned int u16;
    typedef unsigned char u8;
    
    sbit LSA = P3^0;
    sbit LSB = P3^1;
    sbit LSC = P3^3;
    
    char num = 0;
    u8 DisplayData[8];
    u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    
    
    void delay(u16 i)
    {
        while(i--);
    }
    
    void datapros(int temp)
    {
        float tp;
        if(temp<0){
            DisplayData[0] = 0x40;  //数码管显示一个‘-’来表示负号
            temp = temp-1;  //因为读取的温度是实际温度的补码,而又是负数所以原码是补码减1然后取反
            temp = ~temp;  //得到实际温度
            tp = temp;
            temp = tp*0.0625*100+0.5;  //由于temp是整形所以当小数赋给temp时会把小数点后面的数字去掉,
                                    //为了不让小数部分去掉我们乘100把小数变成整数
        }
        else{
            DisplayData[0] = 0x00;
            tp = temp;
            temp = tp*0.0625*100+0.5;   
        }
        DisplayData[1] = smgduan[temp/10000];  //取出5位数的最高位
        DisplayData[2] = smgduan[temp%10000/1000];   //取出次高位
        DisplayData[3] = smgduan[temp%1000/100] | 0x80; //取出一位并加上个小数点
        DisplayData[4] = smgduan[temp%100/10];
        DisplayData[5] = smgduan[temp%10];     //最低位
    }
    
    void DigDisplay()
    {
        u8 i;
        for(i=0;i<6;i++){
            switch(i)    //位选,选择点亮的数码管,
            {
                case(0):
                    LSA=0;LSB=0;LSC=0; break;//显示第0位
                case(1):
                    LSA=1;LSB=0;LSC=0; break;//显示第1位
                case(2):
                    LSA=0;LSB=1;LSC=0; break;//显示第2位
                case(3):
                    LSA=1;LSB=1;LSC=0; break;//显示第3位
                case(4):
                    LSA=0;LSB=0;LSC=1; break;//显示第4位
                case(5):
                    LSA=1;LSB=0;LSC=1; break;//显示第5位    
            }
            P0 = DisplayData[i];  //向数码管发送数据
            delay(100);//间隔一段时间扫描
            P0 = 0x00;
        }
    }
    
    void main()
    {
        while(1){
            datapros(Ds18b20ReadTemp()); //数据处理函数
            DigDisplay();    //数码管显示函数
        }
    }
    

    相关文章

      网友评论

          本文标题:单片机小白学习之路(三十二.5)---温度计全部代码

          本文链接:https://www.haomeiwen.com/subject/mogbaftx.html