欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

使用STC15W408AS單片機自帶的AD轉換中遇到的問題,虛心求教

[復制鏈接]
跳轉到指定樓層
樓主
ID:601478 發表于 2019-10-14 09:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
說明:下面的程序是一個測溫程序,用的STC15W408AS自帶的AD轉換通道,P1.2 I/O口輸入被測變化電平,使用的NTC負溫度系數傳感器,現在遇到的問題是把程序燒錄進硬件,上電后在4段數碼管上顯示的轉換后的溫度值在人為加熱傳感器 的情況下數值只在上電后3到4秒內會發生變化,時間一長再怎么加熱數值也不會變了,傳感器溫度都7.80度了顯示的數值也是一開始的32度,沒變化,但是掉電后重新上電又有幾秒鐘可以正常顯示60多度的溫度值,之后又卡在那里怎樣加溫降溫顯示值也不變,感覺就是只有硬件上電初時的幾秒會工作,之后就莫名卡死跑飛,很是奇怪,程序自己看了好多遍感覺看不出什么問題,小弟剛接觸單片機,也不知道哪里寫的不對,求各路大佬好心指點一下,感激不盡

上程序:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int


typedef unsigned char BYTE;
typedef unsigned int WORD;

......
......
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEED 0x00

sbit STB = P3^3;
sbit CLK = P3^6;
sbit DIO = P3^7;
sbit KEY = P1^5;


uchar code zhuzhi[101] ={65,62, 59,...........3,2,1};//溫度對應的阻值表

void delay(uchar a)  // 延時
{
        uchar x;
        while(a--)
        {
                x = 200;
                while(x--);
        }
}


void init_ADC()  //初始化AD
{
        P1ASF = 0x06;
  delay(20);
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = ADC_POWER | ADC_SPEED;
}


WORD res_ADC(BYTE ch) //啟動轉換
{
        uint num;
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = ADC_POWER | ADC_SPEED | ADC_START | ch;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        while(!(ADC_CONTR & ADC_FLAG));
        ADC_CONTR &= ~ADC_FLAG;
        num = (ADC_RES<<2)|ADC_RESL;
        return num;
}


float are()  // 多次取值后求平均,再用公式轉成電阻值
{
        uchar i,u;
        uint a,b;
        float n;
        u = ch();
        for(i = 0;i<31;i++)
        {
                a = res_ADC(u);
                b += a;
        }
        b = b/31;
        n = b*0.1/(5.5-0.005*b);
        
        return n;
}

float are2()  //濾波
{
        uchar i;
        float l,k;
        for(i = 0;i<30;i++)
        {
                l = are();
                k += l;
        }
        k = k/30;
        return k;
}


void ADC_biao()  //查表找對應的溫度數值
{
        float r;
        uchar high,low,mid;
        low = 0;
        high = 100;
        mid = (low + high)/2;
        r = are2();
        if((zhuzhi[high]<=r) && (r<=zhuzhi[low]))
        {
                while((high - low) != 1)
                {
                        if(r<zhuzhi[mid])
                        {
                                low = mid+1;
                                mid = (low + high)/2;
                        }
                        else if(zhuzhi[mid]<r)
                        {
                                high = mid-1;
                                mid = (low+high)/2;
                        }
                        else
                        {
                                display(mid);
                        }
                }
                if((zhuzhi[low] - r) < (r - zhuzhi[high]))
                {
                        display(low);
                }
                else if((r - zhuzhi[high]) < (zhuzhi[low] - r))
                {
                        display(high);
                }
                else
                {
                        display(high);
                }
        }
        else
        {
                if(r<zhuzhi[high])
                {
                        display(high);
                }
                if(zhuzhi[low]<r)
                {
                        display(low);
                }
        }
}

void main()  //主循環
{
        P1M1 = 0;
        P1M0 = 0;
        KEY = 1;
        init_ADC();
        while(1)
        {
                ADC_biao();
                delay(25);
        }
}


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

使用道具 舉報

沙發
ID:213173 發表于 2019-10-14 11:11 | 只看該作者
你確認這個程序能通過編譯?硬件電路是什么樣的?
回復

使用道具 舉報

板凳
ID:601478 發表于 2019-10-14 13:30 | 只看該作者
wulin 發表于 2019-10-14 11:11
你確認這個程序能通過編譯?硬件電路是什么樣的?

能通過編譯,硬件電路用的開發板,具體我也不太懂
回復

