|
發布時間: 2018-8-28 15:04
正文摘要:宏晶IAP15W4K58S4單片機最小模塊,測AD值,兩個10k電阻串聯,測a點的ad值不是1024的二分之一,而是700多,為什么?????測b點的ad值就是1023,為什么????? 緊急求助 |
|
AD_Dat = (ADC_RES<<2)|(ADC_RESL&0x03); //高低字節拼接成一個10位數。 關于這句代碼,是不需要強制轉換為int的, 因為AD_Dat是int類型,2個字節16位的,式子右邊的高位是不會丟失的。 |
|
你把b端,值接到單片機VCC引腳嘗試一下,(即和單片機同一基準)看看a的讀數是不是512左右。 或者,你把b端接到P3.7口, 把P3.7設置為推挽輸出,高電平。然后再測a端讀數,我懷疑你之所以a端700多,是因為你b端超過量程了,只能顯示1023,其實1400了…… |
|
本帖最后由 dbxzjq 于 2021-8-31 00:14 編輯 #define ADC_POWER 0x80 //ADC電源控制位 #define ADC_FLAG 0x10 //ADC完成標志 #define ADC_START 0x08 //ADC起始控制位 #define ADC_SPEEDLL 0x00 //540個時鐘 #define ADC_SPEEDL 0x20 //360個時鐘 #define ADC_SPEEDH 0x40 //180個時鐘 #define ADC_SPEEDHH 0x60 //90個時鐘 /*---------------------------- 初始化ADC ----------------------------*/ void InitADC(void) { //P1M0 &= ~0x10; //P1M1 |= 0x10; P1ASF = 0x07; //設置P1口為AD口 ADC_RES = 0; //清除結果寄存器 ADC_RESL = 0; CLK_DIV |= 0x20; //ADRJ=1,ADC_RES[1:0]存放高2位ADC結果,ADC_RESL[7:0]存放低8位結果 ADC_CONTR = ADC_POWER | ADC_SPEEDL; //開啟ADC電源,配置ADC轉換速度為180個時鐘 //Delay(2); //ADC上電并延時 } unsigned int GetADCResult(unsigned char ch) { //unsigned int a=0; ADC_CONTR = ADC_POWER | ADC_SPEEDL | ch | ADC_START; _nop_(); //等待4個NOP _nop_(); _nop_(); _nop_(); while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉換完成 ADC_CONTR &= ~ADC_FLAG; //Close ADC //a=ADC_RES; //a=a<<8|ADC_RESL; return (unsigned int)ADC_RES<<8|ADC_RESL; //返回ADC結果 } 測量出來的ADC都非常正常的啊!切換通道后必須等待四個空周期才能進行測量,另外這型號對于IO口不用設置為高阻輸入的,只管P1ASF設置對應為模擬口即可,不過手冊上也說最好把ADC對應的測量IO配置為高阻輸入為好樓主的代碼:發現合成10位有問題,如下: AD_Dat = (ADC_RES<<2)|(ADC_RESL&0x03); //高低字節拼接成一個10位數。 修改為AD_Dat =(int)(ADC_RES<<2)|(ADC_RESL&0x03); //高低字節拼接成一個10位數。 這里(int)(ADC_RES<<2)因為左移2位后,超出來寄存器的8位寬度,8位機只能默認R0-R7寄存器組都為8位的,必須得強制轉換為16位, 編譯器才會把ADC_RES<<2放在兩個臨時的R0-R7寄存器組里頭再進行運算,得到的最終結果才是正確的值 比如ADC_RES=11111111的二進制值,執行ADC_RES<<2后=11111100,但是如果(int)(ADC_RES<<2)就會不一樣了,它會換成16位進行運算 得到的會是0000 0011 1111 1100的16位值再位或|(ADC_RESL&0x03)這部分的結果送給予6位變量AD_Dat |
188461 發表于 2018-8-29 09:38 單片機的AD轉換時只能使用一個模擬輸入通道嗎 |
小帖 發表于 2018-8-30 16:17 vcc為4.75v,沒接基準電壓,電路簡單 |
wulin 發表于 2018-8-30 17:23 P1M1 = 0x08; P1M0 = 0x00; 我換了P1.3端口,并把其置為高阻模式了,可是沒有效果啊 ![]() 設為準雙向口時,把電源和地換位置,測得ad值也是700多,換位置前后ad值差不多,說明內部上拉電阻沒并聯在上分壓電阻上啊。這是不是說明總的ad值有1500多【哭暈】 這是怎么回事呢,求解答,萬分感謝!!!!! |
188461 發表于 2018-8-29 09:25 你把AD輸入端設為準雙向口當然測出的電壓比實際電壓高,因為準雙向口使用了內部上拉電阻,這個電阻相當于接在你的外電路的a、b兩點之間。也就是并聯在上分壓電阻上從而改變上分壓電阻阻值。 |
| hdx 好東西 好東西 謝謝嘍 |
| VCC是否是單片機的基準電壓,還是大于基準電壓,用的10位的AD,最大值了 |
lilao3 發表于 2018-8-29 00:23 ADC_CONTR = 0x80; //開AD轉換電源,第一次使用時要打開start the ADC for (g=0;g<10000;g++); P1ASF|=0x08; // 選擇P1.3作為AD轉換通道,0x02= 0000 1000 ADC_CONTR=0xE3; // 選擇P1.3作為AD轉換通道,最高轉換速度,清轉換完成標志。 for (g=0;g<1000;g++); ADC_CONTR|=0x08; while((ADC_CONTR & 0x10) == 0) ; //wait for ADC finish ADC_CONTR &= 0xE7; //將ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0 AD_Dat = (ADC_RES<<2)|(ADC_RESL&0x03); //高低字節拼接成一個10位數。 return AD_Dat; 這個程序是p1.3口的,設置為模擬輸入了啊 ![]() |
devcang 發表于 2018-8-28 17:29 沒有設置基準參考電壓,因為應用簡單,直接與vcc比較的 測試時vcc電壓是穩定的5.02v,串聯電阻兩端電壓5.00v |
wulin 發表于 2018-8-28 16:51 一個電阻為9.88k,一個為9.95k。P1端口:P1M1 = 0; P1M0 = 0; //設置為準雙向口 相應的p1.0端口通過ADC_CONTR設置為模擬輸入了 為什么要設置成高阻呢??? |
看你的情況,貌似IO口沒有配置成模擬輸入,默認有弱上拉,所以理論值512,實際測700多。
|
|
AD的參考電壓是多少,要是參考電壓的1半,結果才是那樣。不然,就是自己的參考電壓,2路AD,其中1路是參考電壓,另1路是測試的電壓。 |
| 你能確認兩個10K電阻的實際阻值相同?相應端口是否設為高阻和模擬輸入模式? |