ADC可以將現(xiàn)實世界中連續(xù)變化的模擬量,如溫度、壓力、流量、速度、光強等,轉換成離散的數字量,輸入到計算機中進行處理。按照原理不同,ADC可以分為積分型、逐次逼近型(SAR)、并行比較型、Σ-?調制型、電容陣列逐次比較型及壓頻變換型。逐次逼近型(SAR)ADC由比較器和DA轉換器構成,它從最高有效MSB位開始通過逐次比較,按順序以位位單位對輸入電壓與內置DA轉換器輸出電壓進行比較,經過多次比較輸出相應的數字值。逐次逼近型(SAR)ADC的電路規(guī)模屬于中等,它的優(yōu)點是速度較快、功耗低、成本適中。
ADC簡介
CKS32F4xx系列產品內嵌3個12位SAR型ADC,每個ADC多達19個復用通道,可測量來自16個外部、2個內部和VBAT通道的信號,具有獨立模式、雙重模式和三種模式,并支持單次、連續(xù)、掃描或間斷采樣模式下進行A/D轉換,對于不同AD轉換要求幾乎都有合適的模式可選,轉換的結果可以按照左對齊或右對齊的方式存儲在16位數據寄存器中。下圖是CKS32F4xx系列產品ADC的結構框圖,每個模塊的具體描述和技術參數可以參閱《CKS32F4xx參考手冊》。

