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

作者: kkhkbb    時(shí)間: 2018-3-16 18:11
標(biāo)題: [零基礎(chǔ)學(xué)習(xí)STM32]第九講:ADC實(shí)驗(yàn)—電源監(jiān)控
本帖最后由 kkhkbb 于 2018-3-19 09:05 編輯

一、概述
1、ADC簡介
     ADCA/D轉(zhuǎn)換部件,單片機(jī)不能直接處理模擬量,所以需要ADC將模擬量轉(zhuǎn)換為數(shù)字量后,在進(jìn)行處理。在使用單片機(jī)進(jìn)行模擬數(shù)據(jù)處理的過程中,ADC至關(guān)重要。ADC以下幾種類型:
2、ADC主要參數(shù)介紹
     ADC主要參數(shù)有以下幾點(diǎn):
3、STM32F407IGT6ADC介紹
       STM32F407IGT6具有3個(gè)12位逐次逼近式ADC,共24個(gè)通道,可以配置成12位、8位、6位使用?墒褂密浖䦟σ褂玫腁DC進(jìn)行使能和設(shè)置,進(jìn)行模擬量的采集。
二、硬件電路

圖9_0 ARM 電源監(jiān)測ADC使用圖
     在iCore3雙核心開發(fā)板中,使用了個(gè)ADC進(jìn)行電源監(jiān)控分配如下表所示:
ADC選用   監(jiān)測內(nèi)容
ADC1-14通道  5V電壓
ADC1-15通道  輸入電流
ADC3-15通道  1.2V電壓
ADC3-4通道  3.3V電壓
ADC3-5通道  2.5V電壓
                表9_0 ARM 電源監(jiān)測ADC使用分配表
三、實(shí)驗(yàn)原理
      使用ADC的5個(gè)通道,分別監(jiān)測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)過高端電流檢測芯片 ZXCT1009F 輸入到 ADC 的輸入通道內(nèi),從而實(shí)現(xiàn)電源監(jiān)控功能。
      電壓監(jiān)控硬件連接示意圖:

                    圖9_1電壓監(jiān)測硬件連接圖
     由上圖可知: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)測硬件連接圖
    由 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ā)檢測
  43.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                          //右對齊方式
  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ā)檢測。      
ADC_DataAlign: 用于設(shè)置數(shù)據(jù)對齊方式是左對齊還是右對齊。            
ADC_NbrOfConversion:用來設(shè)置規(guī)則序列的長度 。
五、實(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


作者: cai123    時(shí)間: 2018-3-16 19:34
寫的太好了,十分詳細(xì),值得我們學(xué)習(xí)
作者: heron    時(shí)間: 2018-3-16 20:41
有目錄嗎?
作者: admin    時(shí)間: 2018-3-17 01:22
heron 發(fā)表于 2018-3-16 20:41
有目錄嗎?

點(diǎn)擊樓主的圖像,有樓主的所有帖子列表
作者: dillinllp    時(shí)間: 2018-3-31 09:23
太好了,謝謝分享。




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