STM32f103的數電采集電路的雙ADC的設計與使用


STM32F103C8T6擁有3個ADC,其獨立使用已經在本文的3.1.3里面有詳細的介紹,這里主要是介紹雙ADC的同時使用,即STM32的同步規則模式使用。在此模式在規則通道組上執行時,外部觸發來自ADC1的規則組多路開關(由ADC1_CR2寄存器的EXTSEL[2:0]選擇),它同時給ADC2提供同步觸發。此功能必須使用DMA通道。同時兩組數據是公用一個寄存器,ADC1數據在低16位,ADC2數據在高16位。由於保證數據穩定,在雙ADC同步規則模式的情況下,還添加了多通道同時采樣。

ADC1和ADC2,工作方式采用了同步規則模式,使得兩個ADC可以同時對不同的AD輸入進行采集和數據存儲和傳輸,而且相互不影響,也可以確保采樣時間的減少,同時兩個ADC都是使用4通路同時采集,確保了數據的穩定性。

多功能采集顯示平台使用的芯片是STM32F103ZET6,片上資源提供了ADC123共3路ADC模塊,為了布線方便以及使用的習慣,多功能采集顯示平台采用了ADC1的Chanel 4~7,占用IO口PA 4~7,以及ADC2的Chanel 10~13,占用IO口PC 0~3。

使用時有幾點需要注意的:

1.選擇正確的模式:ADC_Mode_RegSimult,即DUALMOD[3:0] = 0110,ADC2在雙模式中,這些位為保留位

2.開啟ADC的DMA,在雙ADC模式里,為了在主數據寄存器上讀取從轉換數據,必須使能DMA位,即使不使用DMA傳輸規則通道數據。只有ADC1和ADC3能產生DMA請求。所以只需設置ADC1的DMA:ADC_DMACmd(ADC1, ENABLE);

3.ADC2的轉換數據存在ADC1_DR的高半字;

4.不要在2個ADC上轉換相同的通道(兩個ADC在同一個通道上的采樣時間不能重疊)。

5.ADC2的CR2寄存器的第20位——EXTTRIG:規則通道的外部觸發轉換模式必須開啟(軟件啟動的時候也要),這樣才能利用到ADC1的觸發信號。不然的話,需要手動再軟啟動一次ADC2,例如ADC_SoftwareStartConvCmd(ADC2, ENABLE);

但是,假如你設置了這個位之后,就不需要手動軟啟動ADC2了,所以考慮到同步,這樣比較好。用ADC_SoftwareStartConvCmd(ADC2, ENABLE);為什么可以,一方面它 也設置了EXTTRIG位,另一方面也設置了SWSTART。但我覺得先用ADC_ExternalTrigConvCmd(ADC2, ENABLE);的話,一會只要ADC1一啟動,兩者就同 時啟動了,這樣更正確一點。

以下是ADC1配置代碼和使能代碼:

  1. //初始化ADC1  
  2. //這里采用多通道連續采樣,並用DMA1的通道傳送  
  3. //我們默認將開啟通道4~7  
  4. //相應管腳PA4~7  
  5. void Adc1_Multi_Init(void)  
  6. {     
  7.     ADC_InitTypeDef ADC_InitStructure;   
  8.     GPIO_InitTypeDef GPIO_InitStructure;  
  9.   
  10.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1    , ENABLE );   //使能ADC1通道時鍾  
  11.    
  12.   
  13.     RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //設置ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M  
  14.   
  15.     //PA1 作為模擬通道輸入引腳  
  16.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;  
  17.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       //模擬輸入引腳  
  18.     GPIO_Init(GPIOA, &GPIO_InitStructure);    
  19.   
  20.     ADC_DeInit(ADC1);  //復位ADC1,將外設 ADC1 的全部寄存器重設為缺省值  
  21.   
  22.     ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;    //ADC工作模式:ADC1同步規則組模式  
  23.     ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模數轉換工作在掃描模式  
  24.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模數轉換工作在連續轉換模式  
  25.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //轉換由軟件而不是外部觸發啟動  
  26.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //ADC數據右對齊  
  27.     ADC_InitStructure.ADC_NbrOfChannel = 4; //順序進行規則轉換的ADC通道的數目  
  28.     ADC_Init(ADC1, &ADC_InitStructure); //根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器     
  29.   
  30.     ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5 );  
  31.     ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_239Cycles5 );  
  32.     ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_239Cycles5 );  
  33.     ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_239Cycles5 );  
  34.   
  35.     // 開啟ADC的DMA支持(要實現DMA功能,還需獨立配置DMA通道等參數)  
  36.     ADC_DMACmd(ADC1, ENABLE);  
  37. }     
  38. //計算多通道ADC值  
  39. //AD_Value[]是DMA目標地址的數組空間  
  40. u16 Get_Multi_Adc1(void)  
  41. {  
  42.     u32 temp_val=0;  
  43.     u8 t;  
  44.     for(t=0;t<4;t++)  
  45.     {  
  46.         temp_val+=(AD_Value[t] & 0xffff);  
  47.     }  
  48.     return temp_val/4;  
  49. }   

