痞酷網_PIGOO

 找回密碼
 立即註冊
!!! [系統偵測到廣告阻擋軟體] !!!

如果您覺得痞酷網對您有些許幫助,或者您認同痞酷網的理想,

那麼希望您將痞酷網設定為白名單.

並請在上論壇的時候,動動您的手指,用行動支持我們.

謝謝!
查看: 5596|回復: 16

求助: AD轉換練習出了問題 已經解決!!

  [複製鏈接]
發表於 2012-12-24 01:08:34 | 顯示全部樓層 |閱讀模式
本帖最後由 antlu 於 2012-12-24 11:23 PM 編輯

各位先進大大:
   又要麻煩大家幫忙了!!
   AD練習.png

  這是我最近的 A/D 練習,因為從回收場拿到 10K R-2R電阻,和 74LS373 所以就用它來作 A/D轉換,工作構想是 利用 D/A 送出256階的數位信號給 74LS373 鎖定讓它輸出給 R-2R 再把輸出交給 OP LM1458 放大(需要正負電源,所以用 34063轉-5V給OP使用),OP輸出交給比較器作2組比較其中一組是 電壓輸入,用來查看電壓的功能AD1,另外一組是溫度NTC電阻,用來顯示目前的溫度AD2 ,現在問題來了,...
   我把程式設定送出第一組 0~255 並且判斷是否輸出超過電壓,若超過則給 P2^1 信號,讀取 0~255的當時值,再利用當時值*一數值以便轉換成 電壓顯示於 1602.接下來送第二組 0~255 並且判斷是否輸出超過溫度NTC電阻電壓,若超過則給 P2^2 信號,讀取 0~255的當時值,再利用當時值*一數值以便轉換成 溫度顯示於 1602.
    意想不到的結果: 大部分時間只能顯示第二組,除非第一組的電壓調到一定值(如圖 123附近 2.34V)
網拍a07 [800].JPG

   假如我把 P2^2的PIN拔掉,那第一組電壓的顯示就正常了...
請問: 為何會如此呢? 我常是把LM1458輸出各串上10K電阻給 LM393的輸入,卻都不會動作,我把電阻降到1K 有改善會交互動作...

網拍a06 [800].JPG

網拍a05 [800].JPG

網拍a04 [800].JPG

網拍a03 [800].JPG

網拍a02 [800].JPG

網拍a01 [800].JPG

發表於 2012-12-24 08:57:02 | 顯示全部樓層
因程式設為超過設定,才讀值,故OP的輸出要為"1",一定要輸入電壓過大, P2.2方為"1",LCD才會有顯示值,而拔掉P2.2,即強迫P2.2為 "1",故能顯示讀值.
 樓主| 發表於 2012-12-24 10:12:34 | 顯示全部樓層
ciko.ciko 發表於 2012-12-24 08:57 AM static/image/common/back.gif
因程式設為超過設定,才讀值,故OP的輸出要為"1",一定要輸入電壓過大, P2.2方為"1",LCD才會有顯示值,而拔掉P2 ...

ciko.ciko大:
     我的現象是 P2^2拔開(為HI) 的時候 P2^1才會有HI的動作,為何無法 P2^1 P2^2都會動作?
   比方說 D/A輸出3V 而比較器1輸入為2V 比較器2輸入為2.5V這時候是不是應該輸出都是HI才對!!
   我程式因為同一段送出0~4.5V的 STEP 卻導致不正確動作,後來我修改程式為兩段,第一段輸出0V~比較器1的STEP電壓 比較器1反轉後紀錄並停止輸出,再來第二段輸出0~比較器2的STEP電壓直到比較器2反轉後紀錄並停止,然後再顯示 比較器1與比較器2的紀錄值.
發表於 2012-12-24 13:14:14 | 顯示全部樓層
antlu 發表於 2012-12-24 10:12 AM static/image/common/back.gif
ciko.ciko大:
     我的現象是 P2^2拔開(為HI) 的時候 P2^1才會有HI的動作,為何無法 P2^1 P2^2都會動作?  ...

1.將OP的提升電組拔掉再試試,有可能是與8952內部提升電阻,產升負載效應.
2.如若不行拔掉OP至8952的接線,直接測試OP部分的電路功能,是否正常.
3.再不行,直接從 P2.1,P2.2輸入"0,1"不同信號,測試軟體功能.
發表於 2012-12-24 13:53:23 | 顯示全部樓層
另外要留意的是,OP輸出為"0"時,其電壓約為-5V,需注意是否會造成8952異常現象.
發表於 2012-12-24 21:59:21 | 顯示全部樓層
本帖最後由 popcorn 於 2012-12-24 10:00 PM 編輯

