久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7583|回復: 5
收起左側

STC15F104W單片機利用RC充放電使用IO口測量外部電壓

[復制鏈接]
ID:245767 發表于 2018-12-21 15:00 | 顯示全部樓層 |閱讀模式
宏晶科技STC15F系列單片機
RC充放電實現檢測外部電壓

對于沒有ADC的MCU,而又要測量外部的一個電壓時,使用RC充放電的方式是比較容易實現并且低成本的方法。
STC15F系列是1T的MCU,其IO口有OPEN-DRAIN模式,此模式可以很容易用一個IO口配合一個定時器實現RC充放電來測量外部未知電壓。如果沒有空余的定時器,也可以使用指令循環的方式實現。本例使用定時器。
本范例使用P3.2(INT0)來做RC測量,電路和波形示意圖如下:
操作流程:
  • 初始化程序將P3.2設置成OPEN-DRAIN模式, 并將P3.2輸出0給電容放電。INT0設置成上升沿中斷。Timer 0設置成16位自動重裝定時器模式,時鐘源為12T,允許中斷。
  • 測量時,先清Timer 0TH0TL0,然后將P3.2輸出1開始對電容充電,接著設置TR0 = 1來啟動Timer 0,然后在INT0中斷里設置TR0 = 0來停止計數,并將P3.2輸出0對電容放電。讀出TH0TL0的值就是RC充電時間。
由于MCU工作在5V時,IO口讀到“1”的門限電壓大約為2V,所以要求輸入的電壓高于2V,本例的測試數據從4~12.4V,測試結果參考后面的附錄1。
假設輸入電壓為Ux,IO口門限電壓為2V,則RC充電時間為:
                            T =  - R * C * ln ( 1 – 2 / Ux )
按圖示參數,當輸入為10V時,RC時間大約為446uS,附錄1中實測為447uS。
由于RC時間跟R和C有關,而R的溫漂一般較小,但普通電容的溫漂較大,所以要使用溫漂小并且漏電也小的電容。
由充電公式或曲線圖可知,Ux和RC值的關系是非線性的,所以實際項目使用時,要根據自己的實際電路做一些標定,這樣可以得到比較準確的值。
本方法適用于對測量精度要求不是很高的場合。

附錄1:測量結果和曲線

