找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3861|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

[零基礎(chǔ)學(xué)習(xí)STM32]第九講:ADC實(shí)驗(yàn)—電源監(jiān)控

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:278743 發(fā)表于 2018-3-16 18:11 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 kkhkbb 于 2018-3-19 09:05 編輯

一、概述
1、ADC簡(jiǎn)介
     ADCA/D轉(zhuǎn)換部件,單片機(jī)不能直接處理模擬量,所以需要ADC將模擬量轉(zhuǎn)換為數(shù)字量后,在進(jìn)行處理。在使用單片機(jī)進(jìn)行模擬數(shù)據(jù)處理的過程中,ADC至關(guān)重要。ADC以下幾種類型:
  • 積分型:積分型AD工作原理是將輸入電壓轉(zhuǎn)換成時(shí)間(脈沖寬度信號(hào))或頻率(脈沖頻率),然后由定時(shí)器/計(jì)數(shù)器獲得數(shù)字值。其優(yōu)點(diǎn)是用簡(jiǎn)單電路就能獲得高分辨率,抗干擾能力強(qiáng),但缺點(diǎn)是由于轉(zhuǎn)換精度依賴于積分時(shí)間,因此轉(zhuǎn)換速率極低。初期的單片AD轉(zhuǎn)換器大多采用積分型,現(xiàn)在逐次比較型已逐步成為主流。
  • 逐次比較型:逐次比較型AD由一個(gè)比較器和DA轉(zhuǎn)換器通過逐次比較邏輯構(gòu)成,從MSB開始,順序地對(duì)每一位將輸入電壓與內(nèi)置DA轉(zhuǎn)換器輸出進(jìn)行比較,經(jīng)n次比較而輸出數(shù)字值。其電路規(guī)模屬于中等。其優(yōu)點(diǎn)是速度較高、功耗低,在低分辯率(<12)時(shí)價(jià)格便宜,但高精度(>12)時(shí)價(jià)格很高。
  • 并行比較型/串并行比較型:并行比較型AD采用多個(gè)比較器,僅作一次比較而實(shí)行轉(zhuǎn)換,又稱FLash(快速)型。由于轉(zhuǎn)換速率極高,n位的轉(zhuǎn)換需要2n-1個(gè)比較器,因此電路規(guī)模也極大,價(jià)格也高,只適用于視頻AD轉(zhuǎn)換器等速度特別高的領(lǐng)域。串并行比較型AD結(jié)構(gòu)上介于并行型和逐次比較型之間,最典型的是由2個(gè)n/2位的并行型AD轉(zhuǎn)換器配合DA轉(zhuǎn)換器組成,用兩次比較實(shí)行轉(zhuǎn)換,所以稱為 Half flash(半快速)型。還有分成三步或多步實(shí)現(xiàn)AD轉(zhuǎn)換的叫做分級(jí)(Multistep/Subrangling)AD,而從轉(zhuǎn)換時(shí)序角度又可稱為流水線(Pipelined)AD,現(xiàn)代的分級(jí)型AD中還加入了對(duì)多次轉(zhuǎn)換結(jié)果作數(shù)字運(yùn)算而修正特性等功能。這類AD速度比逐次比較型高,電路 規(guī)模比并行型小。
  • Σ-Δ(Sigma delta)調(diào)制型:Σ-ΔAD由積分器、比較器、1DA轉(zhuǎn)換器和數(shù)字濾波器等組成。原理上近似于積分型,將輸入電壓轉(zhuǎn)換成時(shí)間(脈沖寬度)信號(hào),用數(shù)字濾波器處理后得到數(shù)字值。電路的數(shù)字部分基本上容易單片化,因此容易做到高分辨率。主要用于音頻和測(cè)量。
  • 電容陣列逐次比較型:電容陣列逐次比較型AD在內(nèi)置DA轉(zhuǎn)換器中采用電容矩陣方式,也可稱為電荷再分配型。一般的電阻陣列DA轉(zhuǎn)換器中多數(shù)電阻的值必須一致,在單芯片上生成高 精度的電阻并不容易。如果用電容陣列取代電阻陣列,可以用低廉成本制成高精度單片AD轉(zhuǎn)換器。最近的逐次比較型AD轉(zhuǎn)換器大多為電容陣列式的。
  • 壓頻變換型:壓頻變換型(Voltage-Frequency Converter)是通過間接轉(zhuǎn)換方式實(shí)現(xiàn)模數(shù)轉(zhuǎn)換的。其原理是首先將輸入的模擬信號(hào)轉(zhuǎn)換成頻率,然 后用計(jì)數(shù)器將頻率轉(zhuǎn)換成數(shù)字量。從理論上講這種AD的分辨率幾乎可以無限增加,只要采樣的時(shí)間能夠滿足輸出頻率分辨率要求的累積脈沖個(gè)數(shù)的寬度。其優(yōu)點(diǎn)是分辯率高、功耗低、價(jià)格低,但是需要外部計(jì)數(shù)電路共同完成AD轉(zhuǎn)換。
