ADC可以將現(xiàn)實(shí)世界中連續(xù)變化的模擬量,如溫度、壓力、流量、速度、光強(qiáng)等,轉(zhuǎn)換成離散的數(shù)字量,輸入到計(jì)算機(jī)中進(jìn)行處理。按照原理不同,ADC可以分為積分型、逐次逼近型(SAR)、并行比較型、Σ-?調(diào)制型、電容陣列逐次比較型及壓頻變換型。逐次逼近型(SAR)ADC由比較器和DA轉(zhuǎn)換器構(gòu)成,它從最高有效MSB位開始通過逐次比較,按順序以位位單位對輸入電壓與內(nèi)置DA轉(zhuǎn)換器輸出電壓進(jìn)行比較,經(jīng)過多次比較輸出相應(yīng)的數(shù)字值。逐次逼近型(SAR)ADC的電路規(guī)模屬于中等,它的優(yōu)點(diǎn)是速度較快、功耗低、成本適中。
ADC簡介
CKS32F4xx系列產(chǎn)品內(nèi)嵌3個12位SAR型ADC,每個ADC多達(dá)19個復(fù)用通道,可測量來自16個外部、2個內(nèi)部和VBAT通道的信號,具有獨(dú)立模式、雙重模式和三種模式,并支持單次、連續(xù)、掃描或間斷采樣模式下進(jìn)行A/D轉(zhuǎn)換,對于不同AD轉(zhuǎn)換要求幾乎都有合適的模式可選,轉(zhuǎn)換的結(jié)果可以按照左對齊或右對齊的方式存儲在16位數(shù)據(jù)寄存器中。下圖是CKS32F4xx系列產(chǎn)品ADC的結(jié)構(gòu)框圖,每個模塊的具體描述和技術(shù)參數(shù)可以參閱《CKS32F4xx參考手冊》。
ADC主要特性
▲ 分辨率支持12位,10位,8位,6位,可軟件配置
▲支持轉(zhuǎn)換結(jié)束產(chǎn)生中斷、包括規(guī)則通道和注入通道
▲支持單次、連續(xù)、間隔轉(zhuǎn)換模式
▲可獨(dú)立設(shè)置各通道采樣時間
▲規(guī)則通道轉(zhuǎn)換和注入通道轉(zhuǎn)換均有外部觸發(fā)選項(xiàng),支持軟件或者硬件觸發(fā)轉(zhuǎn)換
▲支持模擬看門狗
▲支持雙重或者三重模式(具有2個或以上ADC的器件)
▲支持雙重或者三重模式下可配置的DMA數(shù)據(jù)存儲
▲可配置雙重或者三重交替采樣模式下的轉(zhuǎn)換延遲時間間隔
▲ ADC供電要求:全速模式下為2.4V到3.6V,低速模式下為1.8V
▲ ADC輸入電壓范圍:Vref-≤Vin≤Vref+
▲規(guī)則通道轉(zhuǎn)換期間可產(chǎn)生DMA請求
固件庫中與ADC相關(guān)的主要API
CKS32F4xx系列固件庫中與ADC相關(guān)的API定義在cks32f4xx_adc.h和cks32f4xx_adc.c兩個文件中,前者為頭文件,包含寄存器地址、常量定義、API函數(shù)聲明,后者為API的具體實(shí)現(xiàn)。CKS32F4xx系列產(chǎn)品最多有3個ADC,編號分別為ADC1、ADC2、ADC3,大多數(shù)API的第一個參數(shù)為ADC_TypeDef*ADCx,表示操作的ADC實(shí)體編號。下表列出了常用的API函數(shù):
API函數(shù)原型 | 函數(shù)功能 |
void ADC_DeInit(void) | 復(fù)位ADC外設(shè)寄存器 |
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) | 根據(jù)ADC_InitStruct中參數(shù)初始化ADC |
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) | 復(fù)位結(jié)構(gòu)體成員 |
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) | 根據(jù)結(jié)構(gòu)體參數(shù)初始化ADC外設(shè) |
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC外設(shè) |
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) | 設(shè)置ADC規(guī)則通道的參數(shù)和采樣時間 |
void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) | 軟件啟動ADC轉(zhuǎn)換 |
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) | 得到ADC轉(zhuǎn)換狀態(tài) |
voidADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止每個規(guī)則轉(zhuǎn)換通道的EOC |
void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) | 使能或者禁止ADC的連續(xù)轉(zhuǎn)換模式 |
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ī)則通道最后一次轉(zhuǎn)換的數(shù)值 |
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) | 設(shè)置ADC注入通道的參數(shù)和采樣時間 |
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) | 配置注入通道序列長度 |
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) | 設(shè)置注入通道轉(zhuǎn)換值偏移 |
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) | 配置注入通道的外部觸發(fā) |
void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) | 配置注入通道轉(zhuǎn)換 |
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特定標(biāo)志是否設(shè)置 |
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) | 清除ADC標(biāo)志 |
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) | 通過相應(yīng)標(biāo)志檢測是否發(fā)生相應(yīng)中斷 |
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) | 清除中斷掛起位 |
實(shí)現(xiàn)ADC單通道電壓采集
CKS32F4xx系列的ADC功能繁多,我們設(shè)計(jì)幾個實(shí)驗(yàn)盡量完整的展示ADC的功能。本次課堂主要介紹比較基礎(chǔ)實(shí)用的單通道電壓采集,實(shí)現(xiàn)開發(fā)板上引腳電壓的采集并通過串口打印至PC端串口調(diào)試助手。單通道電壓采集適用AD轉(zhuǎn)換完成中斷,在中斷服務(wù)函數(shù)中讀取數(shù)據(jù),不使用DMA傳輸,在后期多通道采集實(shí)驗(yàn)中再使用DMA傳輸。相關(guān)核心代碼實(shí)現(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時候都必須開啟對應(yīng)的GPIO時鐘,GPIO用于AD轉(zhuǎn)換功能必須配置為模擬輸入模式。
(3)配置ADC工作模式
staticvoidTemp_ADC_Mode_Config(void) { ADC_InitTypeDefADC_InitStructure; ADC_CommonInitTypeDefADC_CommonInitStructure; RCC_APB2PeriphClockCmd(TEMP_ADC_CLK,ENABLE);//開啟ADC時鐘 //-------------------ADCCommon結(jié)構(gòu)體參數(shù)初始化------------------------ ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//獨(dú)立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結(jié)構(gòu)體參數(shù)初始化-------------------------- ADC_StructInit( ADC_InitStructure); ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//ADC分辨率 ADC_InitStructure.ADC_ScanConvMode=DISABLE;//禁止掃描模式,多通道采集才需要 ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//連續(xù)轉(zhuǎn)換 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;//數(shù)據(jù)右對齊 ADC_InitStructure.ADC_NbrOfConversion=1;//轉(zhuǎn)換通道1個 ADC_Init(TEMP_ADC, ADC_InitStructure); //配置ADC通道轉(zhuǎn)換順序?yàn)?,第一個轉(zhuǎn)換,采樣時間為3個時鐘周期 ADC_RegularChannelConfig(TEMP_ADC,TEMP_ADC_CHANNEL,1,ADC_SampleTime_56Cycles); //ADC轉(zhuǎn)換結(jié)束產(chǎn)生中斷,在中斷服務(wù)程序中讀取轉(zhuǎn)換值 ADC_ITConfig(TEMP_ADC,ADC_IT_EOC,ENABLE); ADC_Cmd(TEMP_ADC,ENABLE);//使能ADC ADC_SoftwareStartConv(TEMP_ADC);//開始ADC轉(zhuǎn)換,軟件觸發(fā) }
首先,使用ADC_InitTypeDef和ADC_CommonInitTypeDef結(jié)構(gòu)體分別定義一個ADC初始化和ADC通用類型變量。調(diào)用RCC_APB2PeriphClockCmd()開啟ADC時鐘。接下來使用ADC_CommonInitTypeDef結(jié)構(gòu)體變量ADC_CommonInitStructure來配置ADC為獨(dú)立模式、分頻系數(shù)為2、不需要設(shè)置DMA模式、20個周期的采樣延遲,并調(diào)用ADC_CommonInit函數(shù)完成ADC通用工作環(huán)境配置。我們使用ADC_InitTypeDef結(jié)構(gòu)體變量ADC_InitStructure來配置ADC1為12位分辨率、單通道采集不需要掃描、啟動連續(xù)轉(zhuǎn)換、使用內(nèi)部軟件觸發(fā)無需外部觸發(fā)事件、使用右對齊數(shù)據(jù)格式轉(zhuǎn)換通道為1,并調(diào)用ADC_Init函數(shù)完成ADC1工作環(huán)境配置。
ADC_RegularChannelConfifig函數(shù)用來綁定ADC通道轉(zhuǎn)換順序和時間。它接收4個形參,第一個形參選擇ADC外設(shè),可為ADC1、ADC2或ADC3;第二個形參通道選擇,總共可選18個通道;第三個形參為轉(zhuǎn)換順序,可選為1到16;第四個形參為采樣周期選擇,采樣周期越短,ADC轉(zhuǎn)換數(shù)據(jù)輸出周期就越短但數(shù)據(jù)精度也越低,采樣周期越長,ADC轉(zhuǎn)換數(shù)據(jù)輸出周期就越長同時數(shù)據(jù)精度越高。PC3對應(yīng)ADC通道ADC_Channel_13,這里我們選擇ADC_SampleTime_56Cycles即56周期的采樣時間。
利用ADC轉(zhuǎn)換完成中斷可以非常方便的保證我們讀取到的數(shù)據(jù)是轉(zhuǎn)換完成后的數(shù)據(jù)而不用擔(dān)心該數(shù)據(jù)可能是ADC正在轉(zhuǎn)換時“不穩(wěn)定”數(shù)據(jù)。我們使用ADC_ITConfifig函數(shù)使能ADC轉(zhuǎn)換完成中斷,并在中斷服務(wù)函數(shù)中讀取轉(zhuǎn)換結(jié)果數(shù)據(jù)。ADC_Cmd函數(shù)控制ADC轉(zhuǎn)換啟動和停止。
最后使用軟件觸發(fā)調(diào)用ADC_SoftwareStartConvCmd函數(shù)進(jìn)行使能配置。
(4)在Temp_ADC_NVIC_Config函數(shù)中配置ADC轉(zhuǎn)換完成中斷的優(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中斷服務(wù)程序
voidADC_IRQHandler(void) { if(ADC_GetITStatus(TEMP_ADC,ADC_IT_EOC)==SET) { ADC_ConvertedValue=ADC_GetConversionValue(TEMP_ADC);//讀取ADC的轉(zhuǎn)換值 } ADC_ClearITPendingBit(TEMP_ADC,ADC_IT_EOC); }
中斷服務(wù)函數(shù)一般定義在cks32f4xx_it.c文件內(nèi),我們使能了ADC轉(zhuǎn)換完成中斷,因此在ADC轉(zhuǎn)換完成后就會進(jìn)入中斷服務(wù)函數(shù),在中斷服務(wù)函數(shù)內(nèi)直接讀取ADC轉(zhuǎn)換結(jié)果保存在變量ADC_ConvertedValue(在main.c中定義)中。ADC_GetConversionValue函數(shù)是獲取ADC轉(zhuǎn)換結(jié)果值的庫函數(shù),只有一個形參為ADC外設(shè),可選為ADC1、ADC2或ADC3,該函數(shù)返回一個16位的ADC轉(zhuǎn)換結(jié)果值。
(6)Main程序
intmain(void) { Debug_USART_Config();//初始化USART1 Temp_Init();while(1) { ADC_Vol=(float)ADC_ConvertedValue/4096*(float)3.3;//讀取轉(zhuǎn)換的AD值 printf("rnThecurrentADvalue=%fVrn",ADC_Vol); Delay(0xffffee); } }
主函數(shù)先配置調(diào)試串口相關(guān)參數(shù),接下來調(diào)用Temp_Init函數(shù)進(jìn)行ADC初始化配置并啟動ADC。在ADC中斷服務(wù)函數(shù)中把AD轉(zhuǎn)換結(jié)果保存在變量ADC_ConvertedValue中,可以計(jì)算出對應(yīng)的IO口電壓值,最后把相關(guān)數(shù)據(jù)打印至串口調(diào)試助手。
來源:中科芯MCU
-
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8750瀏覽量
148188 -
adc
+關(guān)注
關(guān)注
99文章
6537瀏覽量
545907 -
比較器
+關(guān)注
關(guān)注
14文章
1660瀏覽量
107472 -
電壓采集
+關(guān)注
關(guān)注
2文章
22瀏覽量
14286
發(fā)布評論請先 登錄
相關(guān)推薦
CKS32F4xx系列DSP功能介紹
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>DSP功能介紹](https://file1.elecfans.com/web2/M00/C3/70/wKgaomXlX9WAF_6LAAAKAECj5iU980.png)
CKS32F4xx系列產(chǎn)品串口DMA傳輸
CKS32F4xx系列ADC單通道電壓采集的實(shí)現(xiàn)
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b><b class='flag-5'>ADC</b><b class='flag-5'>單通道</b><b class='flag-5'>電壓</b><b class='flag-5'>采集</b>的實(shí)現(xiàn)](https://file1.elecfans.com/web2/M00/8D/5C/wKgZomS54KWAb2-6AAA6mj1hqZQ755.png)
CKS32F4xx系列RNG功能設(shè)置
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>RNG功能設(shè)置](https://file1.elecfans.com/web2/M00/A3/86/wKgaomT6gH2AHojwAAAPwIIu7n0544.jpg)
CKS32F4xx系列FSMC功能簡介
![<b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>FSMC功能簡介](https://file1.elecfans.com/web2/M00/C9/52/wKgaomYbgNeAYwUKAABKakV6wDo253.png)
評論