我不懂線路,但早年有維修TTL一點經驗
圖2 3 AD1:出現12數字殘影,LCM供壓是否過高或12數字顯示時間過長留下

如果確定線路正確,被操過的74LS373可能會有熱損誤動作
我會在74LS373 pin1&20 加一顆優質.1u/50V

DSCI6234.JPG
 樓主| 發表於 2012-12-24 22:30:36 | 顯示全部樓層
ciko.ciko 發表於 2012-12-24 01:53 PM static/image/common/back.gif
另外要留意的是,OP輸出為"0"時,其電壓約為-5V,需注意是否會造成8952異常現象.

ciko.ciko大:
  今天確認一些問題,對換兩個比較器,發現問題還是在 "電壓輸入"的輸入端,因為只要是他電壓低於2.8V就不行了(不顯示)就算是接到 P2^7也是一樣,除非把另外一個比較器的輸出拔掉不接.我在比較器的- 輸入串一個10K電阻結果有相同,先前有把 1458輸出串接電阻10K電阻也沒有用!!
發表於 2012-12-24 23:14:58 | 顯示全部樓層
antlu 發表於 2012-12-24 10:30 PM static/image/common/back.gif
ciko.ciko大:
  今天確認一些問題,對換兩個比較器,發現問題還是在 "電壓輸入"的輸入端,因為只要是他電壓 ...

阿乾大,請確認我在4樓建議的檢測流程,並告知這3項的各別測試結果, 以便進一步確認問題所在.
OP的輸出入關係正常嗎?
 樓主| 發表於 2012-12-24 23:18:12 | 顯示全部樓層
popcorn 發表於 2012-12-24 09:59 PM static/image/common/back.gif
我不懂線路,但早年有維修TTL一點經驗
圖2 3 AD1:出現12數字殘影,LCM供壓是否過高或12數字顯示時間過長留 ...

popcorn大;
  感謝!! 問題已經解決了!! 我的程式出的問題!! 東改改西改改已經解決了!! 問題應該出在 我一開始用 while(1)...時間上面較無法掌握,最後改放在中斷服務程式裡面每秒鐘執行一次,就ok了!! 可見時序很重要!!
 樓主| 發表於 2012-12-24 23:22:13 | 顯示全部樓層
ciko.ciko 發表於 2012-12-24 01:53 PM static/image/common/back.gif
另外要留意的是,OP輸出為"0"時,其電壓約為-5V,需注意是否會造成8952異常現象.

ciko.ciko大:
  問題已經解決,比較器不是問題,是時序上面的錯亂!!
程式如下:
一個D/A轉換給2個比較器達到2組A/D的功能,解析度 255階,大家參考

/* 20121224  P0 LCM display P1 DtoA convert mith R-2R+74LS373 P2^0 hi/lo active sent to LM4558 op amp volt ,34063 neg 5v generator LM393 comparator for P2^1 bit ,loop d/a must clear each cycle                         */
#define ADPortL P1//P1.0~P1.7 AD574 low 8bit
#include<reg52.h>
#include<stdio.h>
#include <intrins.h>
#define DataPort P0//P0.0~P0.7 1602 LCM顯示器
#define  _Nop()  _nop_()        //定义空指令
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
sbit RS = P2^4;//P1^0;//LCM指令Lo/資料Hi
sbit RW = P2^5;//P1^1;//讀出 Hi/寫入Lo
sbit EN = P2^6;//P1^2;//動作觸發 Hi>>Lo
char DisplayWord[16];//顯示第一行工作的狀況
char Displaychar[16];// 顯示第二行工作的狀況
unsigned char  counter;         //T0使用的1/100計數器.
unsigned char  TimeFlag;         //T0計數1秒的使用旗標.
void DelayMs(unsigned char);
void DelayUs2x(unsigned char);
void Init_Timer0(void);//定?器初始化
void LCD_Write_String(char x,char y, char *s);
void LCD_Write_Char(char x,char y,char Data);
void LCD_Clear(void);
unsigned int ADget(void);
unsigned char ADT,ADTT;

//------------20121217------------------
unsigned char ADVL;//ADVL display AD data
sbit CMPDT= P2^1;//compare bit P2^2 for temperature
sbit CMPD = P2^2;//compare bit P2^1 for volt
sbit LTH = P2^0;//74ls373 latch bit
bit SHV_flag;// latch volt
bit SHT_flag;//latch temp
bit SH_flag;//clean show flag
//-----------------DAO-------------------
void DAO(void)//DA converter
{
unsigned char DA=0;
  while(!CMPD)//compare bit P2^1
  {
   ADPortL=DA;
   LTH=1;
   LTH=0;
   DelayMs(2);
   DA++;
  }  
   ADT=DA;//ADVL display AD data
   ADPortL=0;
   LTH=1;
   LTH=0;
   DelayMs(2);
   SH_flag=1;// show flag
}



