找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2442|回复: 2
收起左侧

单片机DS18B20点位关系对应的多点温度测量 含原理 源码 文档 仿真

[复制链接]
ID:62509 发表于 2020-7-24 00:20 | 显示全部楼层 |阅读模式
点位关系对应的多点温度测量问题的最终结果过去的多点温度测量并显示模型,Proteus模拟时LCD1602上一阵温度值,前后无序的显示以后你搞不清哪个DS18B20对应哪个温度值,这样造成很难实用。
                              
我对程序进行了研究解读后发现,DS18B20的每个器件的序列号都是存在的,只是没有对应图中的模型号,比如:
U5是ROMData5={0x28,0x34, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x52}; //U5其温度是25.5度,
U4是ROMData4={0x28,0x32, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xE0}; //U4其温度是17.0度,
那么,只要查询到序列号给定对应的器件号,并将器件号和温度存储在数据结构中即可。
其他的我就不多说了,请看我的具体做法。
第一、  改变数据结构,增加器件号。
在DS18B20.h内存储着数据结构,在数据结构中增加了btNumber这保证了,前面的数据都跟“检测头编号”对应成了一组数据。
当然你可以再增加检测头名称和检测位置等,这样就更实用了。

第二、  调试系列号与检测头编号的一致对应性
    在DS18B20.c现在屏蔽的这一块是用来做Proteus单步调节读取序列码的。对于有脉冲时间要求的数据读取或存储来说,如果不调试根本不知道结果是什么。
当你通过调试发现可以对应的时候,你就可以把两者关联起来了。

第三、  序列号与器件号对应存储程序
    程序在DS18B20.c中,对于八个器件进行序列号查询,并将查询结果与检测头编号一一对应起来,并存储。
当然也可以利用该程序存储你自己定义的比如检测头名称和检测位置等。

第四、  设置温度显示框架
    在Main.c的主程序循环显示中,先显示框架结构。如不满意可自行调整。

第五、  设置温度数值显示架构
    在Main.c的主程序中,有一个数据值显示结构,它是与框架结构对应的。

第六、  仿真运行的结果如下

  个别显示的温度值,是因为放不下所以进行了收缩,从而造成字体变形。如U8=-18.6收缩以后看起来有点像-13.5’C。等你仿真实际看时就会正常。
温度显示结构如图。如果想显示其他内容,那就需要自行安排了。

第七、  Keil C程序结构

     

第八、  压缩文件结构
    这样做的目的是避免你在改动程序的时候,改错了,你又找不回来源程序。最后你不得不放弃。这样在Keil C下永远存储着一套正确的程序,你可以在Code下放心修改了。而且这种存储结构会让你思路更加清晰。
     
     
     
     
Main.C:
  • #include <Intrins.h>
  • #include <AT89X52.H>
  • #include "DS1602.h"
  • #include "DS18B20.h"
  • TEMPDATA m_TempData;
  • //数据处理子程序
  • void DataProcess()
  • {
  •         m_TempData = ReadTemperature();
  • //        DisplayOne(1, 4,  m_TempData.btNumber,  1);
  •         if (m_TempData.btNegative)
  •         {
  •                 DisplayOne(1, 6, '-', 0);
  •         }
  •         else
  •         {
  •                 DisplayOne(1, 6, m_TempData.btThird, 1);
  •         }
  •         DisplayOne(1, 7,  m_TempData.btSecond,  1);
  •         DisplayOne(1, 8,  m_TempData.btFirst,   1);
  •         DisplayOne(1, 10, m_TempData.btDecimal, 1);
  •         DisplayOne(2, 3,  m_TempData.btNumber,  1);
  • }
  • void main()
  • {
  •         //GetROMSequence();
  •         unsigned char a=0;
  •         Clear();
  •         Init();
  •         DisplayString(0, 0, "  Temperature");
  •         DisplayOne(1, 9, '.', 0);
  •         DisplayOne(1, 11, '`', 0);
  •         DisplayOne(1, 12, 'C', 0);
  •         DisplayOne(2, 2, 'U', 0);
  •         DisplayOne(2, 4, '=', 0);
  •         while (1)
  •         {
  •     a++;
  •                 if(a > 9) a = 0;
  •                 DataProcess();
  •         }
  • }



