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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1797|回復: 4
打印 上一主題 下一主題
收起左側

STC89C52單片機DS18B20程序調試問題求助

[復制鏈接]
跳轉到指定樓層
樓主
最近在學習DS18B20外設時,接觸到了單總線協議。按照DS18B20的DataSheet寫了一版程序后,發現一直無法正常顯示溫度,最后發現是延時的問題,但具體原理一直沒想明白。

單片機芯片為STC89C52,晶振為11.0592MHz。一個_nop_()約為1.085us。

這是我寫的源代碼:
  1.                 #include<reg52.h>
  2.                 #include<intrins.h>
  3.                 #define uchar unsigned char
  4.                 #define uint unsigned int
  5.                
  6.                 sbit DX=P2^6;//(P0為數碼管輸出端口)
  7.                 sbit WX=P2^7;
  8.                 sbit DS18B20_IO=P2^2;
  9.                
  10.                 uchar code Table_D[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  11.                 uchar code Table_W[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
  12.                
  13.                 uchar DS18B20_Reset_OK;
  14.                 uint num;
  15.                
  16.                 void Delay_Us(uint x);
  17.                 void Delay_Ms(uint x);
  18.                 void Display(uint x);
  19.                
  20.                 void DS18B20_Init();
  21.                 void DS18B20_Write_Byte(uchar command);
  22.                 uchar DS18B20_Read_Byte();
  23.                 uint Start_DS18B20();
  24.                
  25.                
  26.                 void main()
  27.                 {
  28.                         while(1)
  29.                         {
  30.                                 num=Start_DS18B20();
  31.                                 Display(num);
  32.                         }
  33.                 }
  34.                
  35.                 void Delay_Us(uint x)//11.0592MHz,一個nop為1.085us
  36.                 {
  37.                         uint a;
  38.                         for(a=x;a>0;a--)
  39.                         {
  40.                                 _nop_();
  41.                         }
  42.                 }
  43.                
  44.                
  45.                 void DS18B20_Init()
  46.                 {
  47.                         DS18B20_IO=1;
  48.                         Delay_Us(2);
  49.                         DS18B20_IO=0;
  50.                         Delay_Us(500);
  51.                         DS18B20_IO=1;
  52.                         Delay_Us(60);
  53.                         if(DS18B20_IO==0)
  54.                         {DS18B20_Reset_OK=1;}
  55.                         else
  56.                         {DS18B20_Reset_OK=0;}
  57.                         Delay_Us(500);
  58.                 }
  59.                
  60.                 void DS18B20_Write_Byte(uchar command)
  61.                 {
  62.                         uchar i,temp;
  63.                         temp=command;
  64.                         
  65.                         for(i=0;i<8;i++)
  66.                         {
  67.                                 DS18B20_IO=0;
  68.                                 _nop_();_nop_();

  69.                                         DS18B20_IO=temp&0x01;
  70.                                 Delay_Us(10);//?????
  71.                                         //Delay_Us(60);

  72.                                 DS18B20_IO=1;
  73.                                 _nop_();_nop_();
  74.                                 temp=temp>>1;
  75.                         }
  76.                         Delay_Us(10);
  77.                 }
  78.                
  79.                 uchar DS18B20_Read_Byte()
  80.                 {
  81.                         uchar i,temp1,temp2;
  82.                         
  83.                         for(i=0;i<8;i++)
  84.                         {
  85.                                 DS18B20_IO=0;
  86.                                 _nop_(); _nop_();
  87.                                 DS18B20_IO=1;
  88.                                 _nop_(); _nop_();
  89.                                 temp1=DS18B20_IO;
  90.                                 temp2=(temp2)>>1|(temp1<<7);
  91.                                 Delay_Us(60);
  92.                         }
  93.                         
  94.                         return temp2;
  95.                 }
  96.                
  97.                 uint Start_DS18B20()
  98.                 {
  99.                         uchar a,b;
  100.                         uint temp=0;
  101.                         DS18B20_Init();
  102.                         DS18B20_Write_Byte(0xcc);
  103.                         DS18B20_Write_Byte(0x44);
  104.                         DS18B20_Init();
  105.                         DS18B20_Write_Byte(0xcc);
  106.                         DS18B20_Write_Byte(0xbe);                        
  107.                         a=DS18B20_Read_Byte();
  108.                         b=DS18B20_Read_Byte();
  109.                         temp=b;
  110.                         temp=(temp<<8)|a;
  111.                         temp=temp*0.0625*10+0.5;
  112.                         
  113.                         return temp;
  114.                 }
  115.                
  116.                
  117.                

  118.                
  119.                 void Delay_Ms(uint x)
  120.                 {
  121.                         uint a,b;
  122.                         for(a=x;a>0;a--)
  123.                         {
  124.                                 for(b=0;b<1000;b++)
  125.                                 {_nop_();}
  126.                         }
  127.                 }
  128.                                 
  129.                
  130.                 void Display(uint x)
  131.                 {
  132.                         P0=0xff;
  133.                         WX=1;
  134.                         WX=0;
  135.                         P0=Table_D[x/100];
  136.                         DX=1;
  137.                         DX=0;
  138.                         P0=Table_W[0];
  139.                         WX=1;
  140.                         WX=0;               
  141.                         Delay_Ms(1);
  142.                         
  143.                         P0=0xff;
  144.                         WX=1;
  145.                         WX=0;
  146.                         P0=Table_D[x%100/10]|0x80;
  147.                         DX=1;
  148.                         DX=0;
  149.                         P0=Table_W[1];
  150.                         WX=1;
  151.                         WX=0;        
  152.                         Delay_Ms(1);
  153.                         
  154.                         P0=0xff;
  155.                         WX=1;
  156.                         WX=0;
  157.                         P0=Table_D[x%100%10];
  158.                         DX=1;
  159.                         DX=0;
  160.                         P0=Table_W[2];
  161.                         WX=1;
  162.                         WX=0;
  163.                         Delay_Ms(1);
  164.                 }
復制代碼

現在字節寫入那里是:
  1. DS18B20_IO=temp&0x01;
  2. Delay_Us(10);//?????
  3. //Delay_Us(60);
復制代碼
運行結果如下:



按照DataSheet,一位數據的讀/要持續最少60us,最大120us的時間。



如果我將字節寫入部分改成:

  1. DS18B20_IO=temp&0x01;
  2. //Delay_Us(10);
  3. Delay_Us(60);
復制代碼
運行結果如下:




我又參考了一下該開發板上外設的DS18B20例程,發現使用的都是非精確延時。
  1. void delayus(uint t)   //微秒級的延時函數
  2. {
  3.         while(t--);
  4. }
復制代碼
  1. void ds_write_byte(uchar dat)   //寫一個字節函數
  2. {
  3.         uchar i;
  4.         for(i=0;i<8;i++)      //循環8次
  5.         {
  6.                 ds=0;          //把總線拉為低電平
  7.                 _nop_();        //延時一機器周期,約1微秒
  8.                 ds=dat&0x01;    //dat寫0x01按位與,目的是先傳送dat的最低位
  9.                 delayus(6);      //延時,讓整個讀時序持續60~120微秒
  10.                 ds=1;          //把總線釋放,讓ds等于1
  11.                 dat=dat>>1;     //讓dat右移一位,準備下一位的寫入
  12.         }
  13.                 delayus(6);     //延時,讓每個函數之間都有一定的間隔停頓
  14. }
復制代碼
  1. void ds_reset()    //單總線初始化函數
  2. {
  3.         ds=1;           //總線先置高,讓ds等于1
  4.         delayus(5);      //稍延時
  5.         ds=0;          //主機發送復位脈沖
  6.         delayus(80);    //延時(在480~960ms之間)
  7.         ds=1;          //釋放總線,讓ds等于1
  8.         delayus(14);    //等待(15~60ms)
  9.         if(ds==0)      //判斷總線ds是否等于0
  10.                 flag=1;    //flag等于1表示DS18B20存在
  11.         else
  12.                 flag=0;    //flag等于0表示DS18B20不存在。
  13.         delayus(20);
  14. }
復制代碼

可是我用Keil的仿真模式查看了一下延時時間,發現和DataSheet以及注釋都對不上,讓我有點想不明白。
這兩個時間差也不夠60us啊,Project Option那晶振頻率設的也是11.0592MHz,這個問題確實沒搞懂



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:213173 發表于 2021-10-25 06:27 | 只看該作者
  1. //測試條件12.0MHz晶振/12T MCU,如采用11.0592MHz晶振延時時間*1.085倍
  2. #include "reg51.h"

  3. typedef unsigned char uchar;
  4. typedef unsigned int uint;

  5. /*------------------------------------------------
  6. uS延時函數,含有輸入參數 unsigned char t
  7. 大致延時長度如下 T=t*2+5us
  8. ------------------------------------------------*/
  9. void Delay_2xtus(uchar t)
  10. {   
  11.         while(--t);
  12. }
  13. /*------------------------------------------------
  14. uS延時函數,含有輸入參數 unsigned uint t
  15. 大致延時長度如下 T=t*8+6us
  16. ------------------------------------------------*/
  17. void Delay_8xtus(uint t)
  18. {   
  19.         while(--t);
  20. }
  21. /*------------------------------------------------
  22. uS延時函數,含有輸入參數 unsigned char t
  23. 大致延時長度如下 T=t*6+11us
  24. ------------------------------------------------*/
  25. void delay_6xtus(uchar t)
  26. {      
  27.         while(t--);
  28. }
  29. /*------------------------------------------------
  30. uS延時函數,含有輸入參數 unsigned int t
  31. 大致延時長度如下 T=t*9+16us
  32. ------------------------------------------------*/
  33. void delay_9xtus(uint t)
  34. {      
  35.         while(t--);
  36. }
  37. /*------------------------------------------------
  38. mS延時函數,含有輸入參數 unsigned char t
  39. 大致延時1mS
  40. ------------------------------------------------*/
  41. void Delay_ms(uchar t)
  42. {
  43.         while(t--)
  44.         {
  45.                 Delay_2xtus(243);
  46.                 Delay_2xtus(242);
  47.         }
  48. }

  49. void main()
  50. {
  51.         Delay_2xtus(100);
  52.         Delay_ms(100);
  53.         Delay_8xtus(100);
  54.         delay_9xtus(100);
  55.         delay_6xtus(100);

  56.         while(1);
  57. }
  58. //不同數據類型和寫法的延時時間區別
  59. /*
  60.         unsigned char i=10;//2um
  61.         while(--i);//i*2um

  62.         unsigned int i=10;//4um
  63.         while(--i);//i*8us

  64.         unsigned char i=10;//2um
  65.         while(i--);//i*2+2um

  66.         unsigned int i=10;//4um
  67.         while(i--);//i*8+8us
  68. */
復制代碼
回復

使用道具 舉報

板凳
ID:916650 發表于 2021-10-25 11:23 | 只看該作者

感謝大佬,驗證后發現原來的精確延時方法確實有問題
  1.                 void Delay_Us(uint x)//11.0592MHz,一個nop為1.085us
  2.                 {
  3.                         uint a;
  4.                         for(a=x;a>0;a--)
  5.                         {
  6.                                 _nop_();
  7.                         }
  8.                 }
復制代碼


之前做的實驗對時序的要求沒那么嚴格,導致沒發現這種精確延時方法有問題。
將10us的精確延時改成
  1.                 void Delay_Us_10()
  2.                 {
  3.                         _nop_();_nop_();_nop_();
  4.                         _nop_();_nop_();_nop_();
  5.                 }
復制代碼

就好了
回復

使用道具 舉報

地板
ID:123289 發表于 2021-10-25 16:23 | 只看該作者
這個不難解決,去研讀DS18B20手冊,特別是它的讀寫時序部分。再對比一下,你的程序對它的操作時序,能滿足手冊上的要求嗎?
回復

使用道具 舉報

5#
ID:916650 發表于 2021-10-25 17:02 | 只看該作者
yzwzfyz 發表于 2021-10-25 16:23
這個不難解決,去研讀DS18B20手冊,特別是它的讀寫時序部分。再對比一下,你的程序對它的操作時序,能滿足 ...

嗯,您說的很對。最后發現是精確延時函數有問題,導致延時的時間并不是理想的定義的uint x的時間,超過了DataSheet要求的最大值120us,導致最后輸出數據紊亂。確實是時序沒對好導致的。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩国产一区二区三区不卡 | 亚洲高清一区二区三区 | 中文字幕在线电影观看 | 国产一在线 | 国内在线视频 | 超碰免费在线观看 | 成人精品一区二区 | 狠狠操天天干 | 欧美黄色片在线观看 | 亚洲国产精久久久久久久 | 午夜精品久久久久久久久久久久久 | 国产精品视频一区二区三区 | 亚洲国产成人av | 黄色一级大片在线免费看产 | 青青草在线播放 | 视频二区国产 | 欧美黄在线观看 | 欧美99久久精品乱码影视 | 免费h在线| 国产亚洲人成a在线v网站 | 国产在线精品一区二区 | 欧美日韩18 | 99精品欧美一区二区三区综合在线 | 久久国产精品久久久久久 | 正在播放一区二区 | 夜夜爽99久久国产综合精品女不卡 | 日韩综合一区 | 一级亚洲 | 亚洲综合热 | 亚洲综合国产精品 | 成人免费视频 | 国产有码| 99国产精品99久久久久久 | 国产一区二区在线91 | 欧美成年黄网站色视频 | 九九热这里只有精品在线观看 | 日韩欧美一区二区三区四区 | 国产精品永久免费 | 91精品一区二区三区久久久久久 | 午夜精品久久久久久久久久久久久 | 日韩欧美视频免费在线观看 |