//-------------DAO2--------------------
void DAO2(void)//DA converter
{
  unsigned char DA=0;
  while(!CMPDT)//compare bit P2^1
  {
   ADPortL=DA;
   LTH=1;
   LTH=0;
   DelayMs(2);
   DA++;
  }  
   ADTT=DA;//ADVL display AD data
   ADPortL=0;
   LTH=1;
   LTH=0;
   DelayMs(2);
   SH_flag=1;// show flag
}


/*------------      LCM 顯示相關程式--------*/
bit LCD_Check_Busy(void) //檢查是否為"忙碌"
{
DataPort= 0xFF;
RS_CLR; // 指令模式
RW_SET; //寫入模式
EN_CLR; //***特別**** 啟動由LO變成HI **************
_nop_();
EN_SET; //***特別**** 啟動由LO變成HI **************
return (bit)(DataPort & 0x80);//若 讀出的資料bit7 =0 可以寫資料
}


void LCD_Write_Com(char com) //命令寫入
{  
while(LCD_Check_Busy()); //忙则等待 1=while loop still;
RS_CLR; //指令功能
RW_CLR; //寫入
EN_SET; //下降緣 由HI變成LO
DataPort= com; // 指令設定
_nop_();
EN_CLR;//
}

void LCD_Write_Data(char Data) //資料寫入
{
while(LCD_Check_Busy()); //忙则等待
RS_SET; // 資料處理
RW_CLR;// 寫的動作
EN_SET; // 啟動下緣觸發
DataPort= Data; //輸入需要寫入的資料
_nop_();//延後一個時間
EN_CLR;//
}

void LCD_Clear(void)
{
LCD_Write_Com(0x01); //清屏指令
DelayMs(5);//時間延遲5ms.
}

void LCD_Write_String(char x,char y, char *s)
{     
if (y == 0) //y 表示第一行或是第二行
        {     
         LCD_Write_Com(0x80 + x);     //表示第一行bit4 Hi+ x position
        }
else
        {      
        LCD_Write_Com(0xC0 + x);      //表示第二行 bit4 Hi+40+x position
        }        
while (*s)
        {     
LCD_Write_Data( *s); // *s 和 s 不一樣,*s 應該是字串 s是字數   
s ++;     
        }
}

/*
void LCD_Write_Char(char x, char y, char Data)
{     
if (y == 0) //第一行
        {     
        LCD_Write_Com(0x80 + x); //第幾個字的位置   
        }   
else
        {     
        LCD_Write_Com(0xC0 + x);     
        }        
LCD_Write_Data( Data);  //字
}
*/
void LCD_Init(void)
{
   LCD_Write_Com(0x38);    /*显示模式设置*/
   DelayMs(5);
   LCD_Write_Com(0x38); //8bit data  2 line 5x7 character.
   DelayMs(5);
   LCD_Write_Com(0x38);
   DelayMs(5);
   LCD_Write_Com(0x38);  
   LCD_Write_Com(0x08);    /*显示关闭*/
   LCD_Write_Com(0x01);    /*显示清屏*/
   LCD_Write_Com(0x06);    /*显示光标移动设置*/
   DelayMs(5);
   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
   }

void DelayUs2x(unsigned char t)
   {   
     while(t--);
   }
void DelayMs(unsigned char t)
{
      while(t--);
   {
     DelayUs2x(245);//from245>>45
         DelayUs2x(245);
   }
}

//--------------------------------------------------------------------------------------------
void Init_Timer0(void)
{
TMOD |= 0x01;          //使用模式1,16位定?器,使用"|"符?可以在使用多?定?器?不受影?                     
TH0= (65536-2000)/256; //        0x0D8 2ms if 12Mcristal
TL0= (65536-2000)%256;// 0x0F0

EA=1;           
ET0=1;         
TR0=1;         
}
//--------------------------------------------------------------------------------------------
void Timer0_isr(void) interrupt 1
{
TH0= (65536-10000)/256; //        0x0D8 2ms if 12Mcristal
TL0= (65536-10000)%256;// 0x0F0

    counter++;//counter is Global variable.
        if(counter==30)
      DAO2();
        if(counter==60)
          DAO();
    if(counter==100)          //200ms更新一次
     {
            counter=0;
        TimeFlag=1;                //計數器中斷約1秒時設定旗標為1,
        }
}