2、ADC主要參數(shù)介紹
     ADC主要參數(shù)有以下幾點(diǎn):
  • 分辨率:數(shù)字量變化一個(gè)最小量時(shí)模擬量的變化量,定義為滿刻度與2n的比值。分辯率又稱精度,通常以數(shù)字信號(hào)的位數(shù)來表示。
  • 轉(zhuǎn)換速率:完成一次A/D轉(zhuǎn)換所需要時(shí)間的倒數(shù),值越大表示轉(zhuǎn)換得越快。積分型AD的轉(zhuǎn)換時(shí)間是毫秒級(jí)屬低速AD,逐次比 較型AD是微秒級(jí)屬中速AD,全并行/串并行型AD可達(dá)到納秒級(jí)。
  • 量化誤差:由于AD的有限分辯率而引起的誤差,即有限分辯率AD的階梯狀轉(zhuǎn)移特性曲線與無限分辯率AD(理想AD)的轉(zhuǎn)移特 性曲線(直線)之間的最大偏差。通常是1 個(gè)或半個(gè)最小數(shù)字量的模擬變化量,表示為1LSB、1/2LSB。
  • 偏移誤差:輸入信號(hào)為零時(shí)輸出信號(hào)不為零的值,可外接電位器調(diào)至最小。
  • 滿刻度誤差:滿度輸出時(shí)對(duì)應(yīng)的輸入信號(hào)與理想輸入信號(hào)值之差。
  • 線性度:實(shí)際轉(zhuǎn)換器的轉(zhuǎn)移函數(shù)與理想直線的最大偏移。
3、STM32F407IGT6ADC介紹
       STM32F407IGT6具有3個(gè)12位逐次逼近式ADC,共24個(gè)通道,可以配置成12位、8位、6位使用�?墒褂密浖䦟�(duì)對(duì)要使用的ADC進(jìn)行使能和設(shè)置,進(jìn)行模擬量的采集。
二、硬件電路

圖9_0 ARM 電源監(jiān)測(cè)ADC使用圖
     在iCore3雙核心開發(fā)板中,使用了個(gè)ADC進(jìn)行電源監(jiān)控分配如下表所示:
ADC選用   監(jiān)測(cè)內(nèi)容
ADC1-14通道  5V電壓
ADC1-15通道  輸入電流
ADC3-15通道  1.2V電壓
ADC3-4通道  3.3V電壓
ADC3-5通道  2.5V電壓
                表9_0 ARM 電源監(jiān)測(cè)ADC使用分配表
