历史上的今天
返回首页

历史上的今天

今天是:2025年02月14日(星期五)

正在发生

2020年02月14日 | 51单片机多点18b20温度测量系统

2020-02-14 来源:51hei

分享我的期末作业,基于51单片机的多点温度测量
同时多点温度测量是在单总线上挂载多个18b20温度传感器

单片机源程序如下:

#include        

#include   

#define uchar unsigned char  

#define uint unsigned int  

#define MAXNUM 4        //宏定义单总线上最大可扫描DS18B20个数  

//*****************************//

//**初始定义管脚、变量与数组***//

//*****************************//     

sbit DS=P3^7; 

sbit lcden=P2^7;//液晶使能端

sbit lcdrs=P2^6;//液晶数0据命令选择端

sbit lcdrw=P2^5;

union{                 

    uchar c[2];        

    uint x;            

}temp;                                           

uchar time=0;   

uint cc,xs;             //变量cc中保存计算出的温度值的整数部分,xs保存计算出的温度值的小数部分的第一位            

uchar idata disbuffer[6];   //LCD显示缓存数组  

uchar idata ID[4][8]={0};//{{0x28,0xff,0x80,0x2e,0x70,0x16,0x03,0xad},{0x28,0xff,0x95,0xb5,0x81,0x16,0x03,0x50},{0x28,0xff,0x02,0x96,0xa1,0x16,0x04,0x59},{0x28,0xff,0xf0,0xf5,0x62,0x16,0x04,0xd3}};

                       //{"82FF08E2076130DA","82FF595B18613005","82FF20691A614095","82FF0F5F2661403D"};   //用于记录各DS18B20的ROM序列号  

uchar idata RomID_temp[8];  //匹配DS18B20时临时记录要匹配DS18B20的序列号

uchar east[5]=" EAST";

uchar west[5]=" WEST";

uchar south[5]="SOUTH";

uchar north[5]="NORTH";

uchar m=0;             

uchar num=0;           

//***************************//

//*******18b20时序延时*******//

//***************************// 

void delay(uint i)      //i*9.62us   

{  

    uint j;  

    for(j=i;j>0;j--);  

}  

  

void delay_ms(uchar i)  //(j*2+1+2)*i+5     

{ uchar j;              //12MHz   0.5*i ms  

  do{j=248;            

     do{j--;}while(j);   

     i--;   

    }while(i);   

}  

    

void delay_2us(uchar i)   // 2*i+5 us  

{  

  while(--i);  

}  

//**************************//

//******18b20子程***********//

//**************************//  

uchar DS_init(void)       //18B20复位,初始化函数  

{  

  uchar presence;  

  DS=0;          delay_2us(250); //根据DS18B20的复位时序.先把总线拉低555us  

  DS=1;          delay_2us(30);  //再释放总线,65us后读取DS18B20发出的信号  

  presence=DS;   delay_2us(250); //如果复位成功,则presence的值为0;否则为1  

  return (presence);             //返回0则初始化成功,否则失败  

}   

  

uchar read_byte(void)       //读1字节  

{  

  uchar i,j,dat=0;  

  for(i=1;i<=8;i++)          //作8个循环,读出的8位组成一个字节  

    {DS=0;   _nop_();       //先将总线拉低1us,   

     DS=1;   delay_2us(2);  //再释放总线,产生读起始信号,延迟9us后读取总线上的DS18B20发出的值  

     j=DS;   delay_2us(30); //一位读完后,延迟65us后读下一位  

     dat=(j<<7)|(dat>>1);   //读出的数据最低位在一个字节的最低位,这样刚好一个字节在DAT里  

    }  

  return(dat);  

}   

  

uchar read_2bit(void)       //读2位  

{  

  uchar i=0,j=0;  

  DS=0;   _nop_();          //先将总线拉低1us,   

  DS=1;   delay_2us(2);     //再释放总线,产生读起始信号,延迟9us后读取总线上的DS18B20发出的值  

  j=DS;   delay_2us(30);    //一位读完后,延迟65us后读下一位  

  DS=0;   _nop_();            

  DS=1;   delay_2us(2);  

  i=DS;   delay_2us(30);  

  i=j*2+i;              //将读出的两位放到变量i中,其中第一个读出的位处于i的第1位;而第二个读出的位处于i的第0位  

  return(i);  

}   

    

void write_byte(uchar dat)  //写1字节  

