找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 5148|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)讀取溫度數(shù)碼管顯示程序,最后一位明顯更亮,求解釋

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:426640 發(fā)表于 2018-11-26 01:29 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
今天通過(guò)DS18B20讀取溫度并通過(guò)LED數(shù)碼管顯示,最后一位明顯更亮,為啥呢?


下面是我的函數(shù)
3個(gè)文件:頭文件,DS18B20系列子函數(shù)文件,主函數(shù)部分(既數(shù)據(jù)處理和顯示部分)

頭文件:
#ifndef __TEMP_H_
#define __TEMP_H_

#include<reg52.h>
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint  
#define uint unsigned int
#endif

sbit DSPORT=P2^2;


void Delay1ms(uint );
uchar Ds18b20Init();
void Ds18b20WriteByte(uchar com);
uchar Ds18b20ReadByte();
void  Ds18b20ChangTemp();
void  Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

#endif


DS18B20系列子函數(shù)文件

#include"temp.h"
/*******************************************************************************
*            : Delay1ms


*******************************************************************************/

void Delay1ms(uint y)
{
        uint x;
        for( ; y>0; y--)
        {
                for(x=110; x>0; x--);
        }
}
/*******************************************************************************
*            : Ds18b20Init
*                   : ʼ
*              :
*              : ʼɹ1ʧܷ0
*******************************************************************************/

uchar Ds18b20Init()
{
        uchar i;
        DSPORT = 0;                         //-480us~960us
        i = 70;         
        while(i--);
        DSPORT = 1;  
        i = 0;
        while(DSPORT)
        {
                Delay1ms(1);
                i++;
                if(i>5)//ȴ>5MS
                {
                        return 0;
                }

        }
        return 1;
}

/*******************************************************************************
*            : Ds18b20WriteByt
*              :
*              :
*******************************************************************************/

void Ds18b20WriteByte(uchar dat)
{
        uint i, j;

        for(j=0; j<8; j++)
        {
                DSPORT = 0;
                i++;
                DSPORT = dat & 0x01;
                i=6;
                while(i--);  
                DSPORT =  1;  
                dat >>= 1;
        }
}
/*******************************************************************************
*            : Ds18b20ReadByte


*******************************************************************************/


uchar Ds18b20ReadByte()
{
        uchar byte, bi;
        uint i, j;         
        for(j=8; j>0; j--)
        {
                DSPORT = 0;
                i++;
                DSPORT = 1;
                i++;
                i++;
                bi = DSPORT;

                byte = (byte >> 1) | (bi << 7);                                               
                i = 4;
                while(i--);
        }                                 
        return byte;
}
/*******************************************************************************
*            : Ds18b20ChangTemp
*              :
*              :
*******************************************************************************/

void  Ds18b20ChangTemp()
{
        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);  
        Ds18b20WriteByte(0x44);           
//        Delay1ms(100);

}
/******************************************************************************* *******************************************************************************/

void  Ds18b20ReadTempCom()
{         

        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);         
        Ds18b20WriteByte(0xbe);         
}
/******************************************************************************* *******************************************************************************/

int Ds18b20ReadTemp()
{
        uchar temp = 0;
        uchar tmh, tml;
        Ds18b20ChangTemp();        
        Ds18b20ReadTempCom();
        tml = Ds18b20ReadByte();
        tmh = Ds18b20ReadByte();
        /*temp = tmh;
        //temp <<= 8;
        temp |= tml;*/
        tml>>=4;
        tmh<<=4;
        temp=tml|tmh;
        return temp;
}


主函數(shù)部分
#include "reg52.h"        
#include"temp.h"         

#define u16 unsigned int
#define u8 unsigned char  


sbit numchoose=P2^6;
sbit wela=P2^7;

/*this code is the num form 0 to F in the LED tube*/
u8 duanxuantable[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};


char num=0;
u8 DisplayData[8];
//u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

/*******************************************************************************
*            : delay
*                   i=1時(shí)延時(shí)10us
*******************************************************************************/
void delay(u16 i)
{
        while(i--);         
}


/******************************************************************************處理讀取的原碼,使之成為對(duì)應(yīng)溫度值 并存儲(chǔ)正負(fù)符號(hào)于DisplayData[0]
*******************************************************************************/
u8 datapros(u8 temp)           
{
           float tp;   
        if(temp>127)   
          {
                DisplayData[0] = 0x40;
                temp=temp-1;
                temp=~temp;
                tp=temp;
//                temp=tp/2;
                temp=tp*0.0625*100+0.5;         

          }
         else
          {                        
                DisplayData[0] = 0x00;
                tp=temp;
                temp=tp*0.625+0.5;         
        }

        return temp;
}


