找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9790|回復(fù): 15
收起左側(cè)

STC8H1k28單片機(jī)自帶adc跳來跳去 求分析

  [復(fù)制鏈接]
ID:837101 發(fā)表于 2020-11-28 22:22 | 顯示全部樓層 |閱讀模式
對,就是跳來跳去……我都沒想到這么不準(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ī)源程序如下:
  1. //頭文件-----------------------------------------------
  2. #include <stc8.h>
  3. #include<stdio.h>  
  4. #include <intrins.h>
  5. #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
  6. //端口聲明----------------------------------------------
  7. sbit led1=P1^6;
  8. sbit led2=P1^7;
  9. sbit DIN=P3^4;
  10. sbit CLK=P3^5;
  11. sbit key1=P3^2;
  12. sbit key2=P3^3;
  13. unsigned char ah;
  14. unsigned char al;


  15. //端口聲明----------------------------------------------

  16. unsigned int i;
  17. unsigned char code nbr[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39};  //共陽數(shù)碼管段碼數(shù)據(jù)

  18. void delay(unsigned z)
  19. {
  20.    unsigned x,y;
  21.         for(x=z;x>0;x--)
  22.                 for(y=300;y>0;y--);
  23. }

  24. //IIC協(xié)議start通訊開始函數(shù)-----------------------------------
  25. void I2CStart()
  26. {
  27.     DIN=1;
  28.     CLK=1;
  29.         delay(2);

  30.         DIN=1;
  31.         delay(2);

  32.         DIN=0;
  33.         delay(4);

  34.         CLK=0;
  35.         delay(2);
  36. }



  37. //IIC協(xié)議stop通訊結(jié)束函數(shù)-----------------------------------
  38. void I2CStop()
  39. {
  40.         CLK=1;
  41.         delay(2);

  42.         DIN=0;
  43.         delay(2);

  44.         DIN=1;
  45.         delay(2);

  46.         CLK=0;
  47.         DIN=0;

  48. }

  49. //發(fā)送8bit數(shù)據(jù),從低位開始-----------------------------
  50. void I2CWritebyte(unsigned char oneByte)
  51. {
  52.   unsigned char i;
  53.   for(i=0;i<8;i++)
  54.   {
  55.     CLK=0;
  56.         if(oneByte&0x01)
  57.           DIN=1;
  58.         else
  59.           DIN=0;
  60.         delay(3);
  61.         CLK=1;
  62.         oneByte=oneByte>>1;
  63.         }
  64.         CLK=0;
  65.         delay(4);
  66.         DIN=0;
  67.         delay(2);
  68. }
  69. //TM1640寫數(shù)據(jù),再次封裝,簡化程序----------------------------
  70. void tmw(int ha,hb)
  71. {
  72.         I2CStart();
  73.                 I2CWritebyte(ha);        //地址命令設(shè)置:初始地址00H
  74.                 for(i=0;i<1;i++)        //發(fā)送16位顯示數(shù)據(jù)
  75.                         {
  76.                                 I2CWritebyte(hb);         //顯示值
  77.                         }
  78.                 I2CStop();
  79. }        
  80. //TM1640開啟顯示便捷函數(shù)-------------------------------------
  81. void tms()
  82. {
  83.                 I2CStart();
  84.                 I2CWritebyte(0x8c);        //顯示控制:顯示開,脈沖寬度設(shè)為11/16
  85.                 I2CStop();

  86. }

  87. //adc中斷-----------------------------------------------------        

  88. void ADC_Isr() interrupt 5
  89. {
  90.         ADC_CONTR &= ~0x20; //清中斷標(biāo)志
  91.         ah = ADC_RES; //讀取 ADC 結(jié)果
  92.         al = ADC_RESL; //讀取 ADC 結(jié)果
  93.         delay(2);//必要的延時(shí)
  94.         ADC_CONTR |= 0x40; //繼續(xù) AD 轉(zhuǎn)換
  95. }
  96. //adc采樣函數(shù)-----------------------------------------------------        
  97. void ad()
  98. {
  99.         unsigned int ab = 0;
  100.         int ac = 0;
  101.         float ad;
  102.   ab = ah*4+al;//兩個寄存器(adc結(jié)果)合并
  103.         ad = ab*10000/1024*3.2;//計(jì)算電壓(無小數(shù)點(diǎn))
  104.         ac = ad;
  105.         tmw(0xc0,nbr[ac/1000%10]);//每一位依次顯示在數(shù)碼管上
  106.         delay(10);
  107.         tmw(0xc1,nbr[(ac/100)%10]);
  108.         delay(10);
  109.         tmw(0xc2,nbr[(ac/10)%10]);
  110.         delay(10);
  111.         tmw(0xc3,nbr[ac%10]);
  112.         delay(10);
  113.         tms();
  114.         delay(20);
  115.         
  116. }
  117. //main函數(shù)-----------------------------------------------------        
  118. void main()
  119. {
  120.         //uart_init();

  121.         P0M0 = 0x00; //配置io口寄存器為雙向口
  122.         P0M1 = 0x01; //設(shè)置 P0.0 為 ADC 口
  123.         P1M0 = 0x00;
  124.         P1M1 = 0x00;
  125.         P2M0 = 0x00;
  126.         P2M1 = 0x00;
  127.         P3M0 = 0x00;
  128.         P3M1 = 0x00;
  129.         P4M0 = 0x00;
  130.         P4M1 = 0x00;
  131.         P5M0 = 0x00;
  132.         P5M1 = 0x00;
  133.         P_SW2 |= 0x80;
  134.         ADCTIM = 0x3f; //設(shè)置 ADC 內(nèi)部時(shí)序
  135.         P_SW2 &= 0x7f;
  136.         ADCCFG = 0x0f; //設(shè)置 ADC 時(shí)鐘為系統(tǒng)時(shí)鐘/2/16/16
  137.         ADC_CONTR = 0x88; //使能 ADC 模塊
  138.         EADC = 1; //使能 ADC 中斷
  139.         EA = 1;
  140.         ADC_CONTR |= 0x40; //啟動 AD 轉(zhuǎn)換
  141.         led1 = 0;
  142.         while(1){
  143.                         ad();
  144.                 }
  145. }