輸入電壓(V)
Timer 0讀數
時間uS(18.432MHZ)
4
2100
1367
4.2
1966
1280
4.4
1846
1202
4.6
1740
1133
4.8
1646
1072
5
1560
1016
5.2
1487
968
5.4
1416
922
5.6
1354
882
5.8
1297
844
6
1245
811
6.2
1196
779
6.4
1150
749
6.6
1110
723
6.8
1070
697
7
1033
673
7.2
1000
651
7.4
968
630
7.6
938
611
7.8
910
592
8
884
576
8.2
860
560
8.4
836
544
8.6
814
530
8.8
793
516
9
772
503
9.2
754
491
9.4
736
479
9.6
718
467
9.8
702
457
10
686
447
10.2
671
437
10.4
656
427
10.6
642
418
10.8
629
410
11
616
401
11.2
604
393
11.4
592
385
11.6
581
378
11.8
570
371
12
560
365
12.2
550
358
12.4
540
352
附錄2C語言程序
  1. /*

  2. 功能描述: 使用STC15F系列C版本做的RC測量電壓的例子.

  3. */

  4. #include "reg51.h"

  5. #define MAIN_Fosc                            22118400L              //定義主時鐘

  6. #define              uchar              unsigned char
  7. #define uint              unsigned int

  8. sfr AUXR = 0x8e;    //Auxiliary register
  9. sfr P3M1  = 0xB1;              //P3M1.N,P3M0.N               =00--->Standard,              01--->push-pull
  10. sfr P3M0  = 0xB2;              //                                                                      =10--->pure input,              11--->open drain

  11. sbit              P_TXD1  = P3^1;              //定義模擬串口發送腳,打印信息用
  12. sbit    P_RC = P3^2;              //RC port
  13. uchar              SampleCnt;                            //發送結果的采樣間隔計數
  14. uchar              LineCnt;                            //每行顯示結果計數
  15. bit                            B_Over;                                          //超時標志
  16. bit                            B_ADC_OK;                            //檢測完成標志
  17. uint              adc;                                          //RC做的ADC值

  18. void              RC_start(void);
  19. void              Tx1Send(uchar dat);
  20. void               InitTimer(void);
  21. void              delay_ms(unsigned char ms);

  22. ///////////////////////////////////////////////////////////

  23. void main(void)
  24. {

  25.               InitTimer();                            //初始化Timer

  26.     P3M1 |=  1 << 2;         //P3.2 config as Open-Drain
  27.               P3M0 |=  1 << 2;
  28.               P_RC = 0;               //Clear RC port to 0
  29. //    TMOD |= 0x00;           //T0 as 16 bits timer, auto reload

  30.     while (1)
  31.     {
  32.         delay_ms(5);   //放電時間
  33.                            
  34.                             B_ADC_OK = 0;                            //清除ADC結束標志
  35.                             B_Over = 0;                                          //清除超量程標志
  36.         RC_start();           //RC charge-decharge
  37.                             while(!B_ADC_OK && !B_Over)              ;              //等待ADC結束或超時
  38.                             if(B_ADC_OK)
  39.                             {
  40.                                           if(++SampleCnt >= 100)              //1秒鐘發一個結果給串口
  41.                                           {
  42.                                                         SampleCnt = 0;
  43.                                                         Tx1Send(adc / 10000 + '0');           //send to PC from the UART
  44.                                                         Tx1Send(adc % 10000 / 1000 + '0');
  45.                                                         Tx1Send(adc % 1000 / 100 + '0');
  46.                                                         Tx1Send(adc % 100 / 10 + '0');
  47.                                                         Tx1Send(adc % 10 + '0');
  48.                                                         Tx1Send(' ');
  49.                                                         Tx1Send(' ');
  50.                                                         if(++LineCnt >= 10)                            //10個結果后換行
  51.                                                         {
  52.                                                                       LineCnt = 0;
  53.                                                                       Tx1Send(0x0d);   //send CR
  54.                                                                       Tx1Send(0x0a);
  55.                                                         }
  56.                                           }
  57.                             }
  58.     }
  59. }


  60. ///////////////////////////////////////////////////////////

  61. //============================================================
  62. // 函數: void  delay_ms(unsigned char ms)
  63. // 描述: 延時函數。
  64. // 參數: ms,要延時的ms數.
  65. // 返回: none.
  66. // 版本: VER1.0
  67. // 日期: 2010-12-15
  68. // 備注:
  69. //============================================================
  70. void  delay_ms(unsigned char ms)
  71. {
  72.      unsigned int i;
  73.               do
  74.               {
  75.                             i = MAIN_Fosc / 14000L;              //1T
  76.                             while(--i)              ;   //13T per loop
  77.      }while(--ms);
  78. }


  79. /**************** RC啟動函數 ******************************/
  80. void   RC_start(void)
  81. {
  82.                         //使用Timer 0 計時
  83.     TH0 = 0;            //clear Timer 0
  84.     TL0 = 0;
  85.               B_Over = 0;                                          //Clear Over flag
  86.     P_RC = 1;           //RC charge
  87.     TR0 = 1;            //enable Timer 0
  88.               IE0 = 0;                                          //Clear INT0 flag
  89.               EX0 = 1;                            //INT0 Enable
  90.               IT0 = 0;                            //INT0 上升,下降沿中斷            
  91. }

  92. /********************* INT0中斷函數 *************************/
  93. void INT0_int (void) interrupt 0                            //
  94. {
  95.     if(INT0 && !B_Over)                            //上升沿中斷,無超時
  96.               {
  97.                             TR0 = 0;            //deable Timer 0
  98.                             P_RC = 0;           //decharge
  99.                             adc = TH0;            //read the RC time
  100.                             adc = (adc << 8) + TL0;
  101.                             B_ADC_OK = 1;                            //標志ADC結束
  102.               }
  103. }


  104. /**************** Timer初始化函數 ******************************/
  105. void InitTimer(void)
  106. {
  107.               TMOD = 0;                            //for STC15Fxxx系列              Timer0 as 16bit reload timer.
  108.               TH0 = 0;
  109.               TL0 = 0;
  110.               ET0 = 1;                            //允許Timer0中斷
  111.               TR0 = 0;
  112.               EA  = 1;                            //允許總中斷
  113. }

  114. /********************** Timer0中斷函數************************/
  115. void timer0 (void) interrupt 1
  116. {
  117.               TR0 = 0;              //超量程關閉
  118.               B_Over = 1;              //標志超量程
  119. }


  120. /********************** 模擬串口相關函數************************/

  121. void              BitTime(void)              //位時間函數
  122. {
  123.               uint i;
  124.               i = ((MAIN_Fosc / 100) * 104) / 130000L - 1;                            //根據主時鐘來計算位時間
  125.               while(--i);
  126. }

  127. //模擬串口發送
  128. void              Tx1Send(uchar dat)                            //9600,N,8,1                            發送一個字節
  129. {
  130.               uchar              i;
  131.               EA = 0;
  132.               P_TXD1 = 0;
  133.               BitTime();
  134.               for(i=0; i<8; i++)
  135.               {
  136.                             if(dat & 1)                            P_TXD1 = 1;
  137.                             else                                          P_TXD1 = 0;
  138.                             dat >>= 1;
  139.                             BitTime();
  140.               }
  141.               P_TXD1 = 1;
  142.               EA = 1;
  143.               BitTime();
  144.               BitTime();
  145. }