void main(void)
{
Init_Timer0();//起始定時器
LCD_Init();// LCM 啟動
LCD_Clear();//LCM清屏
sprintf(DisplayWord," AD data %5d",00000);//顯示AD為零
while(1)
{
  if(TimeFlag==1)//每1000Ms 更新一次
  {
  TimeFlag=0;//清除定時旗標
  if(SH_flag==1)// show flag
  {
  SH_flag=0;
  sprintf(DisplayWord,"AD1:%3d AD2:%3d",(int)ADT,(int)ADTT);//顯示第一組的計數 第二組的計數
  LCD_Write_String(0,0, DisplayWord);//顯示在第一行
sprintf(DisplayWord,"v=%3.2f tmp=%2.1f" ,ADT*0.019,(193-ADTT)*0.5);//轉換成電壓 和 溫度
  LCD_Write_String(0,1, DisplayWord);//顯示在第二行
  }
  }
}      
}

發表於 2012-12-25 00:37:03 | 顯示全部樓層
阿乾大:
要不要再玩不一樣的ADC讀取方式呢?
Rc充電 → Op Amp → I/O → Mcu
AT89C2051可以直接玩,不用加Op Amp.

你可以先看看這裡,再想想要怎麼做.
http://delphi.ktop.com.tw/board. ... 1167&tid=103774
 樓主| 發表於 2012-12-25 11:17:19 | 顯示全部樓層
scottwang 發表於 2012-12-25 12:37 AM static/image/common/back.gif
阿乾大:
要不要再玩不一樣的ADC讀取方式呢?
Rc充電 → Op Amp → I/O → Mcu

scottwang大:
   這個概念在這次的A/D轉換玩具之前有搜尋過,之所以先做這累進D/A法的原因是,資源回收場(大倉庫^_^)找到了 74373 和 R-2R 所以各取1管( 20個),另外,他的時間不必精準,又不需要太高階的中斷技巧...
   您的這建議我會做的,這次的比較器經驗讓我對OP經驗提升不少,睡前有在想要把他用在哪裡? 電源供應? 溫控烙鐵? ???
發表於 2012-12-25 17:20:06 | 顯示全部樓層
antlu 發表於 2012-12-24 11:22 PM static/image/common/back.gif
ciko.ciko大:
  問題已經解決,比較器不是問題,是時序上面的錯亂!!
程式如下:

用DA++方式太耗時了,0~255要做256次+1跟比較,
有個技巧可以在8次迴圈做完:

1. 將指標設為最高BIT。
2. 將指標所指示的BIT設為1。
3. 延遲一小短時間。
4. 若DA輸出<待測電壓則該BIT保留,否則該BIT=0。
5. 將指標指向下一BIT。
6. 重複2~5步驟8次。

這種演算法就有如二進位搜尋法一般,重複1半1半的程序,8次就可以得到答案。
發表於 2012-12-25 17:39:49 | 顯示全部樓層
本帖最後由 scottwang 於 2012-12-25 06:12 PM 編輯
ysc 發表於 2012-12-25 05:20 PM static/image/common/back.gif
用DA++方式太耗時了,0~255要做256次+1跟比較,
有個技巧可以在8次迴圈做完:


我寫了一半才在想說,該怎麼寫比較好,你就先寫了,我把此法稱為二分法,就像在玩遊戲一樣.增半或減半以增加比較速度.
我是以255的一半128為基準,做增半減半,如128+64,或128-64等等.
 樓主| 發表於 2012-12-25 18:26:26 | 顯示全部樓層
ysc 發表於 2012-12-25 05:20 PM static/image/common/back.gif
用DA++方式太耗時了,0~255要做256次+1跟比較,
有個技巧可以在8次迴圈做完:

YSC大:
   好久不見!! 感謝您的建議!!好高超的技巧啊!!這好像是以前(30年)學資料結構的問題....
  找時間試看看!!
 樓主| 發表於 2012-12-25 18:30:33 | 顯示全部樓層
scottwang 發表於 2012-12-25 05:39 PM static/image/common/back.gif
我寫了一半才在想說,該怎麼寫比較好,你就先寫了,我把此法稱為二分法,就像在玩遊戲一樣.增半或減半以增加 ...

scottwang 大:
    這要沉澱一下+想破頭 才(可能)可以成功!! 希望我有能力成功!!
發表於 2012-12-25 18:39:06 | 顯示全部樓層
antlu 發表於 2012-12-25 06:26 PM static/image/common/back.gif
YSC大:
   好久不見!! 感謝您的建議!!好高超的技巧啊!!這好像是以前(30年)學資料結構的問題....
  找時間 ...

這不算高超技巧,在資料結構裡常常用到。
您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

關閉

站長小叮嚀上一條 /1 下一條

禁閉室|手機版|連繫我們|痞酷網電子技術論壇

GMT+8, 2024-11-23 09:04 AM , Processed in 0.207578 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.