找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 446|回復: 4
收起左側

關于adc0809的轉換問題

[復制鏈接]
ID:1148254 發(fā)表于 2025-4-16 20:54 | 顯示全部樓層 |閱讀模式
現(xiàn)在有個很大的問題,打板焊接后我沒有模擬量輸入adc0809也會有數(shù)字量輸出,大概在90左右,換算下在in0有個1.75v左右的電壓,不確定是什么原因,然后插上GP2Y1014AU后adc輸出的數(shù)字量直接變成0,偶爾會在跳變一下。現(xiàn)在不知道怎么辦了,想換個adc芯片。下面是程序,附件是原理圖和pcb文件。順便問下我的報警電路這樣設計可以換成無源蜂鳴器嗎?第一次發(fā)這個,如果有違規(guī)的地方請和我說。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int

// LCD1602引腳
sbit lcdrs = P3^4;  // RS接P3.4
sbit lcdrw = P3^3;  // RW接P3.3
sbit lcden = P3^2;  // EN接P3.2
#define LCD_Data P1  // 數(shù)據(jù)口接P1

// ADC0809引腳
sbit clock = P2^0;  // 時鐘輸入
sbit state = P2^2;  // 啟動轉換
sbit eoc   = P2^3;  // 轉換結束
sbit oe    = P2^7;  // 輸出使能
#define adcdata P0   // 數(shù)據(jù)口接P0

// GP2Y1014AU引腳(粉塵傳感器)
sbit led = P3^7;     // LED控制

// 延時函數(shù)(11.0592MHz晶振)
void delay_us(uchar us) {
    while(--us);
}

void delay_ms(uint ms) {
    uint i, j;
    for(i = ms; i > 0; i--)
        for(j = 100; j > 0; j--); // 適配11.0592MHz,約1ms
}

// LCD寫命令
void write_com(uchar com) {
    lcdrs = 0; lcdrw = 0;
    LCD_Data = com;
    lcden = 1; delay_us(10); lcden = 0;
    delay_ms(2);
}

// LCD寫數(shù)據(jù)
void write_dat(uchar dat) {
    lcdrs = 1; lcdrw = 0;
    LCD_Data = dat;
    lcden = 1; delay_us(10); lcden = 0;
    delay_ms(1);
}

// LCD初始化
void init_lcd() {
    delay_ms(50); // 上電延時
    write_com(0x38); // 8位數(shù)據(jù),2行
    delay_ms(5);
    write_com(0x0C); // 顯示開,無光標
    delay_ms(5);
    write_com(0x06); // 光標右移
    delay_ms(5);
    write_com(0x01); // 清屏
    delay_ms(5);
}

// LCD顯示字符串
void LCD_ShowString(uchar x, uchar y, uchar *str) {
    uchar addr = (y == 0) ? (0x80 + x) : (0xC0 + x);
    write_com(addr);
    while(*str) write_dat(*str++);
}
uchar LCD_ShowNum(uchar x, uchar y, uint num) {
    uchar addr = (y == 0) ? (0x80 + x) : (0xC0 + x);
    uchar digits[5]; // 最多 5 位(uint 最大 65535)
    uchar i, len = 0;

    // 將數(shù)字轉換為字符數(shù)組,從低位到高位
    do {
        digits[len++] = (num % 10) + '0';
        num /= 10;
    } while (num > 0 && len < 5);

    // 設置顯示位置
    write_com(addr);
    // 從高位到低位顯示(反向輸出),跳過前導 0
    for (i = len; i > 0; i--) {
        write_dat(digits[i - 1]);
    }
    return len;
}

// 初始化定時器0(500kHz時鐘)
void init_timer0() {
    TMOD |= 0x02;   // 定時器0,模式2
    TH0 = 0x22;     // 500kHz @11.0592MHz
    TL0 = 0x22;
    ET0 = 1;        // 允許定時器0中斷
    EA = 1;         // 開啟總中斷
    TR0 = 1;        // 啟動定時器0
}

// 定時器0中斷服務函數(shù)(生成時鐘)
void timer0_isr() interrupt 1 {
    clock = ~clock;
}
uchar reverse_bits(uchar value) {
    uchar result = 0;
    uchar i;
    for (i = 0; i < 8; i++) {
        result <<= 1;          // 左移一位
        result |= (value & 1);  // 取最低位
        value >>= 1;            // 右移一位
    }
    return result;
}
// ADC讀取函數(shù)
uchar ADC_Read() {
    uchar adc_value;

    // 1. 啟動轉換(START下降沿)
    state = 1;
    _nop_(); _nop_();
    state = 0;

    // 2. 等待轉換開始(EOC變低)
    //while(eoc == 1);
    // 3. 等待轉換完成(EOC變高)
    while(eoc == 0);

    // 4. 讀取數(shù)據(jù)
    oe = 1;
    //adcdata = 0xFF;     // P0設置為輸入
    _nop_(); _nop_();
    adc_value =reverse_bits( adcdata);
回復

使用道具 舉報

ID:1148254 發(fā)表于 2025-4-16 20:56 | 顯示全部樓層
                return adc_value;
}
//PM2.5
uint PM_Value()
{
        uint adc_value=0;        //adc值變量
        uint PM_value =0;        //PM2.5值變量
        led=0;
        delay_us(280);
        adc_value=ADC_Read();//獲取一次adc值,并累加
        if(adc_value==0)
                return 0;
        delay_us(19);
        led=1;
        PM_value=((adc_value/255.0)*5*0.17-0.1)*1000;//計算PM2.5值
        delay_us(9680);
        return PM_value;
}
// 主函數(shù)
void main() {
                uchar i;
    init_timer0();  // 啟動ADC時鐘
    init_lcd();     // 初始化LCD
    state = 0;      // START初始低
    oe = 0;         // OE初始關閉
   
    LCD_ShowString(0, 0, "ADC Value:");
    LCD_ShowString(0, 1, "PM2.5:   ");
   
    while(1) {
        uchar val = ADC_Read();
                                uchar pm  = PM_Value();
        LCD_ShowNum(10, 0, val);  // 顯示ADC值
        i=LCD_ShowNum(6, 1, pm);   // 顯示PM2.5模擬值
                                LCD_ShowString(6+i, 1, "ug/m3   ");
        delay_ms(200);            // 控制采樣率
    }
}
這個是剩下的程序
回復

使用道具 舉報

ID:469589 發(fā)表于 2025-4-17 09:01 | 顯示全部樓層
adc0809輸入不能開路,否則可能有數(shù)字。
所以有任何電路接入則這個“干擾”會減小。
回復

使用道具 舉報

ID:940483 發(fā)表于 2025-4-17 15:29 | 顯示全部樓層
注釋掉reverse_bits:
讓ADC_Read直接返回adcdata,觀察下數(shù)值
  1. uchar ADC_Read() {
  2.     state = 1; _nop_(); state = 0;
  3.     while(eoc == 0);
  4.     oe = 1;
  5.     _nop_();
  6.     uchar adc_value = adcdata; // 移除
  7.     oe = 0;
  8.     return adc_value;
  9. }
復制代碼
如果輸入都沒有的話,ADC輸出0,就是reverse_bits導致的啦,那就是很大可能連線問題了
還有你電路圖傳在哪里?
回復

使用道具 舉報

ID:1148254 發(fā)表于 2025-4-18 15:16 | 顯示全部樓層
Tonghao666 發(fā)表于 2025-4-17 15:29
注釋掉reverse_bits:
讓ADC_Read直接返回adcdata,觀察下數(shù)值
如果輸入都沒有的話,ADC輸出0,就是rever ...

附件里面
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

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