{    

  uchar i;  

  for(i=0;i<8;i++)           //作8个循环,写入的8位组成一个字节  

    {DS=0;                  //先将总线拉低  

     DS = dat&0x01;         //向总线上放入要写的值  

     delay_2us(50);         //延迟105us,以使DS18B20能采样到要写入的值  

     DS = 1;                //释放总线,准备写入下一位  

     dat>>=1;             //将要写的下一位移到dat的最低位        

    }  

}   

   

void write_bit(bit dat) //写1位  

{    

  DS=0;             //先将总线拉低  

  DS=dat;           //向总线上放入要写的值  

  delay_2us(50);    //延迟105us,以使DS18B20能采样到要写入的值  

  DS = 1;           //释放总线  

}  

//************************//

//*******1602延时*********//

//************************// 

void delay1(uint z)

{

        uint i,j;

        for(i=z;i>0;i--)

        for(j=110;j>0;j--);

}

//************************//

//******1602子程**********//

//************************// 

void write_com(uchar com) //写命令 

{

        lcdrs=0;//选择写命令模式

        P0=com;//将要写的命令字送到数据总线上

        delay1(5);//稍作延时以待数据稳定

        lcden=1;//使能端给一高电平脉冲,因为初始化函数中已将lcden置零

        delay1(5);//稍作延时

        lcden=0;//将使能端置零完成高脉冲

}


void write_data(uchar date)  //写数据 

{

        lcdrs=1;//选择写数据操作

        P0=date;//将要写的数据送到数据总线上

        delay1(5);//稍作延时

        lcden=1;//使能端给一高电平脉冲

        delay1(5);

        lcden=0;

}


void init()   //1602初始化 

{

        lcdrw=0;

        lcden=0;

        write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口

        write_com(0x0c);//设置开显示,不显示光标

        write_com(0x06);//写一个字节后地址指针加1

        write_com(0x01);//显示清零,数据指针清零

        write_com(0x80);//设置数据指针起点

}

//****************************//

//***读取18b20温度数据子程 ***//

//****************************//

void Read_Temperature_rom(void) //读取温度函数  

{   uchar i;  

    DS_init();  

    write_byte(0x55);       //匹配ROM  

    for(i=0;i<8;i++)     //发出64位ROM编码  

            write_byte(RomID_temp[i]);  

    write_byte(0x44);       //开始转换温度 

    DS_init();  

    write_byte(0x55);       //匹配ROM  

    for(i=0;i<8;i++)     //发出64位ROM编码  

            write_byte(RomID_temp[i]);  

    write_byte(0xBE);       //发读温度命令  

    temp.c[1]=read_byte();  //读低字节,之所以c[1]中放低字节,是因为C51采用的是大端格式 

    temp.c[0]=read_byte();  //读高字节,之所以c[0]中放低字节,是因为C51采用的是大端格式 

                            //共用体定义 

}  

  

void Temperature_cov(void)      //温度转化

{                              

    cc=temp.x/16;           //计算出温度值的整数部分,这个语句相当于数值乘0.0625再取整数部分  

    xs=temp.x&0x0f;         //取温度值小数部分的第一位  

    xs=xs*10;               //这两条语句相当于乘0.625,得小数位的第一位,注意不是乘0.0625  

    xs=xs/16; 

}  

//***********************//

//******显示子程*********// 

//***********************//

void display_m(void)   //显示18b20个数或方向 

{

        uchar i;

        write_com(0x8B);

        //write_data('0'+m);

        if(m==0)

        for(i=0;i<5;i++)

        {write_data(east[i]);}

        if(m==1)

        for(i=0;i<5;i++)

        {write_data(west[i]);}

        if(m==2)

        for(i=0;i<5;i++)

        {write_data(south[i]);}

        if(m==3)

        for(i=0;i<5;i++)

        {write_data(north[i]);}

}


void display_ROMID(void)        //显示序列号  

