找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 4728|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

pic單片機(jī)數(shù)碼管顯示實(shí)時溫度問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:187532 發(fā)表于 2017-9-28 21:46 | 只看該作者 回帖獎勵 |正序?yàn)g覽 |閱讀模式
3黑幣
代碼如下:
#include <pic.h>           //調(diào)用PIC16F87XA單片機(jī)的頭文件


__CONFIG(HS&WDTDIS&LVPDIS);
unsigned char temp1;
unsigned char temp2;
unsigned char buf,buf1,buf2;
//轉(zhuǎn)換后的溫度值小數(shù)點(diǎn)部分查表
const unsigned char table[16]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};
//---------------------------------------
//數(shù)碼管字形表,供顯示時查詢
const unsigned char LED[11]=
{                          //定義表格一定要使用const,這樣會做到程序存儲區(qū)中
    0B00111111,            //"0"的字形表,0x3F
    0B00000110,            //"1"的字形表,0x06
    0B01011011,            //"2"的字形表,0x5B
    0B01001111,            //"3"的字形表,0x4F
    0B01100110,            //"4"的字形表,0x66
    0B01101101,            //"5"的字形表,0x6D
    0B01111101,            //"6"的字形表,0x7D
    0B00000111,            //"7"的字形表,0x07
    0B01111111,            //"8"的字形表,0x7F
    0B01101111,            //"9"的字形表,0x6F
  0B10000000,                //.
   
};

//---------------------------------------
//4位數(shù)碼管相關(guān)I/O設(shè)置
#define U5A  RB0           //4位數(shù)碼管單元的U5(74HC138)的A腳接在RB0口上
#define U5B  RB1           //4位數(shù)碼管單元的U5(74HC138)的B腳接在RB1口上
#define U5C  RB2           //4位數(shù)碼管單元的U5(74HC138)的C腳接在RB2口上

//名稱:復(fù)位DS18B20函數(shù)

unsigned char Reset(void)
{
        unsigned int i;   
        unsigned char k;       
        TRISA4=0;                                //設(shè)置RA4位輸出口
        RA4=0;                                     //拉低DQ總線開始復(fù)位       
           i=67;                                     //保持DQ低大約870uS,符合不低于480US的要求
           while(i>0)                             //保持DQ低大約870uS,符合不低于480US的要求
       i--;                               //保持DQ低大約870uS,符合不低于480US的要求       
    TRISA4=1;               //設(shè)置RA4為輸入口,以釋放總線等電阻拉高總線
    i=6;                                    //大約78uS后,判斷是否復(fù)位成功
           while(i>0)                            //大約78uS后,判斷是否復(fù)位成功
       i--;                              //大約78uS后,判斷是否復(fù)位成功
        if(RA4==0)                             //讀出數(shù)據(jù)并保存
                   k=0;     
        else
                k=1;
           i=31;                                            //維持約400US,符合總讀時隙不低于480US的要求
           while(i>0)                            //維持約400US,符合總讀時隙不低于480US的要求
       i--;                              //維持約400US,符合總讀時隙不低于480US的要求
           return k;               //k=0為復(fù)位成功,k=1為復(fù)位失敗
}


//名稱:寫字節(jié)函數(shù)

void WriteByte(unsigned char dat)
{
        unsigned int i;
           unsigned char j;
           for(j=0;j<8;j++)
           {            
                if(dat&0x01)                        //如果寫1
              {      
                        TRISA4=0;                        //設(shè)置RA4位輸出口
                           RA4=0;                                 //拉低      
                 NOP();                       //維持6US,符合大于1US小于15US的規(guī)范
                 NOP();                       //維持6US,符合大于1US小于15US的規(guī)范   
                        NOP();                       //維持6US,符合大于1US小于15US的規(guī)范
                 NOP();                       //維持6US,符合大于1US小于15US的規(guī)范
                        NOP();                       //維持6US,符合大于1US小于15US的規(guī)范
                 NOP();                       //維持6US,符合大于1US小于15US的規(guī)范      
                 TRISA4=1;           //設(shè)置RA4為輸入口,以釋放總線等電阻拉高總線        
                 i=5;                                  //維持約63US,符合不低于60US的要求
                 while(i>0)                  //維持約63US,符合不低于60US的要求
                         i--;                     //維持約63US,符合不低于60US的要求
                }
              else                                        //如果寫0
              {         
                        TRISA4=0;                        //設(shè)置RA4位輸出口   
                        RA4=0;                                 //拉低                 
                 i=5;                                //維持約63US,符合不低于60US的要求
                 while(i>0)                        //維持約63US,符合不低于60US的要求
                         i--;                    //維持約63US,符合不低于60US的要求        
                 TRISA4=1;           //設(shè)置RA4為輸入口,以釋放總線等電阻拉高總線                
                 NOP();                       //維持2US,符合大于1US的規(guī)范
                 NOP();                       //維持2US,符合大于1US的規(guī)范                   
              }
                dat=dat>>1;                                //寫入字節(jié)右移1位
        }
}