使用道具 舉報

地板
ID:213173 發表于 2019-10-14 15:24 | 只看該作者
PDDDF 發表于 2019-10-14 13:30
能通過編譯,硬件電路用的開發板,具體我也不太懂

我可以負責任的對你說,你發的這個程序根本就不完整,不可能通過編譯。使用STC15W408AS芯片可以用51頭文件,但必須聲明51頭文件中不包含的特殊寄存器的地址。如:
sfr ADC_CONTR   =   0xBC;           //ADC控制寄存器
sfr ADC_RES     =   0xBD;           //ADC高8位結果
sfr ADC_LOW2    =   0xBE;           //ADC低2位結果
sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器
sfr P1M0        =   0x92;   /端口1模式寄存器0
sfr P1M1        =   0x91;   /端口1模式寄存器1
ADC轉換結果是12位,你的溫度對應的阻值表是8位數組,并且數組成員不完整。
你的數碼管顯示函數在哪里?
P1M1 = 0;P1M0 = 0;表示P1口全部是弱上拉準雙向口,應該把ADC輸入設為高阻口,如果是用P1.0口作ADC輸入應設為P1M1 = 0x01;P1M0 = 0x00;
設置P1的第0通道端口作為模擬輸入P1ASF=0x01;

回復

使用道具 舉報

5#
ID:47286 發表于 2019-10-14 20:46 | 只看該作者
用P1M0和P1M1把P1.2端口置成高阻狀態

然后 在AD的采集端 用萬用表測量電壓 如果電壓持續隨溫度變化則檢查端口配置和程序 否則檢查硬件
回復

使用道具 舉報

6#
ID:401564 發表于 2019-10-15 11:58 | 只看該作者
我用的時匯編的,看不明白你這明白
但編程的原理是一樣的,你一下子搞那么多代碼放這,哪里出了問題都可能找不到
你可以先寫一個單獨的ADC程序,也不用查表顯示什么的,不用濾波處理
簡單的:一直進行ADC再把結果輸出到一個帶LED的端口就可以了,要保證用手摸一下NTC,端口的LED就跟著變化就可以,用來驗證ADC代碼是否正確,其它功能也是這樣一步一步的來就可以了
匯編的思維就是這樣的,保證一個一個小功能正確了再去搞別的功能
順便說一下,取平均值那一段,盡可能的用整形,不要用浮點型,能用位移就不要用除法運算,在C上面它是可以正確計算的,但編譯器編譯之后就不一定是正確的算法了,你可以對比一下官方的手冊,它取平均值也是用位移的方法來計算的
回復

使用道具 舉報

7#
ID:601478 發表于 2019-10-16 09:47 | 只看該作者
Y_G_G 發表于 2019-10-15 11:58
我用的時匯編的,看不明白你這明白
但編程的原理是一樣的,你一下子搞那么多代碼放這,哪里出了問題都可能找 ...

我現在就是試著實現這塊芯片的AD轉換功能,程序的思路就是簡單的一直循環檢測輸入電平和顯示溫度值,取平均值那里我也換成整形變量了,移位求商這個真的頭一次知道,現在細節還在弄,謝謝大佬的回復
回復

使用道具 舉報

8#
ID:601478 發表于 2019-10-16 10:13 | 只看該作者
wulin 發表于 2019-10-14 15:24
我可以負責任的對你說,你發的這個程序根本就不完整,不可能通過編譯。使用STC15W408AS芯片可以用51頭文 ...

來了個大佬666
是這樣的程序的確不是完整的,我上面只發了有關AD轉換的部分,數碼管顯示部分我想著關系不大就省略沒發出來,那個阻值表是我用的NTC熱敏電阻的溫度—阻值對應表,1到100度對應的阻值,是問廠家那里拿的;p1口的狀態我改了高阻態但是還是不行;還有測溫的電路圖我不太會分析,AD轉換得到的Vout和Rt熱敏間的關系怎樣求,能麻煩大佬幫忙看下嗎,謝謝大佬回復
完整程序:
#include<reg51.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

typedef unsigned char BYTE;
typedef unsigned int WORD;


#define FOSC    11059200L

sfr P1M1 = 0x91;
sfr P1M0 = 0x92;

sfr ADC_CONTR = 0xBC;
sfr ADC_RES = 0xBD;
sfr ADC_RESL = 0xBE;
sfr P1ASF = 0x9D;
sfr CLK_DIV = 0x97;