{    

    uchar tmp[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,

             0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};        

推荐阅读

史海拾趣

AB Connectors Ltd公司的发展小趣事

AB Connectors Ltd成立于上世纪九十年代初,当时电子行业正处于飞速发展的黄金时期。公司创始人张三和李四凭借对连接器技术的深刻理解和对市场需求的敏锐洞察,决定创立这家公司。初创时期,公司面临着资金短缺、技术瓶颈和市场认可度低等挑战。然而,通过不懈的努力,AB Connectors Ltd成功研发出了一款具有竞争力的新型连接器产品,并在国际电子展览会上获得了广泛关注。这为公司打开了市场大门,奠定了发展的基础。

Eurofarad公司的发展小趣事

随着Eurofarad产品质量的不断提高和市场份额的逐步扩大,公司开始积极拓展国际市场。Eurofarad的产品已经广泛应用于航空航天、国防、医疗、铁路、石油勘探等领域,赢得了全球客户的信赖和好评。同时,Eurofarad还与国际知名企业建立了紧密的合作关系,共同推动电子行业的发展。

Bipolar Integrated Technology Inc公司的发展小趣事

在20世纪初,Bipolar Integrated Technology Inc(以下简称BIT)由几位热衷于电子技术的工程师创立。他们专注于双极型集成电路的研发,这一领域在当时尚未被充分开发。经过无数次的试验和失败,BIT团队终于成功研发出了一款性能稳定、功耗较低的双极型集成电路,这一技术突破为BIT在行业内赢得了初步声誉。

ALCOA公司的发展小趣事

在20世纪的后半叶,ALCOA继续在技术上取得重大突破。例如,在40年代,公司采用N-40(Niagara)50kA中心下料预焙阳极电解槽技术为政府建造了铝冶炼厂。此外,公司还不断扩大海外业务,建立了全球性的生产和销售网络。这种全球布局使得ALCOA能够更好地满足不同地区的市场需求,也增强了公司的竞争力。

ACCRETECH公司的发展小趣事

ALCOA,全称美国铝业公司,其发展历程可追溯至19世纪末。当时,铝在地球上蕴藏丰富,但提炼单质的铝却十分困难。年轻的查尔斯·霍尔(Charles Hall)发明了用电解方式生产单质铝的方法,并于1889年获得专利。随后,他与艾尔弗雷德·亨特(Alfred E. Hunt)船长合作,投资建厂,开始批量生产铝。这一技术创新不仅推动了铝产量的快速上升,还使得铝这种曾经比金子还贵的金属逐渐走进了人们的日常生活。

国兴(GOODSKY)公司的发展小趣事

第一次世界大战期间,铝因其轻质且强度高的特性,被广泛应用于航空和汽车工业。ALCOA公司借此机会迅速发展壮大,为军方和汽车制造商提供了大量的铝材。这种需求推动了公司的技术进步和生产规模的扩大,也奠定了ALCOA在电子行业中的领先地位。

问答坊 | AI 解惑

动态数码显示技术

1. 实验任务 如下图所示,P0端口接动态数码管的字形码笔段,P2端口接动态数码管的数位选择端,P1.7接一个开关,当开关接高电平时,显示“12345”字样;当开关接低电平时,显示“HELLO”字样。 2. 电路原理图 3. 系统板上硬件连线 (1)、我 ...…

查看全部问答>

TI常用的各款DSP数据手册集锦

TM2系列的有: tms320lf240x tms320r281X tms320f2812 TMS320C206 DataSheet…

查看全部问答>

利用ADC0804做一个真正的电压表

本帖转载自www.mcusy.com,作者月夜。…

查看全部问答>

学习学习GPS

GSV GSA GGA分别是什么 a.GPS固定数据输出语句($GPGGA)这是一帧GPS定位的主要数据,也是使用最广的数据。$GPGGA 语句 包括17个字段:语句标识头,世界时间,纬度,纬度半球,经度,经度半球,定位质量指示,使用卫星数量, 水平精确度,海拔高 ...…

查看全部问答>

LED户外大屏幕基础知识

replyreload += \',\' + 374037;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

周公M0新原理图

周公的M0开发板的原理图终于更新了…

查看全部问答>

关于控制USB外设的问题

我是第一次作这方面的东西: 我感觉:首先要判断次外设的存在(包括他的插入于拔除)         向外设发送控制命令(包括向他提供数据)。 不知道思路是不是有问题,请各位给个思路。 …

查看全部问答>

LaunchPAD新配件-音频电容触摸套件

C5000音频电容触摸套件套件具体指标如下:MP3 Encode & DecodeSD Card File SystemUSB Mass Storage ClassOLED, CodecUART client interface可使用该套件配合launchpad制作音乐播放器:MP3 PlayerVoice RecorderFire Alarm – MSP430 detects tem ...…

查看全部问答>

MSP430F149的定时器A的连续计数模式的CCR0

MSP430F149的定时器A的连续计数模式的CCR0的作用?增计数模式是从0增加到CCR0就复位,增减计数模式是从0增加到CCR0,在减到0。可是连续计数模式呢?CCR0的作用?…

查看全部问答>

Linux 常用C函数(中文版)

很详细的c函数介绍文档,我一直把他当做工具书来用,分享给大家! 如果哪位大侠把这个网页式的工具做成chm格式的电子书就完美了,哈哈 截图,先睹为快 [ 本帖最后由 HOHO 于 2012-8-8 16:42 编辑 ]…

查看全部问答>