//名稱:讀字節(jié)函數(shù)

unsigned char ReadByte(void)
{
        unsigned int i;
           unsigned char j,buf=0;
           for(j=1;j<=8;j++)                        //接收8次還原一個字節(jié)數(shù)據(jù)
           {
                buf=buf>>1;                          //接收前,先將接收緩沖區(qū)右移
                TRISA4=0;                                //設(shè)置RA4位輸出口   
                RA4=0;                                         //拉低      
              NOP();                               //維持2US,符合大于1US小于15US的規(guī)范
        NOP();                               //維持2US,符合大于1US小于15US的規(guī)范       
              TRISA4=1;               //設(shè)置RA4為輸入口,以釋放總線等電阻拉高總線 準(zhǔn)備讀               
                NOP();                               //維持6US,符合大于1US小于15US的規(guī)范
        NOP();                               //維持6US,符合大于1US小于15US的規(guī)范
                NOP();                               //維持6US,符合大于1US小于15US的規(guī)范
        NOP();                               //維持6US,符合大于1US小于15US的規(guī)范
                NOP();                               //維持6US,符合大于1US小于15US的規(guī)范
        NOP();                               //維持6US,符合大于1US小于15US的規(guī)范               
                if(RA4==1) buf|=0x80;          //讀出1位數(shù)據(jù)保存于buf中最高位
                i=4;                                          //維持約52US,符合總讀時隙不低于60US的要求
              while(i>0)                          //維持約52US,符合總讀時隙不低于60US的要求
                      i--;                             //維持約52US,符合總讀時隙不低于60US的要求
        }
           return buf;                     //退出的同時將接收緩沖區(qū)參數(shù)返回       
}


//名稱:啟動讀溫度函數(shù)

unsigned char Convert(void)
{
        unsigned int i;
    if(Reset()==0)                    //如果復(fù)位成功
        {  
                i=77;                                         //延時約1000US
              while(i>0)                                 //延時約1000US
                      i--;                            //延時約1000US
        WriteByte(0xcc);             // 跳過多器件識別
        WriteByte(0x44);             // 啟動溫度轉(zhuǎn)換
                return 1;
    }
        else
        {
                return 0;
        }
}


//名稱:讀溫度函數(shù)

void ReadFlash(void)
{
        unsigned int i;
    unsigned char Lsb,Msb;            
    if(Reset()==0)
        {  
                i=77;                                         //延時約1000US
              while(i>0)                                 //延時約1000US
                      i--;                            //延時約1000US
        WriteByte(0xcc);              // 跳過多器件識別
        WriteByte(0xbe);              // 讀暫存器
        Lsb=ReadByte();               // 低字節(jié)
        Msb=ReadByte();                     // 高字節(jié)
                temp2=Lsb&0x0f;                //LSB的低4位為小數(shù)部分
                temp1=(Lsb>>4)|(Msb<<4);//LSB的高4位和MSB拼成整數(shù)部分
    }   
        else
        {
                temp1=0;
                temp2=0;
        }
}
void tempture()
{
        if(Convert()==1)                                 //啟動轉(zhuǎn)換
                {                            
                    ReadFlash();                       //讀取溫度                           
                if(temp1>99) temp1=99;                         
                         if(temp2>15) temp2=0;         
                        buf=temp1/10;                                                 
                        buf1=temp1%10;       
                        buf2=table[temp2&0x0f];
       
               
                                       
                }
}
//---------------------------------------
//名稱: 主函數(shù)

