標(biāo)題: 關(guān)于15系列單片機(jī)AD采樣電壓的問(wèn)題,想測(cè)量電池剩余電壓 [打印本頁(yè)]

作者: 18277067187    時(shí)間: 2018-8-21 23:03
標(biāo)題: 關(guān)于15系列單片機(jī)AD采樣電壓的問(wèn)題,想測(cè)量電池剩余電壓
AD采樣的程序本人已經(jīng)弄好,想測(cè)量電池剩余電壓,但是15系列單片機(jī)上電后P1口的io普遍都有4v以上的電壓,而恰恰ad采樣口就在p1口的io上,那我怎么才能消除原有io上的電壓,用來(lái)測(cè)量電池電壓,不然總是在測(cè)量io口上原本的電壓

作者: 文鳳軒    時(shí)間: 2018-8-22 00:33
這個(gè)好辦呀,在P1口接下拉電阻P1口的電壓不就沒(méi)了嗎,因?yàn)镻1口那個(gè)電流很小的,是上拉電阻過(guò)來(lái)的,接個(gè)下拉電阻就把它給放掉了,電池電壓沒(méi)影響的
作者: wulin    時(shí)間: 2018-8-22 06:36
沙發(fā)的建議是錯(cuò)誤的。有很多型號(hào)的STC15系列單片機(jī)內(nèi)置有ADC功能,只要把其P1相應(yīng)端口特殊功能寄存器初始化時(shí)設(shè)置為高阻即可。
以P1.0設(shè)置高阻為例:
        P1M1 = 0x01; //設(shè)置P1.0高阻:0000 0001
        P1M0 = 0x00;//設(shè)置P1.0高阻 :0000 0000
        P1ASF= 0x01;//設(shè)置P1的0通道端口作為模擬輸入
作者: HC6800-ES-V2.0    時(shí)間: 2018-8-22 08:58
你想多了!
第一:你要測(cè)量的電源與單片機(jī)共地。
第二:設(shè)置好AD轉(zhuǎn)換通道,設(shè)置寄存器如圖所示:

其它設(shè)置,去看手冊(cè)。STC15的手冊(cè)可以從STC官網(wǎng)下載http://www.stcmcu.com/,手冊(cè)中還有例子。
第三:開(kāi)啟AD轉(zhuǎn)換,單片機(jī)會(huì)自動(dòng)從你設(shè)置的AD轉(zhuǎn)換口,讀取數(shù)據(jù)進(jìn)行轉(zhuǎn)換。

例如我的一個(gè)小程序(部分)
void ADCInit (void)//ADC設(shè)置
{
        P1ASF=0x03;//P10、P11為ADC輸入口。手冊(cè)P878
        CLK_DIV=0x20;//ADC轉(zhuǎn)換結(jié)果存放方式。手冊(cè)P880
}


void ADC0 (void)//第一路AD轉(zhuǎn)換函數(shù)
{
        ADC_CONTR=0xe8;//開(kāi)ADC電源、速度最快、開(kāi)始轉(zhuǎn)換、P10口。手冊(cè)P879
        while (!(ADC_CONTR&0x10));//如果轉(zhuǎn)換沒(méi)結(jié)束,則等待
        ADC_CONTR=0x00;//關(guān)ADC電源、清轉(zhuǎn)換完畢標(biāo)志
        ADCdate=ADC_RES;//ADC轉(zhuǎn)換數(shù)據(jù)高兩位。手冊(cè)P880
        ADCdate=(ADCdate<<8);
        ADCdate=(ADCdate|ADC_RESL);//合并10位轉(zhuǎn)換數(shù)據(jù)
        ADCXX();
}


我測(cè)過(guò)一節(jié)、兩節(jié)干電池的電壓。
注意:我不是高手,這樣做可能從電路來(lái)說(shuō)是很粗暴的——僅僅是做了程序方面的試驗(yàn)。
歡迎指正

