亚洲春色中文字幕久久久-三上亚,91精品国产亚一区二区三区,久久久九色综合亚洲成色777,涩涩视频下载,国产午夜亚洲精品午夜鲁丝片,国产精品A一区二区三区腾讯导航,影音先锋色情AV在线看片,蜜臀国产在线视频,极品少妇高潮啪啪无码吴梦梦 ,精品人妻无码一区二区三区手机版

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

關于ADC0832的誤差有疑問

[復制鏈接]
跳轉到指定樓層
樓主
ID:1159547 發表于 2025-10-20 10:22 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我現在用ADC0832采集數據,0832的基準電壓測出來實際是4.95V,剛開始是采集后的數據顯示到數碼管上,但是有誤差,于是就改為將電壓值發送到串口進行顯示,現在串口顯示數據為4.51V的時候,輸入電壓測出來實際值為4.77V,有0.2v的誤差,有沒有大神知道這誤差怎么來的,以及如何解決呢。感謝。
這是我的程序,寫的有點亂,因為修改了好多次,見諒。

#include<reg52.h>
#include<intrins.h>

/***********ad0832與單片機的接口定義**********************/
sbit CS =P3^2;                 
sbit CLK=P3^3;
sbit OUT=P3^4;
sbit DI=P3^5;

float key;
unsigned char code tab[]={        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                                        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
unsigned char temdat[]={0,0,0};  



unsigned char adc0832(void);
void display(unsigned char *pl);
void delayms(unsigned char t);
void uart_init(void);
void send_string(unsigned char *str);



void main(void)
{
        float tep;
        unsigned char string[10];  // "X.XXV\r\n"共6個字符
        unsigned int integer_part;  // 整數部分(0~5)
        unsigned int decimal_part;  // 小數部分(0~99,代表0.00~0.99)
        uart_init();
       
       
       
        while(1)
        {
               
                tep = (5.0 / 255.0) * adc0832();  // 正確計算電壓值
                integer_part = (unsigned int)tep;  // 提取整數部分(如3.85→3)
                decimal_part = (unsigned int)((tep - integer_part) * 100 + 0.5);  // 提取兩位小數(+0.5是四舍五入)

                // 構造字符串(例如 "3.85V\r\n")
                string[0] = integer_part + '0';       // 整數位(3→'3')
                string[1] = '.';                      // 小數點
                string[2] = (decimal_part / 10) + '0'; // 小數第一位(85/10=8→'8')
                string[3] = (decimal_part % 10) + '0'; // 小數第二位(85%10=5→'5')
                string[4] = 'V';
                string[5] = '\r';
                string[6] = '\n';
                string[7] = '\0';
               
               
                send_string(string);
        
        delayms(1000);// 間隔1秒
        }
}
/*********************************************
**函數描述:AD采樣函數
**寫入參數:無
**返回參數:電壓0-5V對應的8位二進制數即0—255
************************************************/
unsigned char adc0832(void)
{
        unsigned char i;
        unsigned int l_key;
       
        OUT=1;
    CLK=0;
        _nop_();_nop_();       
       
        CS=0;
        DI=1;
        _nop_();_nop_();//大于等于500ns       
        _nop_();_nop_();
        _nop_();_nop_();
        CLK=1;
        _nop_();_nop_();
        CLK=0;
        DI=1;
        _nop_();_nop_();               
        CLK=1;
        _nop_();_nop_();
        CLK=0;
        DI=0;
        _nop_();_nop_();               
        CLK=1;
        _nop_();_nop_();
       
        CLK=0;
        _nop_();_nop_();
        CLK=1;
        _nop_();_nop_();       
        CLK=0;
               
        for(i=0;i<8;i++)
        {
                l_key<<=1;
                if(OUT)
                        l_key++;
                CLK=1;
                _nop_();_nop_();
                CLK=0;
                _nop_();_nop_(); //兩個時鐘下降延后就輸出第一個數據,是一個同步串行通信協議
        }
        CS=1; //結束讀取
       
       
        return l_key;
}
/********************************************************
**名稱:顯示子函數      
**功能:動態掃描P2口做為位選,P0口送段碼
**輸入:pl指向要顯示數據的地址,最后3位
**返回:無
*******************************************************/
void display(unsigned char *pl)
{
        P2=0x04;
        P1=tab[*pl];                     //低
        delayms(3);
        P1=0xff;
       
        P2=0x02;
        P1=tab[*(pl+1)];                    //中
        delayms(3);
        P1=0xff;
       
        P2=0x01;
        P1=tab[*(pl+2)]&0x7f;   //高        //高位數碼管總是帶小數,因為電壓的范圍:0—5V
        delayms(3);
        P1=0xff;                 
}

void delayms(unsigned char t)
{
        unsigned char x,y;
        for(x=t;x>0;x--)
                for(y=110;y>0;y--);
}



//串口配置
void uart_init(void)
{
       
       
       
        PCON |= 0x80;                //使能波特率倍速位SMOD
        SCON  = 0x50;       //允許接收中斷,其中包括REN=1
        TMOD &= 0x0F;                //設置定時器模式
        TMOD |= 0x20;            //設置定時器1為方式2自動重載
        TH1   = 0xf3;       //波特率4800 (11.0592MHz晶振)
        TL1   = 0xf3;
        ET1   = 0;              //禁止定時器1自身中斷
        TR1   = 1;                        //啟動定時器1
        EA    = 1;          //打開總中斷
        ES    = 1;          //打開串口中斷
       
       


}

// 發送一個字節
void sendbyte(unsigned char byte)
{
        SBUF = byte;
        while(TI == 0);    //等待發送完成
        TI = 0;            //清除發送標志
}

// 發送字符串
void send_string(unsigned char *str)        //*str表示這是一個字符型指針,用于接收要發送的字符串的首地址
{
    while(*str != '\0')
    {
        sendbyte(*str);
        str++;  
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:332444 發表于 2025-10-20 11:28 | 只看該作者
作為單通道模擬信號輸入時ADC0832的輸入電壓是0~5V,且8位分辨率時的電壓精度為19.53mV。注意需要處理小數。
回復

使用道具 舉報

板凳
ID:879809 發表于 2025-10-20 16:57 | 只看該作者
應該是這句 tep = (5.0 / 255.0) * adc0832(); 把誤差放大了。
回復

使用道具 舉報

地板
ID:1133081 發表于 2025-10-20 17:20 | 只看該作者
計算方法不佳導致擴大誤差。以下結果是mV。
        ADC = adc0832();  // 讀取ADC
        tep = (5000 * (long)ADC / 256) ;  // 計算電壓值 (mV)
回復

使用道具 舉報

5#
ID:469589 發表于 2025-10-20 18:15 | 只看該作者
只有8位分辨率的片子,有這誤差非常好了。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

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