//---------------------------------------
void main(void)            //主函數(shù),單片機(jī)開機(jī)后就是從這個函數(shù)開始運(yùn)行
{

    unsigned int c=0;     //定義一個char型變量,做延時用
    unsigned char d=0;     //定義一個char型變量,控制顯示位置

    TRISB=0B11111000;      //初始化RB7-RB0的輸入輸出方向
    TRISD=0B00000000;      //初始化RD7-RD0的輸入輸出方向
    PORTB=0B00000000;      //初始化RB7-RB0的數(shù)值
    PORTD=0B00000000;      //初始化RD7-RD0的數(shù)值

    while(1)               //死循環(huán),單片機(jī)初始化后,將一直運(yùn)行這個死循環(huán)
    {
               
                    tempture();
                        for(c=0;c<20;c++);//做一個0-250的循環(huán),不執(zhí)行其他操作,只為延時
                PORTD=0;           //關(guān)一次顯示,以免顯示出鬼影
                if(++d>3) d=0;     //先將d加1,然后判斷是否大于3,大于3歸零
                if(d==0)           //如果d=0,顯示千位
                {
                    U5A=0;         //U5A=0,U5B=0,U5C=0,選通數(shù)碼管的千位進(jìn)行顯示
                    U5B=0;         //U5A=0,U5B=0,U5C=0,選通數(shù)碼管的千位進(jìn)行顯示
                    U5C=0;         //U5A=0,U5B=0,U5C=0,選通數(shù)碼管的千位進(jìn)行顯示
                    PORTD=LED[buf];          //溫度整數(shù)部分十位
                }
                else if(d==1)      //如果d=1,顯示百位
                {
                    U5A=1;         //U5A=1,U5B=0,U5C=0,選通數(shù)碼管的百位進(jìn)行顯示
                    U5B=0;         //U5A=1,U5B=0,U5C=0,選通數(shù)碼管的百位進(jìn)行顯示
                    U5C=0;         //U5A=1,U5B=0,U5C=0,選通數(shù)碼管的百位進(jìn)行顯示       
                    PORTD=LED[buf1];  //溫度整數(shù)部分個位
                }
                else if(d==2)      //如果d=2,顯示十位
                {
                    U5A=0;         //U5A=0,U5B=1,U5C=0,選通數(shù)碼管的十位進(jìn)行顯示
                    U5B=1;         //U5A=0,U5B=1,U5C=0,選通數(shù)碼管的十位進(jìn)行顯示
                    U5C=0;         //U5A=0,U5B=1,U5C=0,選通數(shù)碼管的十位進(jìn)行顯示
                    PORTD=LED[10];  //十位顯示"2"
                }
                else if(d==3)      //如果d=3,顯示個位
                {
                    U5A=1;         //U5A=1,U5B=1,U5C=0,選通數(shù)碼管的個位進(jìn)行顯示
                    U5B=1;         //U5A=1,U5B=1,U5C=0,選通數(shù)碼管的個位進(jìn)行顯示
                    U5C=0;         //U5A=1,U5B=1,U5C=0,選通數(shù)碼管的個位進(jìn)行顯示
                    PORTD=LED[buf2];  //溫度小數(shù)部分
                }
            }
       
}

   我用四位數(shù)碼管顯示實(shí)時溫度,顯示的現(xiàn)象有微小閃爍,跪求大神們?nèi)绾谓鉀Q,幫忙改一下代碼。

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

使用道具 舉報(bào)

樓主
ID:123289 發(fā)表于 2017-9-28 23:53 | 只看該作者
1、建議每4ms切換一個LED顯示,或更短時間�!疽曈X殘留】
2、切換時先關(guān)全體,然后送“數(shù)字”,再開需要顯示的LED�!窘徊罡蓴_】
3、“關(guān)全體”之前,必須先將“數(shù)字”準(zhǔn)備好,不可在“關(guān)全體后,才始處理“數(shù)字”�!撅@示效率】
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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