作者: angmall    時(shí)間: 2018-8-22 09:02
你可以運(yùn)用這個(gè)程序
讀ADC內(nèi)部基準(zhǔn)計(jì)算MCU的工作電壓, 不需要增加任何硬件零件.


  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited ----------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.GXWMCU.com --------------------------------------------*/
  8. /* --- QQ:  800003751 -------------------------------------------------*/
  9. /* 如果要在程序中使用此代碼,請(qǐng)?jiān)诔绦蛑凶⒚魇褂昧撕昃Э萍嫉馁Y料及程序   */
  10. /*---------------------------------------------------------------------*/


  11. /*************        本程序功能說(shuō)明        **************

  12. 讀ADC內(nèi)部基準(zhǔn)計(jì)算MCU的工作電壓, 不需要增加任何硬件零件.

  13. 用STC的MCU的IO方式控制74HC595驅(qū)動(dòng)8位數(shù)碼管。

  14. 用戶可以修改宏來(lái)選擇時(shí)鐘頻率.

  15. 用戶可以在"用戶定義宏"中選擇共陰或共陽(yáng). 推薦盡量使用共陰數(shù)碼管.

  16. 使用Timer0的16位自動(dòng)重裝來(lái)產(chǎn)生1ms節(jié)拍,程序運(yùn)行于這個(gè)節(jié)拍下, 用戶修改MCU主時(shí)鐘頻率時(shí),自動(dòng)定時(shí)于1ms.

  17. 右邊4位數(shù)碼管顯示MCU的工作電壓值值.


  18. ******************************************/

  19. #define MAIN_Fosc                22118400L        //定義主時(shí)鐘

  20. #include        "STC15Fxxxx.H"


  21. /***********************************************************/

  22. #define DIS_DOT                0x20
  23. #define DIS_BLACK        0x10
  24. #define DIS_                0x11

  25. #define P1n_pure_input(bitn)                P1M1 |=  (bitn),        P1M0 &= ~(bitn)

  26. /****************************** 用戶定義宏 ***********************************/

  27. #define                LED_TYPE        0x00                //定義LED類(lèi)型, 0x00--共陰, 0xff--共陽(yáng)

  28. #define        Timer0_Reload        (65536UL -(MAIN_Fosc / 1000))                //Timer 0 中斷頻率, 1000次/秒

  29. /*****************************************************************************/






  30. /*************        本地常量聲明        **************/
  31. u8 code t_display[]={                                                //標(biāo)準(zhǔn)字庫(kù)
  32. //         0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  33.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  34. //black         -     H    J         K          L           N        o   P         U     t    G    Q    r   M    y
  35.         0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
  36.         0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};        //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

  37. u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};                //位碼


  38. /*************        IO口定義        **************/
  39. sbit        P_HC595_SER   = P4^0;        //pin 14        SER                data input
  40. sbit        P_HC595_RCLK  = P5^4;        //pin 12        RCLk        store (latch) clock
  41. sbit        P_HC595_SRCLK = P4^3;        //pin 11        SRCLK        Shift data clock


  42. /*************        本地變量聲明        **************/

  43. u8         LED8[8];                //顯示緩沖
  44. u8        display_index;        //顯示位索引
  45. bit        B_1ms;                //1ms標(biāo)志

  46. u8        msecond;

  47. u16        Get_ADC10bitResult(u8 channel);        //channel = 0~7




  48. /**********************************************/
  49. void main(void)
  50. {
  51.         u8        i;
  52.         u16        j;

  53.         P0M1 = 0;        P0M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  54.         P1M1 = 0;        P1M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  55.         P2M1 = 0;        P2M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  56.         P3M1 = 0;        P3M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  57.         P4M1 = 0;        P4M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  58.         P5M1 = 0;        P5M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  59.         P6M1 = 0;        P6M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  60.         P7M1 = 0;        P7M0 = 0;        //設(shè)置為準(zhǔn)雙向口
  61.        
  62.         display_index = 0;
  63.         P1ASF = 0;        //對(duì)內(nèi)部基準(zhǔn)做ADC
  64.         ADC_CONTR = 0xE0;                        //90T, ADC power on
  65.        
  66.         AUXR = 0x80;        //Timer0 set as 1T, 16 bits timer auto-reload,
  67.         TH0 = (u8)(Timer0_Reload / 256);
  68.         TL0 = (u8)(Timer0_Reload % 256);
  69.         ET0 = 1;        //Timer0 interrupt enable
  70.         TR0 = 1;        //Tiner0 run
  71.         EA = 1;                //打開(kāi)總中斷
  72.        
  73.         for(i=0; i<8; i++)        LED8[i] = 0x10;        //上電消隱

  74.        
  75.         while(1)
  76.         {
  77.                 if(B_1ms)        //1ms到
  78.                 {
  79.                         B_1ms = 0;
  80.                         if(++msecond >= 200)        //200ms到
  81.                         {
  82.                                 msecond = 0;

  83.                                 for(j=0,i=0; i<16; i++)                j += Get_ADC10bitResult(0);        //讀內(nèi)部基準(zhǔn)ADC, P1ASF=0, 讀0通道
  84.                                 j = (u32)128000UL*16 / j;        // ADC = 1024 * Uref / Ux, 則 Ux = 1024 * Uref / ADC = 1024 * 1.25 / ADC = 1280 / ADC

  85.                                 LED8[5] = j / 100 + DIS_DOT;        //顯示MCU電壓值, 計(jì)算時(shí)放大了100倍, 電壓有兩位小數(shù).
  86.                                 LED8[6] = (j % 100) / 10;
  87.                                 LED8[7] = j % 10;
  88.                         }
  89.                 }
  90.         }
  91. }
  92. /**********************************************/

  93. //========================================================================
  94. // 函數(shù): u16        Get_ADC10bitResult(u8 channel)
  95. // 描述: 查詢法讀一次ADC結(jié)果.
  96. // 參數(shù): channel: 選擇要轉(zhuǎn)換的ADC.
  97. // 返回: 10位ADC結(jié)果.
  98. // 版本: V1.0, 2012-10-22
  99. //========================================================================
  100. u16        Get_ADC10bitResult(u8 channel)        //channel = 0~7
  101. {
  102.         ADC_RES = 0;
  103.         ADC_RESL = 0;

  104.         ADC_CONTR = (ADC_CONTR & 0xe0) | 0x08 | channel;         //start the ADC
  105.         NOP(4);

  106.         while((ADC_CONTR & 0x10) == 0)        ;        //wait for ADC finish
  107.         ADC_CONTR &= ~0x10;                //清除ADC結(jié)束標(biāo)志
  108.         return        (((u16)ADC_RES << 2) | (ADC_RESL & 3));
  109. }



  110. /**************** 向HC595發(fā)送一個(gè)字節(jié)函數(shù) ******************/
  111. void Send_595(u8 dat)
  112. {               
  113.         u8        i;
  114.         for(i=0; i<8; i++)
  115.         {
  116.                 dat <<= 1;
  117.                 P_HC595_SER   = CY;
  118.                 P_HC595_SRCLK = 1;
  119.                 P_HC595_SRCLK = 0;
  120.         }
  121. }

  122. /********************** 顯示掃描函數(shù) ************************/
  123. void DisplayScan(void)
  124. {       
  125.         Send_595(~LED_TYPE ^ T_COM[display_index]);                        //輸出位碼
  126.         Send_595( LED_TYPE ^ t_display[LED8[display_index]]);        //輸出段碼

  127.         P_HC595_RCLK = 1;
  128.         P_HC595_RCLK = 0;                                                        //鎖存輸出數(shù)據(jù)
  129.         if(++display_index >= 8)        display_index = 0;        //8位結(jié)束回0
  130. }


  131. /********************** Timer0 1ms中斷函數(shù) ************************/
  132. void timer0 (void) interrupt TIMER0_VECTOR
  133. {
  134.         DisplayScan();        //1ms掃描顯示一位
  135.         B_1ms = 1;                //1ms標(biāo)志
  136. }