三、實(shí)驗(yàn)原理
      使用ADC的5個(gè)通道,分別監(jiān)測(cè)5種電源信息,使用程序進(jìn)行相應(yīng)的轉(zhuǎn)換后,使用putty串口工具將采集到電源信息打印到PC機(jī)屏幕上,了解開發(fā)板的電源狀態(tài)。
      STM32 內(nèi)部集成三個(gè) 12 位 ADC, iCore3 的所有電源經(jīng)過電阻分壓或者直接接入 STM32的 ADC 的輸出通道內(nèi), 輸入電流經(jīng)過高端電流檢測(cè)芯片 ZXCT1009F 輸入到 ADC 的輸入通道內(nèi),從而實(shí)現(xiàn)電源監(jiān)控功能。
      電壓監(jiān)控硬件連接示意圖:

                    圖9_1電壓監(jiān)測(cè)硬件連接圖
     由上圖可知:VCC =(1 + R1 / R2)*ADC_IN;
     故知:VCC = (1 + 49.9K / 10K)*ADC_IN = 6*ADC_IN;
     其他電源監(jiān)控同理可得:D3V3 = 2*ADC_IN;
                                        A2V5 =2*ADC_IN;
                                        D1V2 =ADC_IN。
     電流監(jiān)控硬件連接示意圖如下圖:
           圖9_2電流監(jiān)測(cè)硬件連接圖
    由 ZXCT1009F 的原理可知:ADC_IN = 0.01 * (VCC - LOAD)*R2;
    通過 R1 的電流:I = 100 *ADC_IN /R2 /R1;
    帶入 R2 = 10K,R1 = 0.02:得出:I =ADC_IN / 2;

四、源代碼
1.主函數(shù)
  1. //--------------------------- Include ---------------------------//
  2. #include "..\include\led.h"
  3. #include "..\include\main.h"
  4. #include "..\include\usart.h"
  5. #include "..\include\adc.h"
  6. #include "..\fwlib\inc\stm32f4xx_gpio.h"

  7. //---------------------------- Define ---------------------------//

  8. //-------------------------- Variable ---------------------------//

  9. //--------------------- Function Prototype ----------------------//

  10. //--------------------------- Function --------------------------//
  11. /*
  12. * Name                : main
  13. * Description         : ---
  14. * Author              : ysloveivy.
  15. *
  16. * History
  17. * --------------------
  18. * Rev                 : 0.00
  19. * Date                : 11/21/2015
  20. *
  21. * create.
  22. * --------------------
  23. */
  24. int main(void)
  25. {
  26.         int i;

  27.         //初始化
  28.         led.initialize();
  29.         LED_RED_ON;
  30.         usart4.initialize(115200);
  31.         adc.initialize();

  32.         usart4.printf("\x0c");                                   //清屏

  33.         usart4.printf("\033[1;32;40m");                          //設(shè)置終端字體為綠色

  34.         usart4.printf("\r\n\r\nhello! I am iCore3!\r\n\r\n\r\n");
  35.         while(1){
  36.                 for(i = 0;i < 10000000;i++);

  37.                 //ADC 監(jiān)控電源
  38.                 for(i = 0;i < 5;i++){
  39.                         adc.read(i);
  40.                 }
  41.                 //打印系統(tǒng)供電電壓,
  42.                 usart4.printf(" [V] %4.2fV, ",adc.value[0] * 6);
  43.                 usart4.printf("[I] %3.0fmA , ",adc.value[1] / 2* 1000.);
  44.                 usart4.printf("[1.2V] %4.2fV, ",adc.value[2]);
  45.                 usart4.printf("[3.3V] %4.2fV, ",adc.value[3] * 2);
  46.                 usart4.printf("[2.5V] %4.2fV\r",adc.value[4] * 2);
  47.         }
  48. }
復(fù)制代碼

