久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3529|回復: 8
收起左側

51單片機,18B20,1602溫度計+串口通信,實際溫度計 上位機程序VS2010 C++ MFC

  [復制鏈接]
ID:417092 發表于 2020-11-21 01:11 | 顯示全部樓層 |閱讀模式
制作出來的實物圖如下:
02.jpg 01.jpg

05.jpg

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
06.jpg

上位機:
03.jpg 04.jpg VS2010 C   MFC.PNG

安裝程序解壓到同一目錄下。再運行setup安裝。。。。

溫度計.exe
編寫環境Win10 x64.     VS2010 x86  C++ MFC
測試環境Win10 x64.   

在32位系統上,能不能正常使用還不清楚。
所以公布了源代碼文件,如果在32位系統上,不能正常使用。
請使用源代碼文件,在32位系統上重新生成一下應用程序。。。

單片機源程序如下:
  1. #include <reg52.h>
  2. #include "math.h"

  3. bit flag1s = 0, _up = 0;          //1s定時標志
  4. unsigned char T0RH = 0;  //T0重載值的高字節
  5. unsigned char T0RL = 0;  //T0重載值的低字節

  6. void ConfigTimer0(unsigned int ms);
  7. unsigned char IntToString(unsigned char *str, int dat);
  8. extern bit Start18B20();
  9. extern bit Get18B20Temp(int *temp);
  10. extern void InitLcd1602();
  11. extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

  12. //串口初始化函數
  13. void InitUART()
  14. {
  15.                 //IP = 0x10;
  16.                 TMOD &= 0x0F;
  17.     TMOD |= 0x20;
  18.     SCON = 0x50;
  19.     TH1 = 0xF3;
  20.     TL1 = TH1;
  21.     PCON = 0x00;
  22.     EA = 1;
  23.     ES = 1;
  24.     TR1 = 1;
  25. }

  26. //串口發送1字節數據
  27. void SendOneByte(unsigned char c)
  28. {
  29.     SBUF = c;
  30.     while(!TI);
  31.     TI = 0;
  32. }
  33. void main()
  34. {
  35.     bit res;
  36.     int temp, former=0xffff;        //讀取到的當前溫度值
  37.     int intT, decT;  //溫度值的整數和小數部分
  38.     unsigned char len;
  39.     unsigned char str[12];
  40.                
  41.                 IP = 0x10;
  42.                 InitUART();
  43.     // EA = 1;            //開總中斷
  44.     ConfigTimer0(10);  //T0定時10ms
  45.     Start18B20();      //啟動DS18B20
  46.     InitLcd1602();     //初始化液晶
  47.    
  48.     while (1)
  49.     {
  50.         if (flag1s || _up)  //每秒更新一次溫度
  51.         {
  52.             flag1s = 0;
  53.             res = Get18B20Temp(&temp);  //讀取當前溫度
  54.             if (res && ((abs(temp-former) >= 4)||_up))                 //讀取成功時,刷新當前溫度顯示
  55.             {
  56.                                                                 former = temp;                                                                //記錄新的溫度
  57.                                                                 _up = 0;
  58.                                                                 SendOneByte((unsigned char) (temp/256));
  59.                                                                 SendOneByte((unsigned char) (temp%256));
  60.                 intT = temp >> 4;             //分離出溫度值整數部分
  61.                 decT = temp & 0xF;            //分離出溫度值小數部分
  62.                 len = IntToString(str, intT); //整數部分轉換為字符串
  63.                 str[len++] = '.';             //添加小數點
  64.                 decT = (int)((decT*100) * 0.0625 + 0.5);        //二進制的小數部分轉換為1位十進制位
  65.                 str[len++] = decT/10 + '0';      //十進制小數位再轉換為ASCII字符
  66.                                                                 str[len++] = decT%10 + '0';
  67.                                                                 str[len++] = 'C';
  68.                 while (len < 7)               //用空格補齊到6個字符長度
  69.                 {
  70.                     str[len++] = ' ';
  71.                 }
  72.                 str[len] = '\0';              //添加字符串結束符
  73.                 LcdShowStr(0, 0, str);        //顯示到液晶屏上
  74.             }
  75.             else                        //讀取失敗時,提示錯誤信息
  76.             {
  77.                                                                 if(!res)
  78.                                                                         LcdShowStr(0, 0, "error!");
  79.             }
  80.             Start18B20();               //重新啟動下一次轉換
  81.         }
  82.     }
  83. }
  84. /* 整型數轉換為字符串,str-字符串指針,dat-待轉換數,返回值-字符串長度 */
  85. unsigned char IntToString(unsigned char *str, int dat)
  86. {
  87.     signed char i = 0;
  88.     unsigned char len = 0;
  89.     unsigned char buf[6];
  90.    
  91.     if (dat < 0)  //如果為負數,首先取絕對值,并在指針上添加負號
  92.     {
  93.         dat = -dat;
  94.         *str++ = '-';
  95.         len++;
  96.     }
  97.     do {          //先轉換為低位在前的十進制數組
  98.         buf[i++] = dat % 10;
  99.         dat /= 10;
  100.     } while (dat > 0);
  101.     len += i;     //i最后的值就是有效字符的個數
  102.     while (i-- > 0)   //將數組值轉換為ASCII碼反向拷貝到接收指針上
  103.     {
  104.         *str++ = buf[i] + '0';
  105.     }
  106.     *str = '\0';  //添加字符串結束符
  107.    
  108.     return len;   //返回字符串長度
  109. }
  110. /* 配置并啟動T0,ms-T0定時時間 */
  111. void ConfigTimer0(unsigned int ms)
  112. {
  113.     unsigned long tmp;  //臨時變量
  114.    
  115.     tmp = 12000000 / 12;      //定時器計數頻率
  116.     tmp = (tmp * ms) / 1000;  //計算所需的計數值
  117.     tmp = 65536 - tmp;        //計算定時器重載值
  118.     tmp = tmp + 15;           //補償中斷響應延時造成的誤差
  119.     T0RH = (unsigned char)(tmp>>8);  //定時器重載值拆分為高低字節
  120.     T0RL = (unsigned char)tmp;
  121.     TMOD &= 0xF0;   //清零T0的控制位
  122.     TMOD |= 0x01;   //配置T0為模式1
  123.     TH0 = T0RH;     //加載T0重載值
  124.     TL0 = T0RL;
  125.     ET0 = 1;        //使能T0中斷
  126.     TR0 = 1;        //啟動T0
  127. }
  128. /* T0中斷服務函數,完成1秒定時 */
  129. void InterruptTimer0() interrupt 1
  130. {
  131.     static unsigned char tmr1s = 0;
  132.    
  133.     TH0 = T0RH;  //重新加載重載值
  134.     TL0 = T0RL;
  135.     tmr1s++;
  136.     if (tmr1s >= 100)  //定時1s
  137.     {
  138.         tmr1s = 0;
  139.                                 if(!flag1s)
  140.                                         flag1s = 1;
  141.     }
  142. }

  143. //串口中斷服務函數,
  144. void UARTInterrupt(void) interrupt 4
  145. {
  146.                 char ch=0;
  147.     if(RI)
  148.     {
  149.         RI = 0;
  150.                                 ch = SBUF;
  151.                                 if((ch=='1') && !_up)
  152.                                         _up = 1;
  153.         //add your code here!
  154.     }/*
  155.     else
  156.         TI = 0;*/
  157. }
