ADC:
1.STM32內部的ADC模塊有三個ADC1,ADC2,ADC3,他們彼此獨立,所以可以進行同步采樣。
2ADC的輸入時鐘不得超過14MHz,它是由PCLK2經分頻產生,要在RCC_CFGR配置,再ADC自己的寄存器中在沒有時鐘分頻的配置位。
3.ADC轉換時間: STM32F103xx增強型產,時鐘為56MHz時為1μ s( 時鐘為72MHz為1.17 μ s)
4.ADC的轉換精度默認設置為12位,輸入范圍:ADC輸入范圍:V REF-≤ VIN≤ VREF+
5.共有18個通道,其中外部16個通道,內部兩個通道,內部溫度傳感器連接在ADC1_IN16,內部參考電壓V REFINT連接在ADC1_IN17
6.轉換的啟動方式:有外部觸發,內部外設觸發如TIMx,以及軟件觸發,一次觸發轉換一個組,軟件使能方式通過設置ADC_CR2 寄存器的ADON。
7.兩個組的概念,a.規則組:一般情況下使用的ADC轉換序列;b.注入組,它的優先級高于規則組中的轉換序列,當規則組正在轉換的情況下,入股觸發了注入組,他將會打斷規則組正在進行的轉換,知道注入組轉換完成,再次會帶規則則組轉換。
8總的來說,規則轉換的方式有兩種,即連獨立單次轉換方式、間斷一次啟動轉換n個通道,n可配置、連續不斷地轉換,知道知道設置了停止。連續加是掃描模式下,一次啟動通道會在序列中逐個來回的轉換,然而規則通道組只有一個數據寄存器ADCx_DR,因此下一次轉換完成之前必須將上次轉換的數據值讀出,否則將會 被覆蓋,這是一般會使能DMA請求,讓每次數據刺激轉換完成后產生EOC的同時,也產生DMA請求,DMA將DR中的數據傳至存儲器單元。
而單次轉換模式下必須要每次完成之后查詢EOC或利用中斷將數據讀出,然后再軟件啟動下一次轉換,在這期間若要改變轉換的序列也可以寫入下次采集的通道。和以前使用AD的模式一樣,但這樣耗費時間。
間斷模式,是在整個SQR寄存器組中通過設置n,一次制轉換其中的幾個,知道將這個序列轉換完。暫時未用。
8.ADC的采樣時間時刻配置的,在采樣時間寄存器配置,一次轉換所需要的時間TCONV= 采樣時間+ 12.5 = 14 周期,12.5是轉換周期。
9.有序數據只有12,不足16位,因此要設置第七方式,方便數據的提取,有注入組中能設置轉換的品偏移量,即轉換結果等于采樣值減去偏移量的值,可能是負值,因此右對齊式,高位時符號位的擴展,規則組下高4位全部為0。
10.可以配置ADC轉換的閥值,類似看門狗功能,ADC_HTR 和ADC_LTR寄存器分別配置上下限,不在這個范圍內飾可以產生中斷標志,用戶可以選擇進入中斷。
11.外部觸發模式,主要是外設的觸發信號,TIM的中斷時間來觸發ADC的轉換開始,達到控制采樣時間的的目的,就不用如原來一樣單獨的寫配置定時器中斷。
12.雙ADC使用,雙ADC有很多中模式,最可能用到的就是雙ADC規則同步轉換方式,可查閱Datasheet來配置。
規則單次轉換配置方式:
關閉CONT,關閉SCAN模式,設置n值等于1,ADC獨立模式,初始化結構體基本上是這樣。
然后向SQR組中的某個位置寫入通道號,配置該通道的轉換采樣時間。
使能ADCx,比較重要的是在最后要進行ADC校準,否則可能不準,校準包括復位校準、AD校準,等待校準完成后才能開始轉換。
每次轉換完成查詢EOC標志位,然后讀取DR數據并且使能下一次轉換,也可寫入新的轉換通道。
void Init_ADC()
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //這是使用連續掃描模式時
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
// ADC_InitStructure.ADC_ScanConvMode = DSIABLE;
// ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
// ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 ); //
ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 2, ADC_SampleTime_239Cycles5 ); //
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1))
{
;
}
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1))
{
;
}
}
讀取函數:
void GetADValue()
{
// ADC_RegularChannelConfig(ADC1
評論
查看更多