2.ADC參數(shù)配置
  1. /*
  2. * Name                : initialize
  3. * Description         : ---
  4. * Author              : ysloveivy.
  5. *
  6. * History
  7. * --------------------
  8. * Rev                 : 0.00
  9. * Date                : 11/21/2015
  10. *
  11. * create.
  12. * --------------------
  13. */
  14. static int initialize(void)
  15. {
  16.         GPIO_InitTypeDef  GPIO_InitStructure;
  17.         ADC_CommonInitTypeDef  ADC_CommonInitStructure;
  18.         ADC_InitTypeDef  ADC_InitStructure;

  19.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
  20.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
  21.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);                             //使能ADC1時(shí)鐘
  22.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);                            //使能ADC3時(shí)鐘

  23.         //ADC1_PC4<----->通道14, ADC1_PC5<----->通道15
  24.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;                                    //模擬輸入
  26.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  27.         GPIO_Init(GPIOC, &GPIO_InitStructure);

  28.         //ADC3_PF5<----->通道15, ADC3_PF6<----->通道4, ADC3_PF7<----->通道5
  29.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  30.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;                                    //模擬輸入
  31.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  32.         GPIO_Init(GPIOF, &GPIO_InitStructure);

  33.         ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                        //ADC為獨(dú)立模式
  34.         ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;    //設(shè)置兩個(gè)采樣階段之間的延遲周期數(shù)為5個(gè)周期
  35.         ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;         //禁止DMA
  36.         ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6;                     //設(shè)置分頻系數(shù)為6分頻
  37.         ADC_CommonInit(&ADC_CommonInitStructure);

  38.         //初始化ADC
  39.         ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                          //ADC轉(zhuǎn)換分辨率12位
  40.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;                                   //非掃描模式
  41.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                             //關(guān)閉連續(xù)轉(zhuǎn)換模式
  42.         ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;     //禁止觸發(fā)檢測(cè)
  43.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                          //右對(duì)齊方式
  44.         ADC_InitStructure.ADC_NbrOfConversion = 1;                                            //1個(gè)轉(zhuǎn)換在規(guī)則序列中
  45.         ADC_Init(ADC1, &ADC_InitStructure);
  46.         ADC_Init(ADC3, &ADC_InitStructure);                                                       //使能ADC
  47.         ADC_Cmd(ADC1, ENABLE);
  48.         ADC_Cmd(ADC3, ENABLE);

  49.         return 0;
  50. }
  51. /*
  52. * Name                  : sort
  53. * Description           : ---
  54. * Author                : XiaomaGee.
  55. *
  56. * History
  57. * ----------------------
  58. * Rev                   : 0.00
  59. * Date                  : 11/21/2015
  60. *
  61. * create.
  62. * ----------------------
  63. */
  64. void sort(unsigned short int a[], int n)
  65. {
  66.         int i, j, t;

  67.         //元素從小到大排列
  68.         for (i = 0; i < n - 1; i++) {
  69.                 for (j = 0; j < n - i - 1; j++) {
  70.                         if (a[j] > a[j + 1]) {
  71.                                 t = a[j];
  72.                                 a[j] = a[j + 1];
  73.                                 a[j + 1] = t;
  74.                         }
  75.                 }
  76.         }
  77. }
  78. /*
  79. * Name                  : read_adc
  80. * Description           : ---
  81. * Author                : ysloveivy.
  82. *
  83. * History
  84. * ----------------------
  85. * Rev                   : 0.00
  86. * Date                  : 11/21/2015
  87. *
  88. * create.
  89. * ----------------------
  90. */
  91. static int read_adc(int channel)
  92. {
  93.         int i,k;
  94.         unsigned long int temp[20] = {0};
  95.         unsigned long int value;
  96.         unsigned short int data[100];
  97.         unsigned char channel_remap[5] = {ADC_Channel_14,ADC_Channel_15,ADC_Channel_15,ADC_Channel_4,ADC_Channel_5};

  98.         //取得到的100個(gè)轉(zhuǎn)換值的中間20個(gè)的平均值作為結(jié)果
  99.         //連續(xù)取20次這樣的平均值,再求平均值作為最終結(jié)果
  100.         for(k = 0;k < 20;k++){
  101.                 for(i = 0;i < 100;i++){
  102.                         if(channel == 0 || channel == 1){
  103.                                 ADC_RegularChannelConfig(ADC1, channel_remap[channel], 1, ADC_SampleTime_480Cycles); //ADC1規(guī)則通道為通道14,15,一個(gè)序列,采樣時(shí)間為480個(gè)周期

  104.                                 ADC_SoftwareStartConv(ADC1);                                                         //使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能

  105.                                 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));                                       //等待轉(zhuǎn)換結(jié)束

  106.                                 data[i] = ADC_GetConversionValue(ADC1);                                                     //將結(jié)果保存

  107.                         }else {
  108.                                 ADC_RegularChannelConfig(ADC3, channel_remap[channel], 1, ADC_SampleTime_480Cycles); //ADC3規(guī)則通道為通道15,4,5,一個(gè)序列,采樣時(shí)間為480個(gè)周期

  109.                                 ADC_SoftwareStartConv(ADC3);

  110.                                 while(!ADC_GetFlagStatus(ADC3,
  111. ADC_FLAG_EOC));

  112.                                 data[i] = ADC_GetConversionValue(ADC3);

  113.                         }
  114.                 }

  115.                 sort(data,100);

  116.                 for(i = 40;i < 60;i++){
  117.                         temp[k] += data[i];
  118.                 }

  119.                 temp[k] = temp[k] / 20;
  120.         }

  121.         value = 0;
  122.         for(k = 0;k < 20;k++){
  123.                 value += temp[k];
  124.         }
  125.         value /= 20;

  126.         adc.value[channel] = value * ADC_REF / 4096;

  127.         return value;
  128. }