主要需要修改的是這句話,使得ADC處於同步規則組模式。

  1. <strong>ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;  //ADC工作模式:ADC1同步規則組模式</strong>  

AD_Value[]是32位的,用於DMA傳送的目標的ADC數據數組。其中高16位是ADC2的數據,地16位的是ADC1的數據。


其次是ADC2配置代碼和使能代碼:

  1. //初始化ADC2  
  2. //這里采用多通道連續采樣,並用DMA1的通道傳送  
  3. //我們默認將開啟通道10~13  
  4. //相應管腳PC0~3  
  5. void Adc2_Multi_Init(void)  
  6. {     
  7.     ADC_InitTypeDef ADC_InitStructure;   
  8.     GPIO_InitTypeDef GPIO_InitStructure;  
  9.   
  10.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC2    , ENABLE );   //使能ADC2通道時鍾  
  11.    
  12.   
  13.     RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //設置ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M  
  14.   
  15.     //PB0,1 作為模擬通道輸入引腳  
  16.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;  
  17.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       //模擬輸入引腳  
  18.     GPIO_Init(GPIOC, &GPIO_InitStructure);    
  19.   
  20.     ADC_DeInit(ADC2);  //復位ADC2,將外設 ADC2 的全部寄存器重設為缺省值  
  21.   
  22.     ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;    //ADC工作模式:ADC1同步規則組模式  
  23.     ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模數轉換工作在掃描模式  
  24.     ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模數轉換工作在連續轉換模式  
  25.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //轉換由軟件而不是外部觸發啟動  
  26.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //ADC數據右對齊  
  27.     ADC_InitStructure.ADC_NbrOfChannel = 4; //順序進行規則轉換的ADC通道的數目  
  28.     ADC_Init(ADC2, &ADC_InitStructure); //根據ADC_InitStruct中指定的參數初始化外設ADCx的寄存器     
  29.   
  30.     ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5 );  
  31.     ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_239Cycles5 );  
  32.     ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 3, ADC_SampleTime_239Cycles5 );  
  33.     ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 4, ADC_SampleTime_239Cycles5 );  
  34.   
  35.     ADC_ExternalTrigConvCmd(ADC2, ENABLE);                                        //使能ADC2的外部觸發模式   
  36.   
  37.     // 開啟ADC的DMA支持(要實現DMA功能,還需獨立配置DMA通道等參數)  
  38.     //ADC_DMACmd(ADC2, ENABLE);  
  39. }  
  1. //計算多通道ADC值  
  2. //AD_Value2[]是DMA目標地址的數組空間  
  3. u16 Get_Multi_Adc2(void)  
  4. {  
  5.     u32 temp_val=0;  
  6.     u8 t;  
  7.     for(t=0;t<4;t++)  
  8.     {  
  9.         temp_val+=((AD_Value[t]>>16) & 0xffff);  
  10.     }  
  11.     return temp_val/4;  
  12. }  

ADC2主要需要添加下面語句,用於ADC1觸發ADC2的工作。

  1. ADC_ExternalTrigConvCmd(ADC2, ENABLE);                                        //使能ADC2的外部觸發模式   

AD_Value[]是32位的,用於DMA傳送的目標的ADC數據數組。其中高16位是ADC2的數據,地16位的是ADC1的數據。這里使用AD_Value[t]>>16進行移位操作,獲取數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM