打印

呀呀呀,这STC12C5A60S2用DS18B20测温在数码管显示,一直是-000.06

[复制链接]
4199|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
乌嘴猫|  楼主 | 2015-1-8 17:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 乌嘴猫 于 2015-1-8 17:03 编辑



#include <STC12C5A60S2.H>
#include<intrins.h>
//#include"temp.h"
#define uchar unsigned char
#define uint unsigned int
//--定义使用的IO--//
#define GPIO_DIG P0

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit DSPORT=P3^7;
//--定义全局变量
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char DisplayData[8];
//用来存放要显示的8位数的值

//--声明全局函数--//
void LcdDisplay(int);
void DigDisplay();
int Ds18b20ReadTemp();
void  Ds18b20ReadTempCom();
void  Ds18b20ChangTemp();
void Ds18b20WriteByte(uchar dat);
uchar Ds18b20ReadByte();
uchar Ds18b20Init();
void delay1ms(uint x);
void delay1us(volatile uchar n);
/*******************************************************************************
* 函 数 名         : main
* 函数功能                   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void main()
{
        while(1)
        {
                LcdDisplay(Ds18b20ReadTemp());
        }
}

/*******************************************************************************
* 函 数 名         : LcdDisplay()
* 函数功能                   : LCD显示读取到的温度
* 输    入         : v
* 输    出         : 无
*******************************************************************************/

void LcdDisplay(int temp)          //lcd显示
{
           float tp;  
        if(temp< 0)                                //当温度值为负数
          {
                DisplayData[0] = 0x40;
                //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;        
                //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
                //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
                //算由?.5,还是在小数点后面。

          }
         else
          {                        
                DisplayData[0] = 0x00;
                tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
                //如果温度是正的那么,那么正数的原码就是补码它本身
                temp=tp*0.0625*100+0.5;        
                //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
                //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
                //算加上0.5,还是在小数点后面。
        }
        DisplayData[1] = DIG_CODE[temp / 10000];
        DisplayData[2] = DIG_CODE[temp % 10000 / 1000];
        DisplayData[3] = DIG_CODE[temp % 1000 / 100] | 0x80;
        DisplayData[4] = DIG_CODE[temp % 100 / 10];
        DisplayData[5] = DIG_CODE[temp % 10];
         DigDisplay();                                           //扫描显示
}

/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能                   : 使用数码管显示
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DigDisplay()
{
        unsigned char i;
        unsigned int j;
        for(i=0;i<8;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位
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;//显示第6位
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;//显示第7位        
                }
                GPIO_DIG=DisplayData;//发送段码
                j=250;                                                 //扫描间隔时间设定
                while(j--);        
                GPIO_DIG=0x00;//消隐
        }
}
void Delay1ms()
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 12;
        j = 168;
        do
        {
                while (--j);
        } while (--i);
}
/*******************************************************************************
* 函 数 名         : Ds18b20Init
* 函数功能                   : 初始化
* 输    入         : 无
* 输    出         : 初始化成功返回1,失败返回0
*******************************************************************************/

uchar Ds18b20Init()
{
        uchar i;
        DSPORT = 0;                         //将总线拉低480us~960us
        delay1us(600);                //延时642us
        DSPORT = 1;                        //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
        i = 0;
        while(DSPORT)        //等待DS18B20拉低总线
        {
                delay1ms(1);
                i++;
                if(i>5)//等待>5MS
                {
                        return 0;//初始化失败
                }
        
        }
        return 1;//初始化成功
}

/*******************************************************************************
* 函 数 名         : Ds18b20WriteByte
* 函数功能                   : 向18B20写入一个字节
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void Ds18b20WriteByte(uchar dat)
{
        uint  j;

        for(j=0; j<8; j++)
        {
                DSPORT = 0;                       //每写入一位数据之前先把总线拉低1us
                delay1us(0);
                DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
                delay1us(70); //延时72us,持续时间最少60us
                DSPORT = 1;        //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
                delay1us(0);
                dat >>= 1;
        }
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadByte
* 函数功能                   : 读取一个字节
* 输    入         : com
* 输    出         : 无
*******************************************************************************/


uchar Ds18b20ReadByte()
{
        uchar byte, bi;
        uint  j;        
        for(j=8; j>0; j--)
        {
                DSPORT = 0;//先将总线拉低1us
                delay1us(0);
                DSPORT = 1;//然后释放总线
                delay1us(6);        //延时6us等待数据稳定
                bi = DSPORT;         //读取数据,从最低位开始读取
                /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
                byte = (byte >> 1) | (bi << 7);                                                  
                delay1us(46);                //读取完之后等待48us再接着读取下一个数
        }                                
        return byte;
}
/*******************************************************************************
* 函 数 名         : Ds18b20ChangTemp
* 函数功能                   : 让18b20开始转换温度
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void  Ds18b20ChangTemp()
{
        Ds18b20Init();
        delay1ms(1);
        Ds18b20WriteByte(0xcc);                //跳过ROM操作命令                 
        Ds18b20WriteByte(0x44);            //温度转换命令
//        Delay1ms(100);        //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTempCom
* 函数功能                   : 发送读取温度命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

void  Ds18b20ReadTempCom()
{        

        Ds18b20Init();
        delay1ms(1);
        Ds18b20WriteByte(0xcc);         //跳过ROM操作命令
        Ds18b20WriteByte(0xbe);         //发送读取温度命令
}
/*******************************************************************************
* 函 数 名         : Ds18b20ReadTemp
* 函数功能                   : 读取温度
* 输    入         : com
* 输    出         : 无
*******************************************************************************/