復(fù)制代碼
3.ADC參數(shù)配置說明
  1.     typedef struct
  2.     {
  3.       uint32_t ADC_Mode;                     
  4.       uint32_t ADC_Prescaler;               
  5.       uint32_t ADC_DMAAccessMode;            
  6.       uint32_t ADC_TwoSamplingDelay;         
  7.     }ADC_CommonInitTypeDeftypedef ;
  8.     typedef struct
  9.     {
  10.       uint32_t ADC_Resolution;               
  11.       FunctionalState ADC_ScanConvMode;      
  12.       FunctionalState ADC_ContinuousConvMode;                                          
  13.       uint32_t ADC_ExternalTrigConvEdge;   
  14.     uint32_t ADC_ExternalTrigConv;         
  15.       uint32_t ADC_DataAlign;               
  16.       uint8_t  ADC_NbrOfConversion;         
  17.     }ADC_InitTypeDef;;
復(fù)制代碼
ADC_Mode:工作模式, 分為獨(dú)立模式和混合模式,混合模式中包含了多種工作模式。                  
ADC_Prescaler:  分頻值, 用于配置ADC時(shí)鐘,有2、4、6、8四種分頻方式。           
ADC_DMAAccessMode:DMX通道模式,分為:不使能、模式1、模式2、模式3。        
ADC_TwoSamplingDelay:兩個(gè)采樣之間的延遲周期。
ADC_Resolution:分辨率,12、10、8、6位可設(shè)置。            
FunctionalState ADC_ScanConvMode:用于是否開啟轉(zhuǎn)換模式。   
FunctionalState ADC_ContinuousConvMode: 用于是否開啟連續(xù)轉(zhuǎn)換模式。                                      
ADC_ExternalTrigConvEdge: 用來設(shè)置啟動(dòng)規(guī)則轉(zhuǎn)換組轉(zhuǎn)換的外部事件。
ADC_ExternalTrigConv: 色孩子數(shù)據(jù)觸發(fā)檢測(cè)。      
ADC_DataAlign: 用于設(shè)置數(shù)據(jù)對(duì)齊方式是左對(duì)齊還是右對(duì)齊。            
ADC_NbrOfConversion:用來設(shè)置規(guī)則序列的長(zhǎng)度 。
五、實(shí)驗(yàn)現(xiàn)象
      iCore3 雙核心板紅色 LED 常亮, 串口一直向終端輸出電源監(jiān)控的數(shù)據(jù)。
                    圖9_3實(shí)驗(yàn)效果圖
六、代碼包下載
      網(wǎng)盤:http://pan.baidu.com/s/1o7wSE06

iCore3_9_ADC.zip

1.39 MB, 下載次數(shù): 41, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:289667 發(fā)表于 2018-3-16 19:34 | 只看該作者
寫的太好了,十分詳細(xì),值得我們學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

板凳
ID:229981 發(fā)表于 2018-3-16 20:41 來自觸屏版 | 只看該作者
有目錄嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:1 發(fā)表于 2018-3-17 01:22 | 只看該作者

點(diǎn)擊樓主的圖像,有樓主的所有帖子列表
回復(fù)

使用道具 舉報(bào)

5#
ID:289512 發(fā)表于 2018-3-31 09:23 | 只看該作者
太好了,謝謝分享。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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