復(fù)制代碼

數(shù)碼管用的tm1640驅(qū)動。熱敏電阻10k,分壓電阻10k(實(shí)測9.2k)
沒有連錫,焊接沒問題,熱敏電阻拆下來量了沒壞
神奇,完全可以改造成隨機(jī)數(shù)生成器……

屏幕截圖 2020-11-28 221606.png
bddffe23f2bc904eff58aa17b8dfea9.jpg
c58d7fcc0290232c475601ea61eb1ac.jpg
5f760ec717cebdefd393f39d489d754.jpg
回復(fù)

使用道具 舉報(bào)

ID:837101 發(fā)表于 2020-11-28 22:29 | 顯示全部樓層
就離譜
回復(fù)

使用道具 舉報(bào)

ID:420836 發(fā)表于 2020-11-29 02:25 | 顯示全部樓層
添加數(shù)字濾波器以平均模擬變量采樣; 此外,請檢查模擬參考電壓是否穩(wěn)定。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2020-11-29 07:26 | 顯示全部樓層
出現(xiàn)問題不要輕易懷疑單片機(jī)問題,首先要確認(rèn)特殊功能寄存器的配置是否正確。
仔細(xì)核對通道選擇,轉(zhuǎn)換速度選擇,轉(zhuǎn)換結(jié)果格式選擇(合并轉(zhuǎn)換結(jié)果高低位的方式不同)。
正確選擇電壓換算公式的數(shù)據(jù)類型,樓主采用的公式錯誤,運(yùn)算過程數(shù)據(jù)溢出。
十二位ADC結(jié)果換算成10進(jìn)制(4舍5入)公式
毫伏=(參考電壓*十二位ADC結(jié)果*10000/4096+5)/10
依據(jù)樓主程序配置建議算法:
void ad()
{
        unsigned int ab = 0;
        unsigned int ac = 0;
        unsigned int ad;
        ab = ((unsigned int)ah<<4)|(al>>4);//兩個寄存器(adc結(jié)果)合并
        ad = (long)ab*10000/4096*3.2;//計(jì)算電壓(無小數(shù)點(diǎn))
        ac = ad;
        ......

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:687694 發(fā)表于 2020-11-29 14:40 | 顯示全部樓層
本帖最后由 lovexulu 于 2020-11-29 14:45 編輯

剛沒仔細(xì)看。。。發(fā)現(xiàn)是采用中斷讀取adc的這個應(yīng)該就是問題所在了,假如恰好正在執(zhí)行運(yùn)算時(shí),中斷并改變了ah,al值,那得到的結(jié)果就不知道是啥了。
流程改一下,開啟轉(zhuǎn)換,中斷讀取,讀取一次,刷新一次 開啟轉(zhuǎn)換,這樣應(yīng)該不會有問題了。

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:401564 發(fā)表于 2020-11-30 09:25 | 顯示全部樓層
ab = ah*4+al
這個什么意思?
ADCCFG = 0x2f,這個寄存器改一下,ADC結(jié)果就直接取高位和低位運(yùn)算就可以了
你參考一下樓上的幾位,先把ADC部分的資料看一下再修改
這沒有什么難度的
回復(fù)

使用道具 舉報(bào)

ID:226055 發(fā)表于 2020-12-1 11:28 | 顯示全部樓層
本人用了STC8H系列的另外一款芯片STC8H8K64U,使用了2.5V基準(zhǔn)電壓,測試ADC效果很好。不過用的是TB上買的現(xiàn)成的板子,我把原理圖ADC部分和實(shí)驗(yàn)源碼發(fā)你參考下,都是STC8H系列的應(yīng)該參考意義比較大。同意樓上見解,STC芯片依然出庫不會有那么大問題的。 STC8H原理圖ADC.jpg



ADC采集實(shí)物圖.jpg

實(shí)驗(yàn)2-9-2:ADC電位器實(shí)驗(yàn)(P0.4讀取電壓值).rar

49.48 KB, 下載次數(shù): 125

評分

參與人數(shù) 2黑幣 +50 收起 理由
REwilliam + 20 很給力!
admin + 30 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:837101 發(fā)表于 2020-12-4 21:20 | 顯示全部樓層
lovexulu 發(fā)表于 2020-11-29 14:40
剛沒仔細(xì)看。。。發(fā)現(xiàn)是采用中斷讀取adc的這個應(yīng)該就是問題所在了,假如恰好正在執(zhí)行運(yùn)算時(shí),中斷并改變了a ...

51官方的datasheet就是個大坑呀!用的51官方的中斷程序……發(fā)現(xiàn)了好幾個錯誤
回復(fù)

使用道具 舉報(bào)

ID:837101 發(fā)表于 2020-12-4 23:24 | 顯示全部樓層
wulin 發(fā)表于 2020-11-29 07:26
出現(xiàn)問題不要輕易懷疑單片機(jī)問題,首先要確認(rèn)特殊功能寄存器的配置是否正確。
仔細(xì)核對通道選擇,轉(zhuǎn)換速度 ...

謝謝!
回復(fù)

使用道具 舉報(bào)

ID:790408 發(fā)表于 2020-12-4 23:31 來自觸屏版 | 顯示全部樓層
可以做個卡爾曼濾波器,或是把采到的數(shù)據(jù)放到matlab中曲線擬合一下
回復(fù)

使用道具 舉報(bào)

ID:837101 發(fā)表于 2020-12-5 00:10 | 顯示全部樓層
wulin 發(fā)表于 2020-11-29 07:26
出現(xiàn)問題不要輕易懷疑單片機(jī)問題,首先要確認(rèn)特殊功能寄存器的配置是否正確。
仔細(xì)核對通道選擇,轉(zhuǎn)換速度 ...

解決了!謝謝大佬!
回復(fù)

使用道具 舉報(bào)

ID:837101 發(fā)表于 2020-12-5 00:11 | 顯示全部樓層
1922323908 發(fā)表于 2020-12-4 23:31
可以做個卡爾曼濾波器,或是把采到的數(shù)據(jù)放到matlab中曲線擬合一下

已經(jīng)解決了!根據(jù)樓上大佬的回復(fù),確實(shí)是使用了不正確的公式導(dǎo)致數(shù)據(jù)溢出。謝謝!
回復(fù)

使用道具 舉報(bào)

ID:292876 發(fā)表于 2021-1-12 14:04 | 顯示全部樓層
經(jīng)常用AD,實(shí)際使用中出現(xiàn)的問題點(diǎn),簡單總結(jié)下,參考下。
AD取樣,沒有特殊情況啥的,兩個算法必須,不然不專業(yè)!
1:注意輸入阻抗問題。電源要穩(wěn)定做好濾波處理,電源很重要,片內(nèi)AD一般都用電源當(dāng)基準(zhǔn)。
2:頭兩次取樣建議丟棄,速度允許,盡可能慢檔位
3:加【中位值平均濾波】 【全程區(qū)間線性插值】
4:如果不使用595或者1650 1638之類LED驅(qū)動芯片,MCU頻率盡可能提高!
5:盡可能用外部晶振。
回復(fù)

使用道具 舉報(bào)

ID:584288 發(fā)表于 2021-3-2 14:41 | 顯示全部樓層
你好,樓主,你有么有用STC8H1K28這個單片機(jī)做PWM波形輸出的程序。這款單片機(jī)剛出來不久,找不到相關(guān)例程。如果有能不能分享一下。
回復(fù)

使用道具 舉報(bào)

ID:111280 發(fā)表于 2021-8-31 02:28 | 顯示全部樓層
cocolala 發(fā)表于 2020-12-1 11:28
本人用了STC8H系列的另外一款芯片STC8H8K64U,使用了2.5V基準(zhǔn)電壓,測試ADC效果很好。不過用的是TB上買的現(xiàn) ...

請問STC8H8K64U支持USB硬件接口仿真嗎?
回復(fù)

使用道具 舉報(bào)

ID:1101600 發(fā)表于 2023-11-28 19:27 | 顯示全部樓層
樓主你測出來精度多少,0.01v嗎,還是0.1v
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表