sbit STB = P3^3;
sbit CLK = P3^6;
sbit DIO = P3^7;
sbit KEY = P1^5;

#define ADC_POWER   0x80
#define ADC_FLAG    0x10
#define ADC_START   0x08
#define ADC_SPEED   0x60

WORD num;
float n;
uchar u = 1;

void display(uchar K);
void delay(WORD n);
uchar code Duanma[10]={0xfa,0x82,0xb9,0xab,0xc3,0x6b,0x7b,0xa2,0xfb,0xe3};
uchar code zhuzhi[101]={65.83,62.54,59.43,56.49,53.72,51.10,48.62,46.28,
                              44.06,41.96,39.97,38.09,36.31,34.63,33.03,31.51,
                              30.07,28.71,27.41,26.18,25.02,23.91,22.86,21.86,
                              20.90,20.00,19.14,18.32,17.54,16.80,16.10,15.42,
                              14.78,14.17,13.59,13.04,12.51,12.00,11.52,11.06,
                              10.62,10.20,9.80,9.42,9.05,8.70,8.37,8.05,7.74,
                              7.45,7.17,6.90,6.65,6.40,6.17,5.94,5.73,5.52,5.32,5.13,
                        4.95,4.77,4.61,4.45,4.29,4.14,4.00,3.86,3.73,3.61,
                        3.48,3.37,3.25,3.15,3.04,2.94,2.85,2.75,2.67,2.58,
                        2.50,2.42,2.34,2.27,2.20,2.13,2.06,2.00,1.94,1.88,
                        1.82,1.77,1.71,1.66,1.61,1.56,1.52,1.47,1.43,1.39,
                        1.35};

void send_8bit(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                if(dat&0x01)
                {
                        DIO = 1;
                }
                else
                {
                        DIO = 0;
                }
               
                CLK = 0;
                CLK = 1;
               
                dat=dat>>1;
        }
}

void command(uchar com)
{
        STB = 1;
        STB = 0;
        send_8bit(com);
}

void display(uchar K)
{
         uchar ge,shi,bai;
   ge = K%10;
         shi = (K/10)%10;
         bai = (K/100)%10;
       
         command(0x03);
         command(0x40);
         command(0xc6);
       
        send_8bit(Duanma[bai]);              
        send_8bit(0x00);

        send_8bit(0x00);            
        send_8bit(0x00);

  send_8bit(Duanma[shi]);
        send_8bit(0x00);

        send_8bit(Duanma[ge]);
        send_8bit(0x00);

        command(0x8f);
        STB = 1;
}

void init_ADC()
{
        P1ASF = 0x06;
        delay(2);
        ADC_RES = 0;
        ADC_RESL = 0;
}

void resetADC(BYTE ch)
{
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = ADC_SPEED | ADC_START | ADC_POWER | ch;
}

void delay(WORD n)
{
        uint x;
        while(n--)
        {
                x = 500;
                while(x--);
        }
}

void get_result()
{
  while (!(ADC_CONTR & ADC_FLAG));
        ADC_CONTR &= ~ADC_FLAG;
  num = (ADC_RES<<2)|ADC_RESL;
}

WORD lvbo()
{
        WORD count;
        uchar i = 0;
        for(i = 0;i<32;i++)
        {
          resetADC(u);
    delay(2);
          get_result();
                count += num;
        }
        count = count>>5;
        return count;
}

void chselect()
{
        if(KEY == 0)
        {
                delay(5);
                if(KEY == 0)
                {
                        while(KEY == 0);
      if(2<++u) u = 1;
                }
        }
}

void data_change()
{
        WORD i;
        i = lvbo();
  n = i/(55-0.05*i);
}

void cha_biao()
{
        uint low,high,middle;
        low = 0;
        high = 100;
        middle = (high + low)/2;
        if((n<=zhuzhi[low])&&(zhuzhi[high]<=n))
        {
           while((high - low) != 1)
           {
                   if(n < zhuzhi[middle])
                   {
                           low = middle+1;
                                 middle = (high + low)/2;
                         }
                         else if(zhuzhi[middle] < n)
                   {
                                 high = middle-1;
                                 middle = (high + low)/2;
                   }
                         else
                         {
                                 if(n == zhuzhi[middle])
                                 {
                                         display(middle);
                                         return;
                                 }
                         }
                 }
                 if((zhuzhi[low]-n)<(n-zhuzhi[high]))
                 {
                         display(low);
                         return;
                 }
                 if((n-zhuzhi[high])<(zhuzhi[low]-n))
                 {
                         display(high);
                         return;
                 }
         }
        else
        {
                if(n<zhuzhi[high])
                {
                        display(high);
                        return;
                }
                if(zhuzhi[low]<n)
                {
                        display(low);
                        return;
                }
        }
}

