|
對,就是跳來跳去……我都沒想到這么不準(zhǔn)……
用來測熱敏電阻的,用的電阻分壓,原理圖見下。
萬用表測量在1.65-1.75之間,但是用單片機(jī)adc就跳來跳去,一會零點(diǎn)幾,一會一點(diǎn)幾……
如果把單片機(jī)靜置,單片機(jī)就會保持在一個不確定的數(shù)值上。動兩下,就會跳來跳去好久
甚至,斷開電阻分壓的供電和地(我設(shè)計(jì)了跳線),依然顯示有電壓,還是跳來跳去。
神奇。。
STC8H1k28自帶adc,adc參考電壓直接連了vcc,用ams1117和兩節(jié)7號電池都是如此。
即使參考電壓再不準(zhǔn),也不至于這樣吧……
總而言之,言而總之,跳變沒有任何規(guī)律。
如下是程序,原理圖和實(shí)拍。tm1640驅(qū)動沒有問題,非常好用(在別人基礎(chǔ)上改的,最近學(xué)的多了才知道是iic)。
adc程序是在datasheet里復(fù)制的,有改動,后續(xù)處理是參考了數(shù)十個程序融合而成的。
單片機(jī)源程序如下:
- //頭文件-----------------------------------------------
- #include <stc8.h>
- #include<stdio.h>
- #include <intrins.h>
- #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
- //端口聲明----------------------------------------------
- sbit led1=P1^6;
- sbit led2=P1^7;
- sbit DIN=P3^4;
- sbit CLK=P3^5;
- sbit key1=P3^2;
- sbit key2=P3^3;
- unsigned char ah;
- unsigned char al;
- //端口聲明----------------------------------------------
- unsigned int i;
- unsigned char code nbr[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39}; //共陽數(shù)碼管段碼數(shù)據(jù)
- void delay(unsigned z)
- {
- unsigned x,y;
- for(x=z;x>0;x--)
- for(y=300;y>0;y--);
- }
- //IIC協(xié)議start通訊開始函數(shù)-----------------------------------
- void I2CStart()
- {
- DIN=1;
- CLK=1;
- delay(2);
- DIN=1;
- delay(2);
- DIN=0;
- delay(4);
- CLK=0;
- delay(2);
- }
- //IIC協(xié)議stop通訊結(jié)束函數(shù)-----------------------------------
- void I2CStop()
- {
- CLK=1;
- delay(2);
- DIN=0;
- delay(2);
- DIN=1;
- delay(2);
- CLK=0;
- DIN=0;
- }
- //發(fā)送8bit數(shù)據(jù),從低位開始-----------------------------
- void I2CWritebyte(unsigned char oneByte)
- {
- unsigned char i;
- for(i=0;i<8;i++)
- {
- CLK=0;
- if(oneByte&0x01)
- DIN=1;
- else
- DIN=0;
- delay(3);
- CLK=1;
- oneByte=oneByte>>1;
- }
- CLK=0;
- delay(4);
- DIN=0;
- delay(2);
- }
- //TM1640寫數(shù)據(jù),再次封裝,簡化程序----------------------------
- void tmw(int ha,hb)
- {
- I2CStart();
- I2CWritebyte(ha); //地址命令設(shè)置:初始地址00H
- for(i=0;i<1;i++) //發(fā)送16位顯示數(shù)據(jù)
- {
- I2CWritebyte(hb); //顯示值
- }
- I2CStop();
- }
- //TM1640開啟顯示便捷函數(shù)-------------------------------------
- void tms()
- {
- I2CStart();
- I2CWritebyte(0x8c); //顯示控制:顯示開,脈沖寬度設(shè)為11/16
- I2CStop();
- }
- //adc中斷-----------------------------------------------------
- void ADC_Isr() interrupt 5
- {
- ADC_CONTR &= ~0x20; //清中斷標(biāo)志
- ah = ADC_RES; //讀取 ADC 結(jié)果
- al = ADC_RESL; //讀取 ADC 結(jié)果
- delay(2);//必要的延時(shí)
- ADC_CONTR |= 0x40; //繼續(xù) AD 轉(zhuǎn)換
- }
- //adc采樣函數(shù)-----------------------------------------------------
- void ad()
- {
- unsigned int ab = 0;
- int ac = 0;
- float ad;
- ab = ah*4+al;//兩個寄存器(adc結(jié)果)合并
- ad = ab*10000/1024*3.2;//計(jì)算電壓(無小數(shù)點(diǎn))
- ac = ad;
- tmw(0xc0,nbr[ac/1000%10]);//每一位依次顯示在數(shù)碼管上
- delay(10);
- tmw(0xc1,nbr[(ac/100)%10]);
- delay(10);
- tmw(0xc2,nbr[(ac/10)%10]);
- delay(10);
- tmw(0xc3,nbr[ac%10]);
- delay(10);
- tms();
- delay(20);
-
- }
- //main函數(shù)-----------------------------------------------------
- void main()
- {
- //uart_init();
- P0M0 = 0x00; //配置io口寄存器為雙向口
- P0M1 = 0x01; //設(shè)置 P0.0 為 ADC 口
- P1M0 = 0x00;
- P1M1 = 0x00;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P_SW2 |= 0x80;
- ADCTIM = 0x3f; //設(shè)置 ADC 內(nèi)部時(shí)序
- P_SW2 &= 0x7f;
- ADCCFG = 0x0f; //設(shè)置 ADC 時(shí)鐘為系統(tǒng)時(shí)鐘/2/16/16
- ADC_CONTR = 0x88; //使能 ADC 模塊
- EADC = 1; //使能 ADC 中斷
- EA = 1;
- ADC_CONTR |= 0x40; //啟動 AD 轉(zhuǎn)換
- led1 = 0;
- while(1){
- ad();
- }
- }
復(fù)制代碼
數(shù)碼管用的tm1640驅(qū)動。熱敏電阻10k,分壓電阻10k(實(shí)測9.2k)
沒有連錫,焊接沒問題,熱敏電阻拆下來量了沒壞
神奇,完全可以改造成隨機(jī)數(shù)生成器……
|
|