找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2155|回复: 1
收起左侧

初学8051:DS18B20,给初学者

[复制链接]
ID:51812 发表于 2015-11-30 21:38 | 显示全部楼层 |阅读模式
初学8051,把买的的学习板带的程序给修改了、数码管显示,串口上位机显示
STC89C52RC
压缩包内有 下位机C51程序,proteus仿真,C#写的简单的串口。

在冰柜里测了低温,在proteus里仿真了100°C以上的高温,都能正确显示。在腋窝里测了下体温,用了好长时间才稳定在36.5°C 。

DS18B20.rar

239.42 KB, 下载次数: 22, 下载积分: 黑币 -5

评分

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

查看全部评分

回复

使用道具 举报

ID:1 发表于 2015-12-2 00:38 | 显示全部楼层
  1. 楼主的程序:
  2. /*****************************************************************
  3. *程序名称:DS18B20 4位数码管 上位机
  4. *程序功能:读写DS18B20,数码管显示温度值,上位机显示。
  5. *开发工具:谷雨电子 多功能51开发板
  6. *MCU型号:STC89C52RC
  7. *时钟频率:11.0592MHZ
  8. *程序作者:LCG
  9. *版权说明:
  10. *****************************************************************/

  11. #include <reg52.h>

  12. #define uint unsigned int
  13. #define uchar unsigned char

  14. //定义DS18B20通信端口,修改硬件时要修改的部分
  15. sbit DQ = P2 ^ 0;
  16. //0-9的8位共阳数码管位码 其中负号0xbf
  17. uchar const LEDNumber[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf };
  18. //0-9的8位共阳数码管位码  带小数点
  19. uchar const LEDNumberDot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
  20. //LCG
  21. uchar const LCGData[]={0xC7,0xC6,0xC2};
  22. //温度是否是负
  23. uchar tempSign;
  24. //传感器的温度的高位低位
  25. uchar tH=0x00;tL=0x00;
  26. //当前温度
  27. float tt=0;//临时
  28. int CurrentT=0;
  29. int t=0;//临时
  30. //数位
  31. uchar bw,sw,gw,sfw;//百位,十位,个位,十分位

  32. //***********************以下为函数声明部分*****************
  33. void DispLCG(int pos, int Data);
  34. void LCGDisp(void);
  35. void delay(uint us);
  36. void Init_DS18B20(void);
  37. uchar ReadOneChar(void);
  38. void WriteOneChar(uchar dat);
  39. void ReadTemperature(void);
  40. void LedDispDig(int Pos, int Dig, uchar isDot);
  41. void DisplayTemp(void);
  42. void init_serial(void);
  43. void Tranfer(char Data);

  44. //char Temp_lower, Temp_upper;         //温度的上限和下限

  45. //=================================================================
  46. // 函数名称 :void delay (uint us)
  47. // 函数功能 :延时
  48. // 入口参数 :us 延时时间的长短
  49. // 出口参数 :无
  50. //=================================================================
  51. void delay(uint us)
  52. {
  53.         //此函数精确计算[12MHz晶振]:18+6*(t-1)=延时时间(us)
  54.         while (us--);
  55. }

  56. //=================================================================
  57. // 函数名称 :void Init_DS18B20(void)
  58. // 函数功能 :DS18B20初始化函数
  59. // 入口参数 :无
  60. // 出口参数 :无
  61. //=================================================================
  62. void Init_DS18B20(void)
  63. {
  64.         uchar x = 0;
  65.         DQ = 1;   //DQ复位
  66.         delay(8); //稍做延时
  67.         DQ = 0;   //单片机将DQ拉低
  68.         delay(80); //精确延时 大于 480us
  69.         DQ = 1;   //拉高总线
  70.         delay(14);
  71.         x = DQ;     //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  72.         delay(20);
  73. }

  74. //=================================================================
  75. // 函数名称 :uchar ReadOneChar(void)
  76. // 函数功能 :DS18B20读字节函数
  77. // 入口参数 :无
  78. // 出口参数 :dat 读回的字节数据
  79. //=================================================================
  80. uchar ReadOneChar(void)
  81. {
  82.         uchar i = 0;
  83.         uchar dat = 0;

  84.         for (i = 0; i < 8; i++)
  85.         {
  86.                 DQ = 0; // 给脉冲信号
  87.                 dat >>= 1;
  88.                 DQ = 1; // 给脉冲信号
  89.                 if (DQ)
  90.                         dat |= 0x80;
  91.                 delay(4);
  92.         }
  93.         return dat;
  94. }

  95. //=================================================================
  96. // 函数名称 :void WriteOneChar(uchar dat)
  97. // 函数功能 :DS18B20写字节函数
  98. // 入口参数 :dat 要写入的字节数据
  99. // 出口参数 :无
  100. //=================================================================
  101. void WriteOneChar(uchar dat)
  102. {
  103.         uchar i = 0;
  104.         for (i = 0; i <8; i++)
  105.         {
  106.                 DQ = 0;
  107.                 DQ = dat & 0x01;
  108.                 delay(5);
  109.                 DQ = 1;
  110.                 dat >>= 1;
  111.         }
  112. }

  113. //=================================================================
  114. // 函数名称 :float ReadTemperature(void)
  115. // 函数功能 :DS18B20读取温度值函数
  116. // 入口参数 :无
  117. // 出口参数 :读取的温度值,为float型的数据
  118. //=================================================================
  119. void ReadTemperature(void)
  120. {
  121.         Init_DS18B20();
  122.         WriteOneChar(0xcc); // 跳过读序号列号的操作
  123.         WriteOneChar(0x44); // 启动温度转换
  124.         Init_DS18B20();
  125.         WriteOneChar(0xcc); //跳过读序号列号的操作
  126.         WriteOneChar(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  127.         tL = ReadOneChar();
  128.         tH = ReadOneChar();
  129.        
  130.         //合并为字
  131.         t = tH;
  132.         t <<= 8;
  133.         t = t | tL;
  134.        
  135.         if((tH & 0xf8)==0xf8) //负温度
  136.         {
  137.                  tt=(~t+1)*0.0625;
  138.                 tempSign = 1;       
  139.         }
  140.         else //正温度
  141.         {
  142.                 tt=t*0.0625;
  143.                 tempSign=0;
  144.         }
  145.         CurrentT=(int)(tt*10); //tt*10保留一位小数并对float型强制取整
  146.        
  147.         bw=CurrentT/1000; //百位
  148.         sw=CurrentT%1000/100; //十位
  149.         gw=CurrentT%100/10; //个位
  150.         sfw=CurrentT%10; //小数十分位
  151. }

  152. //=================================================================
  153. // 函数名称 :void DispLCG(int pos, int Data)
  154. // 函数功能 :显示LCG
  155. // 入口参数 :Pos 数码管的位置
  156. //            Data 要显示的数字
  157. // 出口参数 :无
  158. //=================================================================
  159. void DispLCG(int Pos, int Data)
  160. {
  161.         P0 = LCGData[Data];
  162.         P1 |= 0x0f;
  163.         P1 &= 0xff - (0x01 << Pos);
  164. }
  165. void LCGDisp(void)
  166. {
  167.         int i,j;
  168.         for(j=0;j<500;j++) //大约2秒
  169.         {
  170.                 for(i=0;i<3;++i)
  171.                 {
  172.                         DispLCG(i,i);
  173.                         delay(300);
  174.                 }
  175.         }
  176. }
  177. //=================================================================
  178. // 函数名称 :void LedDispDig(int Pos,int Dig)
  179. // 函数功能 :在指定的数码管上显示数字
  180. // 入口参数 :Pos 数码管的位置
  181. //            Dig 要显示的数字
  182. //                                                isDot 是否是个位数,个位数带小数点
  183. // 出口参数 :无
  184. //=================================================================
  185. void LedDispDig(int Pos, int Dig, uchar isDot)
  186. {
  187.         if (isDot==1)
  188.         {
  189.                 P0=LEDNumberDot[Dig]; //带小数点
  190.         }
  191.         else
  192.         {
  193.                 P0 = LEDNumber[Dig]; //不带小数点
  194.         }
  195.         P1 |= 0x0f;
  196.         P1 &= 0xff - (0x01 << Pos);
  197. }

  198. //=================================================================
  199. // 函数名称 :void scan(float Temp)
  200. // 函数功能 :数码管动态扫描显示温度
  201. // 入口参数 :Temp 数码管上要显示的温度值
  202. // 出口参数 :无
  203. //=================================================================
  204. void DisplayTemp(void)
  205. {       
  206.         //针对4位数码管
  207.         if(tempSign==1) //负温度,不会超过 -100,百位总是0,所以只判断十位来确定在哪个位显示负号
  208.         {
  209.                 if(sw==0)
  210.                 {
  211.                         LedDispDig(1,10,0);//十位显示负号,LEDNumber中第11个元素
  212.                         delay(300);
  213.                         LedDispDig(2,gw,1); //个位,1显示小数点
  214.                         delay(300);
  215.                         LedDispDig(3,sfw,0); //小数十分位
  216.                 }
  217.                 else
  218.                 {
  219.                         LedDispDig(0,10,0);//百位显示负号,LEDNumber中第11个元素
  220.                         delay(300);
  221.                         LedDispDig(1,sw,0); //十位
  222.                         delay(300);
  223.                         LedDispDig(2,gw,1); //个位,1显示小数点
  224.                         delay(300);
  225.                         LedDispDig(3,sfw,0); //小数十分位
  226.                 }
  227.         }
  228.         else //正温度
  229.         {
  230.                 if(bw!=0)
  231.                 {
  232.                         LedDispDig(0,bw,0); //百位
  233.                         delay(300);
  234.                         LedDispDig(1,sw,0); //十位
  235.                         delay(300);
  236.                 }
  237.                 else if(sw!=0) //十位
  238.                 {
  239.                         LedDispDig(1,sw,0);
  240.                         delay(300);
  241.                 }
  242.                 LedDispDig(2,gw,1); //个位,1显示小数点
  243.                 delay(300);
  244.                 LedDispDig(3,sfw,0); //小数十分位
  245.         }
  246.         //P1 |= 0x0f;                        //显示小数点
  247.         //P1 &= 0xfb;
  248.         //P0=0x7f;
  249.         //delay(300);
  250. }

  251. //====================================================================================
  252. //函数名称:void init_serial(void)
  253. //函数功能:初始化串口
  254. //入口参数:无
  255. //出口参数:无
  256. //====================================================================================
  257. void init_serial(void)
  258. {
  259.         TMOD = 0x22;    //定时器T1使用工作方式2
  260.         TH1 = 250;     //设置初值
  261.         TL1 = 250;
  262.         TR1 = 1;      //开始计时
  263.         PCON = 0x80;     //SMOD=1;
  264.         SCON = 0x50;     //工作方式1,波特率9600bit/s,允许接收
  265.         TI = 1;
  266. }

  267. //====================================================================================
  268. //函数名称:void Tranfer(char Data)     
  269. //函数功能:发送数据程序
  270. //入口参数:Data 要发送的数据
  271. //出口参数:无
  272. //====================================================================================
  273. void Tranfer(char Data)
  274. {
  275.         while (TI == 0);
  276.         SBUF = Data;
  277.         TI = 0;
  278. }

  279. //====================================================================================
  280. //函数名称:int main(void)     
  281. //函数功能:主函数,主要用于上位机发送
  282. //入口参数:无
  283. //出口参数:无
  284. //====================================================================================
  285. int main(void)
  286. {
  287.         float Temp;

  288.         //显示LCG
  289.         LCGDisp();
  290.        
  291.         tempSign = 0;

  292.         IT1 = 1;               //负跳变方式产生中断
  293.         EX1 = 1;               //开外部中断1
  294.         EA = 1;                                 //开总中断
  295.         Init_DS18B20();
  296.         init_serial();
  297.         while (1)
  298.         {
  299.                 ReadTemperature();
  300.                 DisplayTemp();
  301.                
  302.                 Tranfer('a');
  303.                 //针对4位数码管
  304.                 if(tempSign==1) //负温度不会超过 -100,百位总是0
  305.                 {
  306.                         Tranfer('-');//发送负号
  307.                         if(sw==0) //十位为零,不发送百位和十位
  308.                         {
  309.                                 Tranfer(gw+0x30); //个位
  310.                                 Tranfer(sfw+0x30); //小数十分位
  311.                         }
  312.                         else
  313.                         {
  314.                                 Tranfer(sw+0x30); //十位
  315.                                 Tranfer(gw+0x30); //个位
  316.                                 Tranfer(sfw+0x30); //小数十分位
  317.                         }
  318.                 }
  319.                 else //第一位百位
  320.                 {
  321.                         if(bw!=0)
  322.                         {
  323.                                 Tranfer(bw+0x30); //百位
  324.                                 Tranfer(sw+0x30); //十位
  325.                         }
  326.                         else if(sw!=0) Tranfer(sw+0x30); //十位
  327.                         Tranfer(gw+0x30); //个位
  328.                         Tranfer(sfw+0x30); //小数十分位
  329.                 }
  330.                 Tranfer('b');
  331.         }
  332. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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