復制代碼

完整的Word格式文檔51黑下載地址:
STC15F104W利用RC充放電使用IO口測量外部電壓.DOC (99.5 KB, 下載次數: 40)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:424598 發表于 2018-12-21 18:31 | 顯示全部樓層
有實物圖嗎?
回復

使用道具 舉報

ID:67274 發表于 2020-4-2 19:56 | 顯示全部樓層
本帖最后由 a461624201 于 2020-4-2 20:18 編輯

圖為5v電壓,然后取最大位的時間數,判定為5V.循環指令,一個nop,就是一個指令時間,1us/次,對于STC15F104,

1.png
回復

使用道具 舉報

ID:67274 發表于 2020-4-2 20:14 | 顯示全部樓層
這個代碼,連接1637后,就會死機, 貼上不使用定時器和中斷,循環指令RC測量代碼,
while(1){                dianrong_jiao = 0;               
                           delay_ms(5);

                   sj=0          ;       
                 
                    
             dianrong_jiao = 1;           
       
                while(dianrong_jiao==0){          _nop_(); sj++;   }
回復

使用道具 舉報

ID:67274 發表于 2020-4-2 20:27 | 顯示全部樓層
其實,無論是定時器中斷還是循環nop,另一方面,測量瓷片電容,還是能粗略判斷電容的容量的,有種簡單電容表的感覺。
回復

使用道具 舉報

ID:67274 發表于 2020-4-3 00:08 | 顯示全部樓層
不用STC15F104中斷的,可以接TM1637數碼管的while程序。  
while (1)
    { P_RC= 0;

        Delay1us(5);
                B_ADC_OK= 0;                //清除ADC結束標志
                                  

                TH0 = 0;            //clear Timer 0
        TL0 = 0;
             B_Over= 0;                        //Clear Over flag
   
            P_RC= 1;           //RC charge
        TR0 = 1;  
                ET0 = 1;                //允許Timer0中斷
            EA  = 1;                //允許總中斷
       while( P_RC==0 ){ };
       
           if( B_Over==0){
                   TR0 = 0;            //關閉定時器
                 ET0 = 0;                 
            EA  = 0;                 
            
             adc = TH0;            //取數據
                adc = (adc << 8) + TL0;
                B_ADC_OK= 1;         //標志ADC結束       
                 }
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费成人在线网站 | 成人一区二区三区在线观看 | 伊人艹| 毛片毛片毛片毛片 | 国产精品揄拍一区二区久久国内亚洲精 | 国产精品揄拍一区二区 | 国产精品一区二区视频 | 成人av一区二区三区 | 电影91久久久 | 一区中文字幕 | 国产精品一区二区三区四区 | 亚洲欧美日本国产 | av毛片 | 黄色大片在线 | 一区二区三区四区av | 国产一级片久久久 | 超碰在线免费 | 在线看片福利 | 亚洲欧美中文字幕在线观看 | 日韩国产精品一区二区三区 | 天天操天天拍 | 在线观看成人 | 免费国产视频 | 伊人伊人 | 欧美一区二区三区在线 | 羞羞的视频免费看 | 成人av在线播放 | 免费的一级视频 | 伊人网影院 | 欧美日韩淫片 | 国产精品一二三区 | 99久久日韩精品免费热麻豆美女 | www.色.com | 日韩av一区二区在线观看 | 爱草视频| 美女在线一区二区 | 五月综合久久 | 久久久999成人 | 日韩欧美在线播放 | 久久久九九 | 国产精品欧美一区二区三区不卡 |