Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1566620
  • 博文数量: 354
  • 博客积分: 8137
  • 博客等级: 中将
  • 技术积分: 5137
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-26 15:40
文章分类

全部博文(354)

文章存档

2010年(300)

2009年(54)

分类: 嵌入式

2010-09-15 13:43:10


/*************************************************
*功能描述: CEPARK CAN开发板-DS18B20温度测试
*说明:数码管上后三位显示DS18B20测得的温度
*版本:v2.00
*声明:程序来自网络,欢迎网友交流改进
* 活跃论坛,共同进步
*作者:协成电子    、hnrain
*时间:2010/09/14
*邮箱:hnrain1004@gmail.com    ,HQL19982003@163.com ,qq:87675298
*网站:bbs.cepark.com ;写程序如果有问题,可以在这里讨论
*我们的口号:让不懂can的学习者,也能轻松玩转can

*推荐教材:
饶运涛,邹继军《现场总线 CAN 原理与应用技术》.北京:北京航空航天大学出版社 (这本书,看着不错)
周立功《增强型80c51单片机速成与实战》还有周立功写的一些can通信程序算法很不错,值得学习
本程序,融入了那么一点点点点点,他们的编程思想,哈哈....仅供学习用
****************************************************/

#include <REG52.H>
#include "config.h"

//数码管段码显示:0~f,不亮

uint8 code DispTab[]={0xc0,0xde,0xa2,0x8a,0x9c,0x89,0x81,0xda,0x80,0x88,
                            0x90,0x85,0xe1,0x86,0xa1,0xb1,0xff};    //段码0-9,a-f

uint8 DispBuf[4];

uint8 TempH,TempL;
uint16 Temp;
bit Presence;

sfr LedPort = 0x80;     //P0口接段码

sbit Led0     =    P2^4; //LED控制脚

sbit Led1      =    P2^5;
sbit Led2     =    P2^6;
sbit Led3     =    P2^7;
sbit DataPort =P3^5;        //18B20的数据口


void uDelay(uint8 DelayTime)         //延时子程序,入口参数每加1约加2us

{     
    while(--DelayTime);        
}

void Hex2Bcd()    //HEX转BCD程序

{    
    if(Presence==1)
        { //如果没有检测到存在则显示“no”

        DispBuf[0]=0xab;
        DispBuf[1]=0xa3;
        DispBuf[2]=0xff;
        DispBuf[3]=0xff;
        }
    else
        {                        //分解后查表得到段码放入显示缓存

        Temp=TempH*256+TempL;     //数据合并成一个双字节数

        
        if((Temp>>12)==0xf)         //右移12位判断是否为负温度

            {Temp=0x10000-Temp;     //计算出负温度值

            DispBuf[0]=0xbf;}     //并将最左边数码管显示“-”号

        else DispBuf[0]=0xff;     //否则不显示

        
        TempH=Temp>>4;             //将小数点4位值移出后,得到整数部分放在TempH中

        Temp=(Temp&0x0f)*625;         //相与取出小数点四位,乘法得到小数点值

        DispBuf[3]=DispTab[Temp/1000];    //小数点位只取最高一位,后三位不显示

        
        DispBuf[2]=DispTab[TempH%10]&0x7f; //个位处理并点亮小数点

        TempH=TempH/10;     //取出百位、十位

        
        if(!TempH) DispBuf[1]=0xff;//百位和十位均为0则十位不显示。

            else DispBuf[1]=DispTab[TempH%10];

        if(DispBuf[0]==0xff)//正温度情况下

            {
            if(TempH/10) DispBuf[0]=DispTab[TempH/10];//百位有数值显示

            else DispBuf[0]=0xff;//为0不显示            

            }
        }
}

void Display(uint8 j)    //显示子程序

{     
    for(;j>0;j--)
    {
        LedPort=DispBuf[0];
        Led0=0;
        uDelay(20);
        Led0=1;
        LedPort=DispBuf[1];
        Led1=0;
        uDelay(20);
        Led1=1;
        LedPort=DispBuf[2];
        Led2=0;
        uDelay(20);
        Led2=1;
        LedPort=DispBuf[3];
        Led3=0;
        uDelay(20);
        Led3=1;
    }
}

void Inti()
{
    DataPort=0;     //拉低

    uDelay(180);     //延时后拉高

    DataPort=1;
    uDelay(24);     //延时后读状态,如果存在,由18B20将端口拉低

    Presence=DataPort;//状态存入,用于后面显示判断

    uDelay(230);    //延时完成一周期时间

}

void WriteByte(uint8 val)    //字节写入

{
 uint8 i;
  for (i=8; i>0; i--)
  {
    DataPort = 0;
    uDelay(4);
    DataPort = val&0x01;
    uDelay(20);
    DataPort = 1;
    val=val/2;
  }
  uDelay(50);
}


uint8 ReadByte()     //字节读取

{
uint8 i;
uint8 value=0;
    for (i=0;i<8;i++)//读入8字节

    {
        DataPort=0;    //拉低后再拉高,产生读间隙

        DataPort=1;
        uDelay(4); //延时后读入

        if(DataPort) value|=0x01<<i;
        uDelay(20); //延时完成一周期时间

    }
return (value);
}

void SetStep(uint8 Dat)    //入口参数,1F-0.5度步进,3F-0.25度,5F-0.125度,7F-0.0625度

{
    Inti();
    WriteByte(0xcc);
    WriteByte(0x4e);
    WriteByte(0x15); //写地址2—TH

    WriteByte(0x00); //写地址3—TL

    WriteByte(Dat); //地址4,保留区,用于小数后分辨率,1F,3F,5F,7F取值,值越大分辨率越高

    Inti();
    WriteByte(0xcc);
    WriteByte(0xbe);
    ReadByte();
    Inti();
    WriteByte(0xcc);
    WriteByte(0x48); //拷贝指令,发出后等6ms等待18B20将数据写入EEPROM,写结束再复位。

    uDelay(100);
    Inti();
    DataPort=1;
}

void GetTemp()     //温度获得子程序,返回值在TempH,TempL中

{
    Inti();                Display(8);//每执行一条指令补充显示,消除闪动

    WriteByte(0xcc);    Display(8);
    WriteByte(0x44);    Display(8);
    Inti();                Display(8);
    WriteByte(0xcc);    Display(8);
    WriteByte(0xbe);    Display(8);
    TempL=ReadByte();    Display(8);
    TempH=ReadByte();    Display(8);
}
 
void main(void)
{
    uDelay(100);
    Presence=1;
    SetStep(0x7f);
    GetTemp();Display(100); //发送第一个取温度指令后,要延时一段时间等待内部转换。(解决开机显示85度的问题。)

    while(1){GetTemp();Hex2Bcd();Display(50);}

}



文件:5 DS18B20显示.zip
大小:25KB
下载:下载
CEPARK CAN总线开发板 程序更新20100914
阅读(1167) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~