void main()
{
        P1M1 = 0x06;
        P1M0 = 0x00;
        KEY = 1;
       
        init_ADC();
        while(1)
        {
                chselect();
    lvbo();
                resetADC(u);
    delay(2);
          get_result();
                data_change();
                cha_biao();
                delay(6);
        }
}C:\Users\Administrator\Desktop\01
回復

使用道具 舉報

9#
ID:601478 發表于 2019-10-16 10:19 | 只看該作者
dzbj 發表于 2019-10-14 20:46
用P1M0和P1M1把P1.2端口置成高阻狀態

然后 在AD的采集端 用萬用表測量電壓 如果電壓持續隨溫度變化則檢 ...

硬件應該不會有問題吧,開發板買了才不到兩個月,我還是懷疑自己的程序問題(其實在考慮要不要買個萬用表),但是又看不出是哪里出錯,哎,難搞
回復

使用道具 舉報

10#
ID:213173 發表于 2019-10-16 13:13 | 只看該作者
PDDDF 發表于 2019-10-16 10:13
來了個大佬666
是這樣的程序的確不是完整的,我上面只發了有關AD轉換的部分,數碼管顯示部分我想 ...

軟件都是基于硬件條件編寫的,把你的開發板原理圖或實物照片發上來,幫你改程序。NTC熱敏電阻的溫阻表不可以直接使用,要根據分壓電阻值計算出溫度電壓關系制作數組表格。不要追求一步完成完美的代碼,應該循序漸進,先完成基本的AD轉換,逐漸學習濾波、換算等功能。
回復

使用道具 舉報

11#
ID:10947 發表于 2019-10-16 14:27 | 只看該作者
最簡單的,你得保證P1.2腳的電壓是對的,在顯示不正常的時候,有測量過P1.2的電壓嗎
回復

使用道具 舉報

12#
ID:601478 發表于 2019-10-19 13:48 | 只看該作者
wulin 發表于 2019-10-16 13:13
軟件都是基于硬件條件編寫的,把你的開發板原理圖或實物照片發上來,幫你改程序。NTC熱敏電阻的溫阻表不 ...

方便加個QQ交流學習一下嗎,我上個回復的圖片發不出來,可以的話QQ截圖比較快
回復

使用道具 舉報

13#
ID:601478 發表于 2019-10-19 13:56 | 只看該作者
lfc315 發表于 2019-10-16 14:27
最簡單的,你得保證P1.2腳的電壓是對的,在顯示不正常的時候,有測量過P1.2的電壓嗎

萬用表剛到手,我測測看
回復

使用道具 舉報

14#
ID:491577 發表于 2019-10-20 00:58 | 只看該作者
WORD res_ADC(BYTE ch) //啟動轉換
{
        uint num;
        ADC_RES = 0;
        ADC_RESL = 0;
        ADC_CONTR = ADC_POWER | ADC_SPEED | ADC_START | ch;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        while(!(ADC_CONTR & ADC_FLAG));
        ADC_CONTR &= ~ADC_FLAG;
        num = (ADC_RES<<2)|ADC_RESL;
        return num;
}
這個函數中:num = (ADC_RES<<2)|ADC_RESL;這個不對,數據溢出了。改成:num = ((uint)ADC_RES<<2)|ADC_RESL;或者num = (uint)ADC_RES*4+ADC_RESL;
回復

使用道具 舉報

15#
ID:601478 發表于 2019-10-21 14:30 | 只看該作者
hhh402 發表于 2019-10-20 00:58
WORD res_ADC(BYTE ch) //啟動轉換
{
        uint num;

是數據溢出,不過不是這里,是另外的濾波函數,謝謝你給我的提示,問題解決了
回復

使用道具 舉報

16#
ID:601478 發表于 2019-10-21 14:32 | 只看該作者
原因找到了,濾波時數據溢出,換了變量類型就沒事了,謝謝樓上幾位老哥的回復,先結貼了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表