復(fù)制代碼


STC15Fxxxx.zip

8.73 KB, 下載次數(shù): 29


作者: aking991    時(shí)間: 2018-8-22 11:26
可能是你現(xiàn)在的IO口是懸空狀態(tài)吧,在所在測(cè)的IO口上加上加一個(gè)下拉10-100K的電阻就行了,如果要測(cè)試電池電壓,建議還是用分壓電阻方案測(cè)試穩(wěn)當(dāng)點(diǎn),我自己現(xiàn)在用的是10K+90K方案,測(cè)試正常,考慮到只有10位AD,精度并不是很好
作者: 18277067187    時(shí)間: 2018-8-22 13:01
angmall 發(fā)表于 2018-8-22 09:02
你可以運(yùn)用這個(gè)程序
讀ADC內(nèi)部基準(zhǔn)計(jì)算MCU的工作電壓, 不需要增加任何硬件零件.

并不是讀取單片機(jī)的工作電壓,我是想通過(guò)io口的ad采樣功能測(cè)量18650電池電量

作者: 18277067187    時(shí)間: 2018-8-22 13:02
wulin 發(fā)表于 2018-8-22 06:36
沙發(fā)的建議是錯(cuò)誤的。有很多型號(hào)的STC15系列單片機(jī)內(nèi)置有ADC功能,只要把其P1相應(yīng)端口特殊功能寄存器初始化 ...

但是情況是我設(shè)置了高阻態(tài),設(shè)置為ad采樣的io還是有電壓

作者: 18277067187    時(shí)間: 2018-8-22 13:14
aking991 發(fā)表于 2018-8-22 11:26
可能是你現(xiàn)在的IO口是懸空狀態(tài)吧,在所在測(cè)的IO口上加上加一個(gè)下拉10-100K的電阻就行了,如果要測(cè)試電池電 ...

是懸空狀態(tài)用萬(wàn)用表測(cè)量有電壓,我就是想測(cè)量電池電壓,怕ad采樣io口原來(lái)的電壓會(huì)影響測(cè)量的數(shù)據(jù),我不知道該怎么樣測(cè)量,還有所說(shuō)的分壓電阻方案,是ad采樣io接上10k+90k的電阻,然后接地,電阻中間引線出來(lái)接待測(cè)的的電池正極是嗎
作者: 18277067187    時(shí)間: 2018-8-22 13:26
HC6800-ES-V2.0 發(fā)表于 2018-8-22 08:58
你想多了!
第一:你要測(cè)量的電源與單片機(jī)共地。
第二:設(shè)置好AD轉(zhuǎn)換通道,設(shè)置寄存器如圖所示:

學(xué)習(xí)了
作者: wulin    時(shí)間: 2018-8-22 15:42
18277067187 發(fā)表于 2018-8-22 13:02
但是情況是我設(shè)置了高阻態(tài),設(shè)置為ad采樣的io還是有電壓

由于是高阻態(tài),此端口懸空時(shí)測(cè)到的電壓不必理會(huì),不影響對(duì)外電路電壓的測(cè)量精度。我用STC15W404AS設(shè)計(jì)的產(chǎn)品從來(lái)沒(méi)有發(fā)生你擔(dān)心問(wèn)題。
作者: Enter_Tang    時(shí)間: 2018-8-22 16:04
樓下說(shuō)的有道理




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1