找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 4546|回復(fù): 8
收起左側(cè)

單片機(jī)+DS18B20程序 數(shù)碼管閃爍

[復(fù)制鏈接]
ID:709561 發(fā)表于 2020-8-22 21:10 | 顯示全部樓層 |閱讀模式
DS18B20溫度顯示程序,使用74hc595控制數(shù)碼管位選【2個4位數(shù)碼管】,數(shù)碼管閃爍頻率很高,閃爍是顯示的也能看得見,不知是那一個環(huán)節(jié)出現(xiàn)了問題更改了好久無法解決,閃爍時就好像在不間斷掃描一樣???麻煩各位大佬指出。
由于拍攝無法看出數(shù)碼管閃爍所以沒有上傳照片
#include<reg52.h>
#include<intrins.h>


#define uchar unsigned char
#define uint  unsigned int
        
sbit SER  = P1^2;    //數(shù)據(jù)輸入
sbit SCK  = P1^0;    //串行移位時鐘
sbit RCK  = P1^1;    //鎖存器時鐘
sbit DQ   = P2^2;    //18B20數(shù)據(jù)輸入


uint tvalue;
uchar tflag;


uchar code tab[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
uchar data buf[5]={0,0,0,0,0xC6};//顯示緩存


void hc595(uchar Data)//74HC595的數(shù)據(jù)串入并出子程序
{
        uchar i;            
        for(i=0;i<8;i++)        //由高位到低位發(fā)送一個字節(jié)
        {
                Data<<=1;                //左移一位,最高位溢出到位寄存器CY
                SER=CY;                        //從位寄存器的進(jìn)位標(biāo)志位CY讀取
                SCK = 0;                         //串行移位
                                _nop_();
                        _nop_();
                SCK = 1;
                        _nop_();
                            _nop_();
                                SCK = 0;
        }
   RCK = 0;                 //鎖存
   _nop_();
                _nop_();
   RCK = 1;
        _nop_();
                _nop_();
   RCK = 0;
}


void delay(unsigned int n)


{


unsigned int i,j;


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


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


}




void delay_18B20(uchar i)
{
        while(i--);
}


void ds1820()  //初始化
{
        uchar x=0;
        DQ = 1;
        delay_18B20(4);
        DQ = 0;
        delay_18B20(100);;
        DQ = 1;
        delay_18B20(40);;
}
uchar ds1820rd()  //讀數(shù)據(jù)
{
        uchar i=0;
        uchar dat=0;
        for(i=8;i>0;i--)
        {
                DQ=0;
                dat>>=1;
                DQ=1;
                if(DQ)
                dat|=0x80;
                delay_18B20(10);;
        }
        return(dat);
}
void ds1820wr(uchar wdata)  //寫數(shù)據(jù)
{
        uchar i=0;
        for(i=8;i>0;i--)
        {
                DQ=0;
                DQ=wdata&0x01;
                delay_18B20(10);;
                DQ=1;
                wdata>>=1;
        }
}


uint read_temp()
{
        uchar a,b;
        ds1820();
        ds1820wr(0xcc);  //跳過讀序列號
        ds1820wr(0x44);  //啟動溫度轉(zhuǎn)化
        ds1820();
        ds1820wr(0xcc);  //跳過讀序列號
        ds1820wr(0xbe);  //啟動溫度轉(zhuǎn)化
        a=ds1820rd();
        b=ds1820rd();
        tvalue=b;
        tvalue<<=8;
        tvalue=tvalue|a;
        if(tvalue<0x0fff)
                tflag=0;
        else
        {
                tvalue=~tvalue+1;
                tflag=1;
        }
        tvalue=tvalue*(0.625);  //溫值擴(kuò)大10倍精確到1位小數(shù)
        return(tvalue);
}
void ds1820disp()
{
        static uchar k=0;
        buf[0]=tab[tvalue/1000];  //百位數(shù)
        buf[1]=tab[tvalue%1000/100];  //十位數(shù)
        buf[2]=tab[tvalue%100/10]&0x7f;  //個位數(shù)
        buf[3]=tab[tvalue%10];  //小數(shù)
        P0=0xFF;
        hc595(0x01<<k);
        P0=buf[k];
        k++;
        k%=5;
        
}






void main()
{
        ds1820();
        while(1)
        {
                ds1820disp();
                read_temp();
               
        }
}


回復(fù)

使用道具 舉報

ID:782419 發(fā)表于 2020-8-23 08:47 | 顯示全部樓層
數(shù)碼管顯示一般在定時器中斷程序執(zhí)行定時刷新,同時要注意消隱。
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2020-8-23 11:59 | 顯示全部樓層
造成數(shù)碼管閃爍的原因是樓主的主程序循環(huán)周期時間太長,達(dá)到8.2ms,5個數(shù)碼管掃描一輪需要41ms,遠(yuǎn)超20ms極限。由于操作18B20耗時6.3ms,占時過長,把read_temp()函數(shù)分3次完成,就可以使主循環(huán)周期平均約2.5ms,5個數(shù)碼管掃描一輪小于20ms。完美解決數(shù)碼管閃爍問題。
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5.         
  6. sbit SER  = P1^2;    //數(shù)據(jù)輸入
  7. sbit SCK  = P1^0;    //串行移位時鐘
  8. sbit RCK  = P1^1;    //鎖存器時鐘
  9. sbit DQ   = P2^2;    //18B20數(shù)據(jù)輸入

  10. uint  Temp;
  11. uchar tflag;
  12. uchar code tab[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  13. uchar data buf[5]={0,0,0,0,0xC6};//顯示緩存


  14. void hc595(uchar Data)//74HC595的數(shù)據(jù)串入并出子程序
  15. {
  16.         uchar i;            
  17.         for(i=0;i<8;i++)        //由高位到低位發(fā)送一個字節(jié)
  18.         {
  19.                 Data<<=1;            //左移一位,最高位溢出到位寄存器CY
  20.                 SER=CY;              //從位寄存器的進(jìn)位標(biāo)志位CY讀取
  21.                 SCK = 0;             //串行移位
  22.                 _nop_();
  23.                 _nop_();
  24.                 SCK = 1;
  25.                 _nop_();
  26.                 _nop_();
  27.                 SCK = 0;
  28.         }
  29.                 RCK = 0;              //鎖存
  30.                 _nop_();
  31.                 _nop_();
  32.                 RCK = 1;
  33.                 _nop_();
  34.                 _nop_();
  35.                 RCK = 0;
  36. }
  37. /*
  38. void delay(unsigned int n)
  39. {
  40.         unsigned int i,j;
  41.         for(j=n;j>0;j--)
  42.                 for(i=112;i>0;i--);
  43. }
  44. */
  45. void delay_18B20(uchar i)
  46. {
  47.         while(i--);
  48. }

  49. void ds1820()  //初始化
  50. {
  51.         uchar x=0;
  52.         DQ = 1;
  53.         delay_18B20(4);
  54.         DQ = 0;
  55.         delay_18B20(100);
  56.         DQ = 1;
  57.         delay_18B20(40);
  58. }
  59. uchar ds1820rd()  //讀數(shù)據(jù)
  60. {
  61.         uchar i=0;
  62.         uchar dat=0;
  63.         for(i=8;i>0;i--)
  64.         {
  65.                 DQ=0;
  66.                 dat>>=1;
  67.                 DQ=1;
  68.                 if(DQ)
  69.                 dat|=0x80;
  70.                 delay_18B20(10);
  71.         }
  72.         return(dat);
  73. }
  74. void ds1820wr(uchar wdata)  //寫數(shù)據(jù)
  75. {
  76.         uchar i=0;
  77.         for(i=8;i>0;i--)
  78.         {
  79.                 DQ=0;
  80.                 DQ=wdata&0x01;
  81.                 delay_18B20(10);
  82.                 DQ=1;
  83.                 wdata>>=1;
  84.         }
  85. }

  86. void read_temp()
  87. {
  88.         static uchar c=0;
  89.         uint tvalue;
  90.         uchar a,b;
  91.         switch(c)
  92.         {
  93.                 case 0:
  94.                         ds1820();
  95.                         ds1820wr(0xcc);  //跳過讀序列號
  96.                         ds1820wr(0x44);  //啟動溫度轉(zhuǎn)化
  97.                         break;
  98.                 case 1:
  99.                         ds1820();
  100.                         ds1820wr(0xcc);  //跳過讀序列號
  101.                         ds1820wr(0xbe);  //啟動溫度轉(zhuǎn)化
  102.                         break;
  103.                 case 2:
  104.                         a=ds1820rd();
  105.                         b=ds1820rd();
  106.                         tvalue=b;
  107.                         tvalue<<=8;
  108.                         tvalue=tvalue|a;
  109.                         if(tvalue<0x0fff)
  110.                                 tflag=0;
  111.                         else
  112.                         {
  113.                                 tvalue=~tvalue+1;
  114.                                 tflag=1;
  115.                         }
  116.                         Temp=tvalue*(0.625);  //溫值擴(kuò)大10倍精確到1位小數(shù)
  117.                         break;
  118.         }
  119.         c++;
  120.         c%=3;
  121. }

  122. void ds1820disp()
  123. {
  124.         static uchar k=0;
  125.         switch(k)
  126.         {
  127.                 case 0:         if(tflag)buf[0]=0xbf;
  128.                                         else buf[0]=tab[Temp/1000]; break;//百位數(shù)
  129.                 case 1: buf[1]=tab[Temp%1000/100]; break;//十位數(shù)
  130.                 case 2: buf[2]=tab[Temp%100/10]&0x7f; break;//個位數(shù)
  131.                 case 3: buf[3]=tab[Temp%10]; break;//小數(shù)
  132.                 case 4: break;//"C"
  133.         }       
  134.         P0=0xff;
  135.         hc595(0x01<<k);
  136.         P0=buf[k];
  137.         k++;
  138.         k%=5;        
  139. }

  140. void main()
  141. {
  142.         ds1820();
  143.         while(1)
  144.         {
  145.                 read_temp();
  146.                 ds1820disp();
  147.         }
  148. }
復(fù)制代碼

評分

參與人數(shù) 1黑幣 +10 收起 理由
1P1P + 10 最具有說服力的解答 洞察羽翼

查看全部評分

回復(fù)

使用道具 舉報

ID:72088 發(fā)表于 2020-8-23 12:32 | 顯示全部樓層
讀取18B20需要750ms,所以閃爍,即便你更改18B20到9位精度,讀取時間也超過了人眼最低掃描頻率
回復(fù)

使用道具 舉報

ID:709561 發(fā)表于 2020-8-23 20:01 | 顯示全部樓層
wulin 發(fā)表于 2020-8-23 11:59
造成數(shù)碼管閃爍的原因是樓主的主程序循環(huán)周期時間太長,達(dá)到8.2ms,5個數(shù)碼管掃描一輪需要41ms,遠(yuǎn)超20ms極 ...

多謝大佬的解答,這個超出20ms極限,確實(shí)沒有想到一直以為是自己寫程序那個環(huán)節(jié)的問題�。。�
經(jīng)過此次問題的解答,感覺自己還是不夠嚴(yán)謹(jǐn),以后要加強(qiáng)自己在軟件與硬件間的微小變化��!
回復(fù)

使用道具 舉報

ID:709561 發(fā)表于 2020-8-23 20:03 | 顯示全部樓層
新鄉(xiāng)家電維修 發(fā)表于 2020-8-23 12:32
讀取18B20需要750ms,所以閃爍,即便你更改18B20到9位精度,讀取時間也超過了人眼最低掃描頻率

這個問題確實(shí)沒有考慮到,多謝大佬的提示解答
回復(fù)

使用道具 舉報

ID:65956 發(fā)表于 2020-8-28 09:26 | 顯示全部樓層
開一個定時器專門給顯示驅(qū)動用的,定時時間按你實(shí)際情況調(diào)試一下就OK了
回復(fù)

使用道具 舉報

ID:693480 發(fā)表于 2022-5-2 02:16 | 顯示全部樓層
aking991 發(fā)表于 2020-8-28 09:26
開一個定時器專門給顯示驅(qū)動用的,定時時間按你實(shí)際情況調(diào)試一下就OK了

會不會在執(zhí)行動態(tài)數(shù)碼管掃描時影響ds18b20讀取時序啊,一般我們操作這個溫感都是關(guān)中斷執(zhí)行的
回復(fù)

使用道具 舉報

ID:105782 發(fā)表于 2024-12-28 19:52 | 顯示全部樓層
路過,觀摩觀摩
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表