當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > ADC
ADC
時間:2019-07-29 來源:成都中心,楊老師
一、ADC介紹
1.基本介紹
ADC,Analog-to-Digital Converter的縮寫,指模/數(shù)轉(zhuǎn)換器或者模數(shù)轉(zhuǎn)換器 。是指將連續(xù)變化的模擬信號轉(zhuǎn)換為離散的數(shù)字信號的器件。真實(shí)世界的模擬信號,例如溫度、壓力、聲音或者圖像等,需要轉(zhuǎn)換成更容易儲存、處理和發(fā)射的數(shù)字形式。模/數(shù)轉(zhuǎn)換器可以實(shí)現(xiàn)這個功能,在各種不同的產(chǎn)品中都可以找到它的身影。與之相對應(yīng)的DAC,Digital-to-Analog Converter,它是ADC模數(shù)轉(zhuǎn)換的逆向過程。
ADC最早用于對無線信號向數(shù)字信號轉(zhuǎn)換。如電視信號,長短播電臺發(fā)接收等。

典型的模擬數(shù)字轉(zhuǎn)換器將模擬信號轉(zhuǎn)換為表示一定比例電壓值的數(shù)字信號。然而,有一些模擬數(shù)字轉(zhuǎn)換器并非純的電子設(shè)備,例如旋轉(zhuǎn)編碼器,也可以被視為模擬數(shù)字轉(zhuǎn)換器。
數(shù)字信號輸出可能會使用不同的編碼結(jié)構(gòu)。通常會使用二進(jìn)制二補(bǔ)數(shù)(也稱作“補(bǔ)碼”)進(jìn)行表示,但也有其他情況,例如有的設(shè)備使用格雷碼(一種循環(huán)碼)。
2.采集原理
在A/D轉(zhuǎn)換中,因?yàn)檩斎氲哪M信號在時間上是連續(xù)的,而輸出的數(shù)字信號是離散量,所以進(jìn)行轉(zhuǎn)換時只能按一定的時間間隔對輸入的模擬信號進(jìn)行采樣,然后再把采樣值轉(zhuǎn)換為輸出的數(shù)字量。通過A/D轉(zhuǎn)換需要經(jīng)過采樣、保持量化、編碼四個步驟。也可將采樣、保持合為一步,量化、編碼合為一步,共兩大步來完成。
二、對比exynos4412和stm32f10的ADC編程
1.exynos ADC 介紹
(1)10 位或 12 位 CMOS 模數(shù)轉(zhuǎn)換器(ADC)由4通道模擬輸入組成。它利用 5MHz A/D 轉(zhuǎn)換器時鐘以最大 1MSPS 的轉(zhuǎn)換速率將模擬輸入信號轉(zhuǎn)換為 10 位或 12 位二進(jìn)制數(shù)字代碼。A/D 轉(zhuǎn)換器采用片上 sample-and-hold 功能。ADC 支持低功耗模式.
(2)ADC 包括下面的特性
分辨率:10-bit / 12-bit(可選)
微分非線性誤差:2.0 LSB(MAX.)
★注:積分非線性表示了ADC器件在所有的數(shù)值點(diǎn)上對應(yīng)的模擬值和真實(shí)值之間誤差最大的那一點(diǎn)的誤差值,也就是輸出數(shù)值偏離線性最大的距離。單位是LSB。例如,一個12bit的ADC,INL值為1LSB,那么,對應(yīng)基準(zhǔn)4.095V,測某電壓得到的轉(zhuǎn)換結(jié)果是1.000V,那么,真實(shí)電壓值可能分布在0.999V到1.001V之間。
積分非線性誤差:4.0 LSB(Max.)
頂部偏移誤差:0~+55 LSB
底部偏移誤差:0~-55 LSB
最大轉(zhuǎn)換速率:1 MSPS
低功耗
電源電壓:1.8V(典型值),1.0V(典型值,數(shù)字 I/O 接口)
模擬輸入范圍:0~1.8V
2.stm32f10 ADC 介紹
12 位 ADC 是一種逐次逼近型模擬數(shù)字轉(zhuǎn)換器。它有多達(dá) 19 個通道,可測量 16 個外部和3個內(nèi)部信號源。各通道的 A/D 轉(zhuǎn)換可以單次、連續(xù)、掃描或間斷模式執(zhí)行。ADC 的結(jié)果可以左對齊或右對齊方式存儲在 16 位數(shù)據(jù)寄存器中。
模擬看門狗允許應(yīng)用程序檢測輸入電壓是否超出了用戶設(shè)定的高 / 低閥值。
一個有效低功耗模式實(shí)施允許在低頻情況下實(shí)現(xiàn)低能耗。
3.stm32f10的ADC(DMA)編程
#define ADC1_DR_Address ((u32)0x40012400+0x4c)
__IO uint16_t ADC_ConvertedValue;
/*
* 函數(shù)名:ADC1_GPIO_Config
* 描述 :使能ADC1和DMA1的時鐘,初始化PC.01
* 輸入 : 無
* 輸出 :無
* 調(diào)用 :內(nèi)部調(diào)用
*/
static void ADC1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure PC.01 as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);// PC1,輸入時不用設(shè)置速率
}
/* 函數(shù)名:ADC1_Mode_Config
* 描述 :配置ADC1的工作模式為MDA模式
* 輸入 : 無
* 輸出 :無
* 調(diào)用 :內(nèi)部調(diào)用
*/
static void ADC1_Mode_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/* DMA channel1 configuration */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;//內(nèi)存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設(shè)地址固定
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; //內(nèi)存地址固定
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //半字
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循環(huán)傳輸
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration */
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //獨(dú)立ADC模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //禁止掃描模式,掃描模式用于多通道采集
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //開啟連續(xù)轉(zhuǎn)換模式,即不停地進(jìn)行ADC轉(zhuǎn)換
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //不使用外部觸發(fā)轉(zhuǎn)換
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集數(shù)據(jù)右對齊
ADC_InitStructure.ADC_NbrOfChannel = 1; //要轉(zhuǎn)換的通道數(shù)目1
ADC_Init(ADC1, &ADC_InitStructure);
/*配置ADC時鐘,為PCLK2的8分頻,即9Hz*/
RCC_ADCCLKConfig(RCC_PCLK2_p8);
/*配置ADC1的通道11為55. 5個采樣周期,序列為1 */
ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/*復(fù)位校準(zhǔn)寄存器 */
ADC_ResetCalibration(ADC1);
/*等待校準(zhǔn)寄存器復(fù)位完成 */
while(ADC_GetResetCalibrationStatus(ADC1));
/* ADC校準(zhǔn) */
ADC_StartCalibration(ADC1);
/* 等待校準(zhǔn)完成*/
while(ADC_GetCalibrationStatus(ADC1));
/* 由于沒有采用外部觸發(fā),所以使用軟件觸發(fā)ADC轉(zhuǎn)換 */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*
* 函數(shù)名:ADC1_Init
* 描述 :無
* 輸入 :無
* 輸出 :無
* 調(diào)用 :外部調(diào)用
*/
void ADC1_Init(void)
{
ADC1_GPIO_Config();
ADC1_Mode_Config();
}
int main(void)
{
/* USART1 config */
USART1_Config();
/* enable adc1 and config adc1 to dma mode */
ADC1_Init();
while (1)
{
ADC_ConvertedValueLocal =(float) ADC_ConvertedValue/4096*3.3; // 讀取轉(zhuǎn)換的AD值
printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue);
printf("\r\n The current AD value = %f V \r\n",ADC_ConvertedValueLocal);
Delay(2000); // 延時
}
}
4.Exynos4412 ADC 編程
代碼如下:
int main ()
{
ADCCON = ADCCON | 1 << 16; //1通道 12bit
ADCCON = ADCCON | 1 << 14; //使能預(yù)分頻
ADCCON = ADCCON & (~(0xff << 6)) | (19 << 6); //分頻值19
ADCCON = ADCCON | 1 << 2; // Standby mode
ADCCON = ADCCON & ~(1 << 1); //stop
unsigned int value = 0;
while (1)
{
ADCCON = ADCCON | 1; //start
while(!(ADCCON & (1 << 15))); //等待結(jié)束
value = ADCDAT & 0xfff;
value = value * 1.8/4096 *1000;
// printf("value = %dmv \n",value);
delay();
}
return 0;
}