DS18B20.C://头文件包含
  1. #include <AT89X52.H>
  2. #include <Intrins.h>
  3. #include "DS18B20.h"

  4. //引脚定义
  5. sbit                                                         DQ = P2^7;                                                        //数据线端口

  6. //DS18B20序列号,通过调用GetROMSequence()函数在P1口读出(读8次)
  7. const unsigned char code ROMData1[8] = {0x28, 0x33, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xD7};        //U1
  8. const unsigned char code ROMData2[8] = {0x28, 0x30, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x8E};        //U2
  9. const unsigned char code ROMData3[8] = {0x28, 0x31, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xB9};        //U3
  10. const unsigned char code ROMData4[8] = {0x28, 0x32, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xE0};        //U4
  11. const unsigned char code ROMData5[8] = {0x28, 0x34, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x52};        //U5
  12. const unsigned char code ROMData6[8] = {0x28, 0x35, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x65};        //U6
  13. const unsigned char code ROMData7[8] = {0x28, 0x36, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x3C};        //U7
  14. const unsigned char code ROMData8[8] = {0x28, 0x37, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x0B};        //U8

  15. //延时16us子函数
  16. void Delay16us()
  17. {
  18.         unsigned char a;

  19.         for (a = 0; a < 4; a++);
  20. }

  21. //延时60us子函数
  22. void Delay60us()
  23. {
  24.         unsigned char a;

  25.         for (a = 0; a < 18; a++);
  26. }

  27. //延时480us子函数
  28. void Delay480us()
  29. {
  30.         unsigned char a;

  31.         for (a = 0; a < 158; a++);
  32. }

  33. //延时240us子函数
  34. void Delay240us()
  35. {
  36.         unsigned char a;

  37.         for (a = 0; a < 78; a++);
  38. }

  39. //延时500ms子函数
  40. void Delay500ms()
  41. {
  42.         unsigned char a, b, c;

  43.         for (a = 0; a < 250; a++)
  44.         for (b = 0; b < 3; b++)
  45.         for (c = 0; c < 220; c++);
  46. }

  47. //芯片初始化
  48. void Initialization()
  49. {
  50.         while(1)
  51.         {
  52.                 DQ = 0;
  53.                 Delay480us();                         //延时480us
  54.                 DQ = 1;
  55.                 Delay60us();                        //延时60us
  56.                 if(!DQ)                                  //收到ds18b20的应答信号
  57.                 {      
  58.                         DQ = 1;
  59.                         Delay240us();                //延时240us
  60.                         break;               
  61.                 }
  62.         }
  63. }

  64. //写一个字节(从低位开始写)
  65. void WriteByte(unsigned char btData)
  66. {
  67.         unsigned char i, btBuffer;

  68.         for (i = 0; i < 8; i++)
  69.         {
  70.                 btBuffer = btData >> i;
  71.                 if (btBuffer & 1)
  72.                 {
  73.                         DQ = 0;
  74.                         _nop_();
  75.                         _nop_();
  76.                         DQ = 1;
  77.                         Delay60us();
  78.                 }
  79.                 else
  80.                 {
  81.                         DQ = 0;
  82.                         Delay60us();
  83.                         DQ = 1;                       
  84.                 }
  85.         }
  86. }

  87. //读一个字节(从低位开始读)
  88. unsigned char ReadByte()
  89. {
  90.         unsigned char i, btDest;

  91.         for (i = 0; i < 8; i++)
  92.         {
  93.                 btDest >>= 1;
  94.                 DQ = 0;
  95.                 _nop_();
  96.                 _nop_();
  97.                 DQ = 1;
  98.                 Delay16us();
  99.                 if (DQ) btDest |= 0x80;
  100.                 Delay60us();
  101.         }

  102.         return btDest;
  103. }

  104. //序列号匹配
  105. void MatchROM(const unsigned char *pMatchData)
  106. {
  107.         unsigned char i;

  108.         Initialization();
  109.         WriteByte(MATCH_ROM);
  110.         for (i = 0; i < 8; i++) WriteByte(*(pMatchData + i));      
  111. }

  112. //得到64位ROM序列(在P1口显示,必须与Proteus联调且在单步调试下才能得到)
  113. /*void GetROMSequence()
  114. {
  115.         unsigned char i;

  116.         Initialization();
  117.         WriteByte(READ_ROM);
  118.         for (i = 0; i < 8; i++)
  119.         P1 = ReadByte();      
  120. }*/

  121. //读取温度值
  122. TEMPDATA ReadTemperature()
  123. {
  124.         TEMPDATA TempData;
  125.         unsigned int iTempDataH;
  126.         unsigned char btDot, iTempDataL;
  127.         static unsigned char i = 0;

  128.         TempData.btNegative = 0;                                                //为0温度为正
  129.         i++;
  130.         if (i == 9) i = 1;
  131.         Initialization();
  132.         WriteByte(SKIP_ROM);                                                        //跳过ROM匹配
  133.         WriteByte(TEMP_SWITCH);                                                        //启动转换
  134.         Delay500ms();                                                                          //调用一次就行      
  135.         Delay500ms();                        
  136.         Initialization();

  137.         //多个芯片的时候用MatchROM(ROMData)换掉WriteByte(SKIP_ROM)
  138.         switch (i)
  139.         {
  140.                 case 1 : MatchROM(ROMData1); TempData.btNumber = 1; break;                        //匹配1
  141.                 case 2 : MatchROM(ROMData2); TempData.btNumber = 2; break;                        //匹配2
  142.                 case 3 : MatchROM(ROMData3); TempData.btNumber = 3; break;                        //匹配3
  143.                 case 4 : MatchROM(ROMData4); TempData.btNumber = 4; break;                        //匹配4      
  144.                 case 5 : MatchROM(ROMData5); TempData.btNumber = 5; break;                        //匹配5
  145.                 case 6 : MatchROM(ROMData6); TempData.btNumber = 6; break;                        //匹配6
  146.                 case 7 : MatchROM(ROMData7); TempData.btNumber = 7; break;                        //匹配7
  147.                 case 8 : MatchROM(ROMData8); TempData.btNumber = 8; break;                        //匹配8
  148.         }
  149.         //WriteByte(SKIP_ROM);                                                        //跳过ROM匹配(单个芯片时用这句换掉上面的switch)
  150.         WriteByte(READ_MEMORY);                                                        //读数据
  151.         iTempDataL = ReadByte();
  152.         iTempDataH = ReadByte();      
  153.         iTempDataH <<= 8;
  154.         iTempDataH |= iTempDataL;

  155.         if (iTempDataH & 0x8000)
  156.         {
  157.                 TempData.btNegative = 1;
  158.                 iTempDataH = ~iTempDataH + 1;                                //负数求补
  159.         }

  160.         //为了省去浮点运算带来的开销,而采用整数和小数部分分开处理的方法(没有四舍五入)
  161.         btDot = (unsigned char)(iTempDataH & 0x000F);        //得到小数部分
  162.         iTempDataH >>= 4;                                                                //得到整数部分
  163.         btDot *= 5;                                                                         //btDot*10/16得到转换后的小数数据
  164.         btDot >>= 3;

  165.         //数据处理
  166.         TempData.btThird   = (unsigned char)iTempDataH / 100;
  167.         TempData.btSecond  = (unsigned char)iTempDataH % 100 / 10;
  168.         TempData.btFirst   = (unsigned char)iTempDataH % 10;
  169.         TempData.btDecimal = btDot;      

  170.         return TempData;
  171. }
复制代码


DS18B20.h:
        #ifndef __DS18B20_H__#define __DS18B20_H__
//ROM操作命令#define  READ_ROM     0x33   //读ROM #define  SKIP_ROM     0xCC   //跳过ROM #define  MATCH_ROM    0x55   //匹配ROM #define  SEARCH_ROM   0xF0   //搜索ROM #define  ALARM_SEARCH 0xEC   //告警搜索
//存储器操作命令#define  ANEW_MOVE     0xB8  //重新调出E^2数据#define  READ_POWER    0xB4  //读电源#define  TEMP_SWITCH   0x44  //启动温度变换 #define  READ_MEMORY   0xBE  //读暂存存储器#define  COPY_MEMORY   0x48  //复制暂存存储器#define  WRITE_MEMORY  0x4E  //写暂存存储器
//数据存储结构typedef struct tagTempData{        unsigned char         btThird;                //百位数据                                                unsigned char         btSecond;                //十位数据        unsigned char         btFirst;                //个位数据        unsigned char         btDecimal;        //小数点后一位数据        unsigned char                btNegative;        //是否为负数                unsigned char         btNumber;                //检测头编号                                        }TEMPDATA;
//芯片初始化void Initialization();
//写一个字节(从低位开始写)void WriteByte(unsigned char btData);
//读一个字节(从低位开始读)unsigned char ReadByte();
//序列号匹配void MatchROM(const unsigned char *pMatchData);
//读取温度值TEMPDATA ReadTemperature();
//得到64位ROM序列void GetROMSequence();
#endif



04温度对应显示框架

04温度对应显示框架

03系列号关联存储

03系列号关联存储

00仿真程序界面

00仿真程序界面

02系列号对应检查

02系列号对应检查

01数据结构变化

01数据结构变化

05数据结果显示安排

05数据结果显示安排

06仿真结果的对应关系

06仿真结果的对应关系

07温度显示结构

07温度显示结构

08Keil C程序结构

08Keil C程序结构

09压缩文件结构

09压缩文件结构

10调试程序位置

10调试程序位置

11可执行程序位置

11可执行程序位置

12程序备份位置

12程序备份位置

多点温度测量系统设计.zip

827.97 KB, 下载次数: 46, 下载积分: 黑币 -5

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:62509 发表于 2020-7-24 00:22 | 显示全部楼层
程序及仿真

《多点温度测量》.zip

119.5 KB, 下载次数: 42, 下载积分: 黑币 -5

程序及仿真

回复

使用道具 举报

ID:8222 发表于 2020-7-24 09:58 | 显示全部楼层
这个很好,可以方便的进行多点测量了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表