/******************************************************************************函數(shù)名: display
功能:顯示輸入的unsigned char型溫度的數(shù)值在2、34位,第一位顯示正負(fù)
輸入:   讀取并處理后的溫度
輸出:   無(wú)
*******************************************************************************/
void display(u8 num)
{
        u8 weitable[]={0,0,0,0};
        weitable[0]=DisplayData[0];
        weitable[1]=num/100;
        weitable[2]=(num/10)%10;
        weitable[3]=num%10;
        wela=1;
        P0=0xfe;
        wela=0;
        numchoose=1;
        P0=duanxuantable[weitable[0]];
        numchoose=0;
        delay(50);

        wela=1;
        P0=0xfd;
        wela=0;
        numchoose=1;
        P0=duanxuantable[weitable[1]];
        numchoose=0;
        delay(50);         

        wela=1;
        P0=0xfb;
        wela=0;
        numchoose=1;
        P0=duanxuantable[weitable[2]];
        numchoose=0;
        delay(50);

        wela=1;
        P0=0xf7;
        wela=0;
        numchoose=1;
        P0=duanxuantable[weitable[3]];
        numchoose=0;
        delay(50);         
}
/*******************************************************************************
*          : main
*                 :  
*            :
*                  :  
*******************************************************************************/
void main()
{         
        while(1)
        {
                /*datapros(Ds18b20ReadTemp());         //ݴ  
                DigDisplay();
                while(1)
                {
                        display(datapros(Ds18b20ReadTemp()));
                }
        }                 
}


不知道為什么KEIL上編譯的文件的中文部分下下來(lái)就亂碼了。。。。,抱歉

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

使用道具 舉報(bào)

沙發(fā)
ID:213173 發(fā)表于 2018-11-26 07:36 | 只看該作者
是因?yàn)檫@個(gè)動(dòng)態(tài)顯示程序有嚴(yán)重缺陷,個(gè)位數(shù)碼管顯示的時(shí)間比其他位占用時(shí)間過(guò)長(zhǎng)。表面上看各位的延時(shí)都一樣,實(shí)際在主循環(huán)運(yùn)行其他程序的時(shí)間里個(gè)位一直在顯示。顯示程序中的數(shù)據(jù)分解語(yǔ)句也很占用時(shí)間,這個(gè)時(shí)段個(gè)位也一直在顯示。
回復(fù)

使用道具 舉報(bào)

板凳
ID:202748 發(fā)表于 2018-11-26 09:01 | 只看該作者
用三極管驅(qū)動(dòng),會(huì)避免這問(wèn)題。當(dāng)然,用別的IC驅(qū)動(dòng)會(huì)更好。
回復(fù)

使用道具 舉報(bào)

地板
ID:426640 發(fā)表于 2018-11-26 13:37 | 只看該作者
wulin 發(fā)表于 2018-11-26 07:36
是因?yàn)檫@個(gè)動(dòng)態(tài)顯示程序有嚴(yán)重缺陷,個(gè)位數(shù)碼管顯示的時(shí)間比其他位占用時(shí)間過(guò)長(zhǎng)。表面上看各位的延時(shí)都一樣 ...

理解了,我改了一下程序,確實(shí)是這個(gè)原因,謝謝大佬
回復(fù)

使用道具 舉報(bào)

5#
ID:413475 發(fā)表于 2018-11-26 15:01 | 只看該作者
1.最后一位和第一位數(shù)碼管之間的延時(shí)較大造成的,這么理解,在處理完一次顯示之后,單片機(jī)讀取18B20的時(shí)間太久
2.建議把void display(u8 num) { …… }內(nèi)最后一個(gè)delay(50); 減小或取消,數(shù)碼管的亮度應(yīng)該會(huì)比較均勻
回復(fù)

使用道具 舉報(bào)

6#
ID:113187 發(fā)表于 2018-11-26 16:11 | 只看該作者
應(yīng)該是占空比不一樣導(dǎo)致的
回復(fù)

使用道具 舉報(bào)

7#
ID:426640 發(fā)表于 2018-11-26 16:23 | 只看該作者
Colin_zhai 發(fā)表于 2018-11-26 15:01
1.最后一位和第一位數(shù)碼管之間的延時(shí)較大造成的,這么理解,在處理完一次顯示之后,單片機(jī)讀取18B20的時(shí)間太 ...

非常感謝您的建議,在一樓點(diǎn)明我的問(wèn)題后我就做了這樣的嘗試,效果并不明顯。主要是原因是讀取溫度的函數(shù)所需時(shí)間太長(zhǎng)了,達(dá)到了肉眼可見(jiàn)的閃爍的地步。我對(duì)主函數(shù)的顯示做了如下修改,使得數(shù)碼管顯示亮度均勻,但是還是有點(diǎn)小瑕疵
void main()
{       
        u8 temp;
        u16 i;
        while(1)
        {
                while(1)
                {
                        display(temp);
                        temp=datapros(Ds18b20ReadTemp());
                        for(i=500;i>0;i--)
                        {
                                display(temp);
                        }
                }
        }               
}
那就是讀取溫度函數(shù)運(yùn)行的時(shí)候數(shù)碼管會(huì)閃爍一下
回復(fù)

使用道具 舉報(bào)

8#
ID:433516 發(fā)表于 2018-11-26 16:45 | 只看該作者
你把延時(shí)設(shè)對(duì)了,就可以了!不過(guò)也有其他問(wèn)題(包括你的上拉電阻,自己測(cè)一下硬件電路,測(cè)完就剩軟件了)
回復(fù)

使用道具 舉報(bào)

9#
ID:853568 發(fā)表于 2021-12-20 09:34 | 只看該作者
我下載下來(lái)怎么數(shù)碼管全亮
回復(fù)

使用道具 舉報(bào)

10#
ID:939710 發(fā)表于 2021-12-21 10:03 | 只看該作者
你要想一樣亮可以把數(shù)碼管動(dòng)態(tài)掃描放中斷里
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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