int Ds18b20ReadTemp()
{
        int temp = 0;
        uchar tmh, tml;
        Ds18b20ChangTemp();                                 //先写入转换命令
        Ds18b20ReadTempCom();                        //然后等待转换完后发送读取温度命令
        tml = Ds18b20ReadByte();                //读取温度值共16位,先读低字节
        tmh = Ds18b20ReadByte();                //再读高字节
        temp = tmh;
        temp <<= 8;
        temp |= tml;
        return temp;
}
void delay1ms(uint x)                //@12.000MHz   X=0,延迟2.83us   x=1,延迟约等于1ms
{
        int i,j;
        for(i=0;i<x;i++)
        {
                for(j=0;j<1000;j++);
        }
}
void delay1us(volatile uchar n)         // 延迟时间=n+2 us  误差2us    n=0,延迟2.08us
{                                 //晶振12MHZ   
        while(n)
        {
                n--;
        }
}

相关帖子

沙发
乌嘴猫|  楼主 | 2015-1-8 17:02 | 只看该作者
时序调试过了,还是显示不出来,这程序是用89c52单片机的程序移植过来的,移植过来显示就不正常了

使用特权

评论回复
板凳
ningling_21| | 2015-1-8 17:17 | 只看该作者
乌嘴猫 发表于 2015-1-8 17:02
时序调试过了,还是显示不出来,这程序是用89c52单片机的程序移植过来的,移植过来显示就不正常了 ...

89C52芯片可以显示正常吗?

使用特权

评论回复
地板
乌嘴猫|  楼主 | 2015-1-8 22:37 | 只看该作者
ningling_21 发表于 2015-1-8 17:17
89C52芯片可以显示正常吗?

可以,现在可以了。问题已经解决,谢谢

使用特权

评论回复
5
臭祥| | 2015-3-29 17:19 | 只看该作者
问题怎么解决的? 求支援

使用特权

评论回复
6
q158467234| | 2015-3-31 15:48 | 只看该作者
你好,那个用stc12要用c51的测温程序LCD显示要怎么改啊?用51芯片能显示温度,用stc12就不显示了,加了延时也不行~~看到你帖子那个问题解决了,能告诉一下怎么解决的吗

使用特权

评论回复
7
q158467234| | 2015-3-31 15:49 | 只看该作者
臭祥 发表于 2015-3-29 17:19
问题怎么解决的? 求支援

你好,那个用stc12要用c51的测温程序LCD显示要怎么改啊?用51芯片能显示温度,用stc12就不显示了,加了延时也不行~~请问你问题解决了吗,能告诉一下怎么解决的吗

使用特权

评论回复
8
hxjlm| | 2015-7-17 17:29 | 只看该作者
89C52是12T周期,STC12系列周期是1T,我也试了很久移植成功了,延时程序修改下

使用特权

评论回复
9
牧斯特Z| | 2015-9-22 10:55 | 只看该作者
你好,我最近也在搞ds18b20测温度的东西,我用dsp控制,现在发现读的数全是1,貌似写入的指令它没有接受,你觉得会是什么问题呢?能不能加qq,我想请教一下,729737287

使用特权

评论回复
10
ningling_21| | 2015-9-22 15:24 | 只看该作者
牧斯特Z 发表于 2015-9-22 10:55
你好,我最近也在搞ds18b20测温度的东西,我用dsp控制,现在发现读的数全是1,貌似写入的指令它没有接受, ...

时序很重要,严格按照芯片手册

使用特权

评论回复
11
牧斯特Z| | 2015-9-23 11:17 | 只看该作者
ningling_21 发表于 2015-9-22 15:24
时序很重要,严格按照芯片手册

现在时序没问题了,但是发现第一次进行18b20的初始化需要很长时间,大概3分钟,甚至有时候不能完成初始化,但是通过设置断点或者暂停一下再继续跑程序的手段可以实现初始化,然后接下来以后的每次初始化都比较正常,很快的完成初始化,为什么呢?

使用特权

评论回复
12
ningling_21| | 2015-9-23 11:26 | 只看该作者
牧斯特Z 发表于 2015-9-23 11:17
现在时序没问题了,但是发现第一次进行18b20的初始化需要很长时间,大概3分钟,甚至有时候不能完成初始化 ...

用51单片机初始化18B20,几百毫秒就完成,还是看看程序的初始化部分

使用特权

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

本版积分规则

8

主题

36

帖子

0

粉丝