復制代碼
51hei.png
所有資料51hei提供下載:
溫度計。單片機 仿真.rar (106.64 KB, 下載次數: 55)
溫度計。上位機.rar (130.59 KB, 下載次數: 46)
安裝程序.7z (13.13 MB, 下載次數: 36)

評分

參與人數 2黑幣 +110 收起 理由
changhz + 10
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:417092 發表于 2020-11-21 20:19 | 顯示全部樓層
更正說明。。。。
設計開發時,一直用的是開發板。

顯示的都是實時溫度。。。。采集不到負溫度。。。。
今天自己在仿真中發現。。。當負溫度時,1602和電腦上顯示不一樣,而且兩個都與DS18B20顯示不一樣。。。
查找原因,發現思路沒錯,細節決定成敗。。。

在C51中,
int i;
-32768<= i <= 32767

unsigned int  i;
0 <=  i   <=  65535

unsigned char LSB, MSB;

當i為int變量時。

i = (int)MSB<<8;

i += LSB    與    i |= LSB  兩者的區別是什么。。。


當i為int變量時。
MSB = i/256; LSB = i%256;      與     MSB = i>>8;    LSB =  i & 0xff    的區別是什么呀。。。。。

找到原因,才知道很簡單。。。。
1、修改了DS18B20.c中的讀溫度函數。。。。
2、修改了main.c中轉換字符串函數。。。。。
有一句話與大家共勉。。。。。。。。
編程入門很重要,養成良好的書寫習慣,才是編程的必修課。。。。

keil.rar

45.46 KB, 下載次數: 19, 下載積分: 黑幣 -5

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:417092 發表于 2020-11-21 01:19 | 顯示全部樓層
忘了,還有一個工具,仿真需虛擬串口

vspd.zip

4.72 MB, 下載次數: 15, 下載積分: 黑幣 -5

回復

使用道具 舉報

ID:328014 發表于 2020-11-21 01:52 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:417092 發表于 2020-11-21 04:24 | 顯示全部樓層
51hei團團 發表于 2020-11-21 01:52
好資料,51黑有你更精彩!!!

團團,早上好
回復

使用道具 舉報

ID:23844 發表于 2020-11-21 07:49 | 顯示全部樓層
51黑有你更精彩!!!下載一份有空學習一下
回復

使用道具 舉報

ID:414573 發表于 2020-11-21 14:00 | 顯示全部樓層
好東東
回復

使用道具 舉報

ID:417092 發表于 2020-11-21 22:02 | 顯示全部樓層

捕獲.PNG
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品二区 | 日韩精品在线看 | 成人在线小视频 | 欧美午夜剧场 | 黄色免费网址大全 | 国产精品永久免费 | 久久这里只有精品首页 | 成人一区二区三区在线观看 | 国产h在线 | 在线观看中文字幕一区二区 | 伊人狠狠| 久久午夜视频 | 欧美精品一区二区三区在线播放 | 亚洲精品欧美精品 | 在线播放一区 | 91精品成人久久 | 天天天操操操 | h视频免费观看 | 亚洲精品一区二区三区四区高清 | 欧美精品一区在线 | 日韩成年人视频在线 | 精品久久中文 | 亚洲一区中文字幕在线观看 | 国产一级一级国产 | 99re视频 | 97色在线观看免费视频 | 一二区视频 | 狠狠干在线 | 手机av在线 | 天天澡天天操 | 久久99精品久久久 | 国产精品视频在 | 在线中文字幕av | 日韩欧美中文字幕在线观看 | 久久久久九九九女人毛片 | 午夜精品久久久久久久99黑人 | 正在播放国产精品 | 成年免费大片黄在线观看一级 | 日本涩涩网 | 九九一级片 | 日韩视频一区在线观看 |