ADC主要特性
▲ 分辨率支持12位,10位,8位,6位,可軟件配置
▲支持轉換結束產生中斷、包括規(guī)則通道和注入通道
▲支持單次、連續(xù)、間隔轉換模式
▲可獨立設置各通道采樣時間
▲規(guī)則通道轉換和注入通道轉換均有外部觸發(fā)選項,支持軟件或者硬件觸發(fā)轉換
▲支持模擬看門狗
▲支持雙重或者三重模式(具有2個或以上ADC的器件)
▲支持雙重或者三重模式下可配置的DMA數據存儲
▲可配置雙重或者三重交替采樣模式下的轉換延遲時間間隔
▲ ADC供電要求:全速模式下為2.4V到3.6V,低速模式下為1.8V
▲ ADC輸入電壓范圍:Vref-≤Vin≤Vref+
▲規(guī)則通道轉換期間可產生DMA請求
固件庫中與ADC相關的主要API
CKS32F4xx系列固件庫中與ADC相關的API定義在cks32f4xx_adc.h和cks32f4xx_adc.c兩個文件中,前者為頭文件,包含寄存器地址、常量定義、API函數聲明,后者為API的具體實現(xiàn)。CKS32F4xx系列產品最多有3個ADC,編號分別為ADC1、ADC2、ADC3,大多數API的第一個參數為ADC_TypeDef*ADCx,表示操作的ADC實體編號。下表列出了常用的API函數:
| API函數原型 | 函數功能 |
| void ADC_DeInit(void) | 復位ADC外設寄存器 |
| void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) | 根據ADC_InitStruct中參數初始化ADC |
| void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) | 復位結構體成員 |
| void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) | 根據結構體參數初始化ADC外設 |
| void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC外設 |
| void ADC_TempSensorVrefintCmd(FunctionalState NewState) | 使能或者禁止溫度傳感器通道 |
| void ADC_VBATCmd(FunctionalState NewState) | 使能或者禁止VBAT通道 |
| void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) | 設置ADC規(guī)則通道的參數和采樣時間 |
| void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) | 軟件啟動ADC轉換 |
| FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) | 得到ADC轉換狀態(tài) |
| voidADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止每個規(guī)則轉換通道的EOC |
| void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC的連續(xù)轉換模式 |
| void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) | 配置ADC規(guī)則組通道的間斷模式 |
| void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC的規(guī)則組通道 |
| uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) | 得到規(guī)則通道最后一次轉換的數值 |
| void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC的DMA請求 |
| void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) | 設置ADC注入通道的參數和采樣時間 |
| void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) | 配置注入通道序列長度 |
| void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) | 設置注入通道轉換值偏移 |
| void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) | 配置注入通道的外部觸發(fā) |
| void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) | 配置注入通道轉換 |
| void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能注入通道組的間斷模式 |
| void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) | 使能或者禁止ADC中斷 |
| FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) | 檢測ADC特定標志是否設置 |
| void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) | 清除ADC標志 |
| ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) | 通過相應標志檢測是否發(fā)生相應中斷 |
| void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) | 清除中斷掛起位 |
實現(xiàn)ADC單通道電壓采集
CKS32F4xx系列的ADC功能繁多,我們設計幾個實驗盡量完整的展示ADC的功能。本次課堂主要介紹比較基礎實用的單通道電壓采集,實現(xiàn)開發(fā)板上引腳電壓的采集并通過串口打印至PC端串口調試助手。單通道電壓采集適用AD轉換完成中斷,在中斷服務函數中讀取數據,不使用DMA傳輸,在后期多通道采集實驗中再使用DMA傳輸。相關核心代碼實現(xiàn)如下:
(1)ADC宏定義
//ADCGPIO宏定義 #defineTEMP_ADC_GPIO_PORTGPIOB #defineTEMP_ADC_GPIO_PINGPIO_Pin_0 #defineTEMP_ADC_GPIO_CLKRCC_AHB1Periph_GPIOB //ADC序號宏定義 #defineTEMP_ADCADC1 #defineTEMP_ADC_CLKRCC_APB2Periph_ADC1 #defineTEMP_ADC_CHANNELADC_Channel_8 //ADC中斷宏定義 #defineTemp_ADC_IRQADC_IRQn #defineTemp_ADC_INT_FUNCTIONADC_IRQHandler
(2)ADC GPIO初始化
staticvoidTemp_ADC_GPIO_Config(void) { GPIO_InitTypeDefGPIO_InitStructure; RCC_AHB1PeriphClockCmd(TEMP_ADC_GPIO_CLK,ENABLE);//使能GPIO時鐘 GPIO_InitStructure.GPIO_Pin=TEMP_ADC_GPIO_PIN;//配置IO GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//配置為模擬輸入 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;//不上拉不下拉 GPIO_Init(TEMP_ADC_GPIO_PORT, GPIO_InitStructure); }
使用到GPIO時候都必須開啟對應的GPIO時鐘,GPIO用于AD轉換功能必須配置為模擬輸入模式。
(3)配置ADC工作模式
staticvoidTemp_ADC_Mode_Config(void)
{
ADC_InitTypeDefADC_InitStructure;
ADC_CommonInitTypeDefADC_CommonInitStructure;
RCC_APB2PeriphClockCmd(TEMP_ADC_CLK,ENABLE);//開啟ADC時鐘
//-------------------ADCCommon結構體參數初始化------------------------
ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//獨立ADC模式
ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//時鐘為fpclkx分頻
ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;//禁止DMA直接訪問模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_20Cycles;//采樣時間間隔ADC_CommonInit( ADC_CommonInitStructure);
//-------------------ADCInit結構體參數初始化--------------------------
ADC_StructInit( ADC_InitStructure);
ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//ADC分辨率
ADC_InitStructure.ADC_ScanConvMode=DISABLE;//禁止掃描模式,多通道采集才需要
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//連續(xù)轉換
ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//禁止外部邊沿觸發(fā)
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;//外部觸發(fā)通道,本例子使用軟件觸發(fā),此值隨便賦值即可
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//數據右對齊
ADC_InitStructure.ADC_NbrOfConversion=1;//轉換通道1個
ADC_Init(TEMP_ADC, ADC_InitStructure);
//配置ADC通道轉換順序為1,第一個轉換,采樣時間為3個時鐘周期
ADC_RegularChannelConfig(TEMP_ADC,TEMP_ADC_CHANNEL,1,ADC_SampleTime_56Cycles);
//ADC轉換結束產生中斷,在中斷服務程序中讀取轉換值
ADC_ITConfig(TEMP_ADC,ADC_IT_EOC,ENABLE);
ADC_Cmd(TEMP_ADC,ENABLE);//使能ADC
ADC_SoftwareStartConv(TEMP_ADC);//開始ADC轉換,軟件觸發(fā)
}
首先,使用ADC_InitTypeDef和ADC_CommonInitTypeDef結構體分別定義一個ADC初始化和ADC通用類型變量。調用RCC_APB2PeriphClockCmd()開啟ADC時鐘。接下來使用ADC_CommonInitTypeDef結構體變量ADC_CommonInitStructure來配置ADC為獨立模式、分頻系數為2、不需要設置DMA模式、20個周期的采樣延遲,并調用ADC_CommonInit函數完成ADC通用工作環(huán)境配置。我們使用ADC_InitTypeDef結構體變量ADC_InitStructure來配置ADC1為12位分辨率、單通道采集不需要掃描、啟動連續(xù)轉換、使用內部軟件觸發(fā)無需外部觸發(fā)事件、使用右對齊數據格式轉換通道為1,并調用ADC_Init函數完成ADC1工作環(huán)境配置。
ADC_RegularChannelConfifig函數用來綁定ADC通道轉換順序和時間。它接收4個形參,第一個形參選擇ADC外設,可為ADC1、ADC2或ADC3;第二個形參通道選擇,總共可選18個通道;第三個形參為轉換順序,可選為1到16;第四個形參為采樣周期選擇,采樣周期越短,ADC轉換數據輸出周期就越短但數據精度也越低,采樣周期越長,ADC轉換數據輸出周期就越長同時數據精度越高。PC3對應ADC通道ADC_Channel_13,這里我們選擇ADC_SampleTime_56Cycles即56周期的采樣時間。
利用ADC轉換完成中斷可以非常方便的保證我們讀取到的數據是轉換完成后的數據而不用擔心該數據可能是ADC正在轉換時“不穩(wěn)定”數據。我們使用ADC_ITConfifig函數使能ADC轉換完成中斷,并在中斷服務函數中讀取轉換結果數據。ADC_Cmd函數控制ADC轉換啟動和停止。
最后使用軟件觸發(fā)調用ADC_SoftwareStartConvCmd函數進行使能配置。
(4)在Temp_ADC_NVIC_Config函數中配置ADC轉換完成中斷的優(yōu)先級分組和優(yōu)先級。
staticvoidTemp_ADC_NVIC_Config(void)
{
NVIC_InitTypeDefNVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置優(yōu)先級分組
NVIC_InitStructure.NVIC_IRQChannel=Temp_ADC_IRQ;//配置中斷優(yōu)先級
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init( NVIC_InitStructure);
}
(5)ADC中斷服務程序
voidADC_IRQHandler(void)
{
if(ADC_GetITStatus(TEMP_ADC,ADC_IT_EOC)==SET)
{
ADC_ConvertedValue=ADC_GetConversionValue(TEMP_ADC);//讀取ADC的轉換值
}
ADC_ClearITPendingBit(TEMP_ADC,ADC_IT_EOC);
}
中斷服務函數一般定義在cks32f4xx_it.c文件內,我們使能了ADC轉換完成中斷,因此在ADC轉換完成后就會進入中斷服務函數,在中斷服務函數內直接讀取ADC轉換結果保存在變量ADC_ConvertedValue(在main.c中定義)中。ADC_GetConversionValue函數是獲取ADC轉換結果值的庫函數,只有一個形參為ADC外設,可選為ADC1、ADC2或ADC3,該函數返回一個16位的ADC轉換結果值。
(6)Main程序
intmain(void)
{
Debug_USART_Config();//初始化USART1
Temp_Init();while(1)
{
ADC_Vol=(float)ADC_ConvertedValue/4096*(float)3.3;//讀取轉換的AD值
printf("rnThecurrentADvalue=%fVrn",ADC_Vol);
Delay(0xffffee);
}
}
主函數先配置調試串口相關參數,接下來調用Temp_Init函數進行ADC初始化配置并啟動ADC。在ADC中斷服務函數中把AD轉換結果保存在變量ADC_ConvertedValue中,可以計算出對應的IO口電壓值,最后把相關數據打印至串口調試助手。
來源:中科芯MCU
-
轉換器
+關注
關注
27文章
9418瀏覽量
156326 -
adc
+關注
關注
100文章
7511瀏覽量
555904 -
比較器
+關注
關注
14文章
1928瀏覽量
111899 -
電壓采集
+關注
關注
2文章
25瀏覽量
14695
發(fā)布評論請先 登錄
CKS32F4xx系列產品串口DMA傳輸
CKS32F4xx系列ADC單通道電壓采集的實現(xiàn)
CKS32F4xx系列RNG功能設置
CKS32F4xx系列FSMC功能簡介
CKS32F4xx系列ADC單通道電壓采集
評論