Stellaris系列微控制器的ADC過採樣技術(二)

2021-01-11 電子產品世界

本文引用地址:http://www.eepw.com.cn/article/160365.htm

//

// 初始化ADC,使用定序器0對通道1進行8x過採樣

// 定序器將被其中一個通用定時器觸發

//

ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);

ADCSoftwareOversampleConfigure(ADC_BASE, 0, 8);

ADCSoftwareOversampleStepConfigure(ADC_BASE, 0, 0, (ADC_CTL_CH1

| ADC_CTL_IE | ADC_CTL_END));

//

// 初始化定時器0,每隔10ms觸發一次ADC轉換

//

TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 100);

TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

代碼段1.a的ADC配置表示在採樣完成時產生一個中斷,這樣就必須具有中斷處理程序(見代碼段1.b)。驅動庫的過採樣函數自動將採樣的數據進行平均,因此,中斷處理函數相對來說也是很基礎的。但要記住:要將每次中斷中計算的平均值和計算的開銷提供給中斷處理程序。

代碼段1.b ADC中斷處理程序

void

ADCIntHandler(void)

{

long lStatus;

//

// 清除ADC中斷

//

ADCIntClear(ADC_BASE, 0);

//

// 獲得ADC的平均數據

//

lStatus = ADCSoftwareOversampleDataGet(ADC_BASE, 0, g_ulAverage);

//

// 佔位符,供ADC處理數據

//

}

在將配置步驟和中斷處理程序放在適當位置後,啟動轉換處理。定時器打開(開始計數)之前,ADC定序器和中斷必須使能(見代碼段1.c)。

代碼段1.c 使能ADC和中斷

//

// 使能ADC定序器0及其中斷 (在ADC和NVIC中)

//

ADCSequenceEnable(ADC_BASE, 0);

ADCIntEnable(ADC_BASE, 0);

IntEnable(INT_ADC0);

//

//使能定時器並啟動轉換處理

//

TimerEnable(TIMER0_BASE, TIMER_A);

使用多個定序器或一個定時器實現大於8倍的過採樣

驅動庫的過採樣函數最大只能進行8倍過採樣(根據採樣定序器的硬體限制),因此需要更大過採樣因子的應用必須使用其它的實現。本小節將描述如何使用下面的兩種方法:在過採樣頻率下運行的多個採樣定序器和一個定時器來解決這個問題。

例2:使用多個採樣定序器的16x過採樣

採樣定序器的靈活性允許對其進行多種配置。將採樣定序器0-2累積起來可獲得16個採樣(8+4+4),因此使用採樣定序器0-2可實現16倍過採樣。為使該級別的過採樣能夠工作,定序器中的所有階段必須設置為對相同的模擬輸入進行採樣,這意味著丟棄了使用一個定序器採樣多個輸入的功能。

代碼段2.a使用定序器0-2配置一個10ms的周期轉換。使用一個定時器觸發就可啟動所有3個定序器的採樣操作,而無需複雜的觸發配置。為獲得所需的結果,要對採樣定序器的優先級進行配置,這樣,採樣定序器2的優先級最低(即它最後採樣),並且在採樣定序器2的最後一步之後,配置為發出一個「轉換結束」中斷。

代碼段2.a ADC配置-多個採樣定序器

//

// 初始化ADC,以便使用定序器0-2對通道1進行16x過採樣

// 轉換操作通過GPTM觸發

//

ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);

ADCSequenceConfigure(ADC_BASE, 1, ADC_TRIGGER_TIMER, 1);

ADCSequenceConfigure(ADC_BASE, 2, ADC_TRIGGER_TIMER, 2);

//

// 配置定序器0的序列步驟(sequence step)

//

ADCSequenceStepConfigure(ADC_BASE, 0, 0, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 1, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 2, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 3, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 4, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 5, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 6, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 0, 7, (ADC_CTL_CH1 | ADC_CTL_END));

//

//配置定序器1的序列步驟

//

ADCSequenceStepConfigure(ADC_BASE, 1, 0, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 1, 1, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 1, 2, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 1, 3, (ADC_CTL_CH1 | ADC_CTL_END));

//

//配置定序器2的序列步驟

//

ADCSequenceStepConfigure(ADC_BASE, 2, 0, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 2, 1, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 2, 2, ADC_CTL_CH1);

ADCSequenceStepConfigure(ADC_BASE, 2, 3, (ADC_CTL_CH1 | ADC_CTL_IE

| ADC_CTL_END));

//

// 初始化定時器0,每隔10ms觸發一次ADC轉換

//

TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 100);

TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

在代碼段2.b中,中斷處理程序必須收集FIFO的數據並進行平均計算。因為不需要處理函數開銷就可以獲得所需的結果,所以不使用ADCSequenceDataGet函數,並且使用直接的寄存器讀操作來清空定序器的FIFO。而使用ADCSequenceDataGet時,要求函數定義一個額外的8入口採樣緩衝區,即使使用直接的寄存器讀操作,中斷處理程序中執行的總和計算和平均計算仍然會有可計算的開銷。

代碼段2.b ADC中斷處理程序

void

ADCIntHandler(void)

{

unsigned long ulIdx;

unsigned long ulSum = 0;

//

// 清除中斷

//

ADCIntClear(ADC_BASE, 2);

//

// 獲得來自定序器0的數據

//

for(ulIdx = 8; ulIdx; ulIdx--)

{

ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO0);

}

//

// 獲得來自定序器1和2的數據

//

for(ulIdx = 4; ulIdx; ulIdx--)

{

ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO1);

ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO2);

}

//

// 將過採樣的數據進行平均

//

g_ulAverage = ulSum >> 4;

//

// 佔位符,以便ADC處理代碼

//

}

在啟動轉換處理之前,將採樣定序器和中斷使能(見代碼段2.c)。

代碼段2.c 使能ADC和中斷

//

// 使能定序器和中斷

//

ADCSequenceEnable(ADC_BASE, 0);

ADCSequenceEnable(ADC_BASE, 1);

ADCSequenceEnable(ADC_BASE, 2);

ADCIntEnable(ADC_BASE, 2);

IntEnable(INT_ADC2);

//

// 使能定時器並啟動轉換處理

//

TimerEnable(TIMER0_BASE, TIMER_A);

例3 使用在fOS下運行的定時器進行16x過採樣

另一個實現16x過採樣的方法(無需消耗ADC定序器的大部分資源)是使用一個在過採樣頻率下運行的周期定時器。例如,如果轉換處理每10ms必須返回到主應用程式並且即將進行16倍過採樣,則能夠將定時器配置為每625µs獲得一個採樣值。讓定時器在過採樣頻率下觸發一次轉換明顯地產生了額外的ADC中斷,這必須在應用程式中說明。

將ADC和定時器配置為執行上述操作的代碼見代碼段3.a。

代碼段3.a ADC配置-在fOS下運行的定時器

//

// 初始化ADC,以便在檢測到一次觸發時在通道1、定序器3上獲得一個採樣值。

//

//

ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_TIMER, 0);

ADCSequenceStepConfigure(ADC_BASE, 3, 0, (ADC_CTL_CH1 | ADC_CTL_IE

| ADC_CTL_END));

//

//初始化定時器0,每625µs觸發一次ADC轉換

//

TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 1600);

TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

既然ADC在過採樣頻率下進行採樣操作,中斷處理程序必須知道已獲得的採樣數以及總和(見代碼段3.b)。在累積了16次轉換後,將這16個採樣值進行平均,並清除全局採樣計數變量和總和變量。

代碼段3.b ADC中斷處理程序

void

ADCIntHandler(void)

{

//

// 清除中斷

//

ADCIntClear(ADC_BASE, 3);

//

// 將新的採樣值加到全局總和中

//

g_ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO3);

//

// g_ucOversampleCnt加1

//

g_ucOversampleCnt++;

//

// 如果累積了16個採樣值,則將它們平均並將全局變量復位

//

if(g_ucOversampleCnt == 16)

{

g_ulAverage = g_ulSum >> 4;

g_ucOversampleCnt = 0;

g_ulSum = 0;

}

//

// 佔位符,以便ADC處理代碼

//

}

最後,在使能定時器之前,將定序器3及其中斷使能,並清除全局計數器和總和變量(見代碼段3.c)。

代碼段3.c 使能ADC、中斷並清除全局變量

//

// 使能定序器和中斷

//

ADCSequenceEnable(ADC_BASE, 3);

ADCIntEnable(ADC_BASE, 3);

IntEnable(INT_ADC3);

//

// 將過採樣計數器和總和變量清零

//

g_ucOversampleCnt = 0;

g_ulSum = 0;

//

// 使能定時器並啟動轉換處理

//

TimerEnable(TIMER0_BASE, TIMER_A);

使用滑動平均進行過採樣

當採樣頻率接近ADC的最大採樣率時,滑動平均非常有用。滑動平均應用中的主要元件是採樣緩衝區,它在每次轉換完成時減去/加上數據。

例4將ADC配置為每隔100µs進行一次採樣,採樣緩衝區含有16個入口。注意:應用程式不向採樣緩衝區預先填充有效的數據,這樣,前16個採樣值必須相應地由軟體來處理。ADC配置為在定時器觸發時採樣,並在每次轉換之後將處理器中斷。

例4 使用滑動平均每100µs過採樣

代碼段4.a ADC配置-滑動平均

//

// 初始化ADC,以便在檢測到觸發時在通道1、定時器3上獲得一個採樣值。

//

//

ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_TIMER, 0);

ADCSequenceStepConfigure(ADC_BASE, 3, 0, (ADC_CTL_CH1 | ADC_CTL_IE

| ADC_CTL_END));

//

// 初始化定時器0,每100µs觸發一次ADC轉換

//

TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);

TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 10000);

TimerControlTrigger(TIMER0_BASE, TIMER_A, true);

中斷處理程序必須更新採樣緩衝區並進行平均計算(見代碼段4.b)。在每次ADC中斷時,去掉採樣緩衝區中的最後一個元素,緩衝區中剩下的數據移動一個位置。然後,在計算平均值之前將新的轉換結果放在採樣緩衝區的開始處。中斷處理程序中執行的額外計算又一次增加了開銷,這一點必須要考慮到。

代碼段4.b ADC中斷處理程序

void

ADCIntHandler(void)

{

//

// 清除中斷

//

ADCIntClear(ADC_BASE, 3);

//

// 檢查g_ucOversampleIdx,確保它的值在範圍內

//

if(g_ucOversampleIdx == 16)

{

g_ucOversampleIdx = 0;

}

//

// 從全局總和中減去最早的值

//

g_ulSum -= g_ulSampleBuffer[g_ucOversampleIdx];

//

// 用新的採樣值代替最早的值

//

g_ulSampleBuffer[g_ucOversampleIdx] = HWREG(ADC_BASE + ADC_O_SSFIFO3);

//

// 將新的採樣值加到總和中

//

g_ulSum += g_ulSampleBuffer[g_ucOversampleIdx];

//

// g_ucOversampleIdx加1

//

g_ucOversampleIdx++;

//

// 從採樣緩衝區的數據中獲得平均值

//

g_ulAverage = g_ulSum >> 4;

//

// 佔位符,供ADC處理代碼

//

}

在啟動定時器之前,使能定時器及其中斷(見代碼段4.c)。

代碼段4.c 使能ADC和中斷

//

// 使能定序器和中斷

//

ADCSequenceEnable(ADC_BASE, 3);

ADCIntEnable(ADC_BASE, 3);

IntEnable(INT_ADC3);

//

// 使能定時器並啟動轉換處理

//

TimerEnable(TIMER0_BASE, TIMER_A);

需考慮的問題

本文檔中描述的過採樣技術需要額外的代碼來執行平均計算,附加中斷,和/或大部分採樣定序器資源,因此它在整個系統性能上有一個顯著的影響。在選擇最適合應用的技術時,需在增加的中斷和龐大的中斷處理程序之間進行權衡。

結論

Luminary Micro的採樣定序器結構為過採樣技術的實現提供了大量的選項。當與軟體平均技術相結合時,該結構能夠使系統設計人員有效地在採樣頻率、系統性能和採樣解決方案之間進行權衡。

相關焦點

  • Stellaris系列微控制器的ADC過採樣技術(一)
    Luminary Micro在Stellaris系列微控制器的部分產品中提供了模數轉換器(ADC)模塊。本應用文檔提供了一個基於軟體的過採樣技術,從而使轉換結果的有效位數(ENOB)得到了改善。文檔中描述了對輸入信號執行過採樣的方法,以及在精度和整個系統性能上的影響。過採樣,顧名思義就是從輸入信號中採集額外的轉換數據。
  • ADI公司AD7380系列SAR ADC的片內過採樣
    Σ-Δ ADC的每次轉換結果都是較小但更頻繁的採樣事件所產生的。SAR ADC利用逐次逼近來確定結果。SAR ADC通過逐步方法來確定數字表示的每個比特在單個採樣瞬間是什麼。SAR採樣電荷再分配電容和數模轉換器(DAC)陣列。採樣數據與每個二進位加權電容陣列進行比較。二進位加權電容的總數決定了SAR ADC的位數或解析度。
  • MAXQ3120 混合信號微控制器的應用案例
    maxq3120 就是為了滿足這些要求而開發的低功耗、高速微控制器。它的主要技術規範如下。  監視系統的設計者和廠商一直希望微控制器能夠為日常監視應用提供不斷增加的通用功能,包括滿足用電計量、汽車監控、數據搜集和傳感器調節等方面的要求。maxq3120 就是為了滿足這些要求而開發的低功耗、高速微控制器。它的主要技術規範如下。
  • ESP8266_22基於自身ADC的電壓採樣
    這一節內容比較簡單,就是電壓採樣,在傳統設計中應用還是比較多的。首先看下支持ADC採樣的管腳,找到你手裡模塊的原理圖,我的如下所示:       如上所示,U1的2腳為ADC管腳,而且整個模塊有且僅有這一個電壓採集管腳。CDS1是一個光敏電阻,它和R1組成一個分壓電路。不同強度的光照在CDS1上時,會導致它的阻值變化,最終導致ADC管腳上的電壓發生變化。
  • 利用過採樣增加SAR ADC的動態範圍
    以前有些關於Δ-Σ和SAR(逐次逼近型)ADC概述中,曾討論過信噪比(SNR)和有效位數(ENOB)相關的過採樣技術。過採樣技術最常用於Δ-Σ型ADC,但也可用於SAR ADC。 本文將對此做進一步討論。
  • adc0809引腳圖及功能詳解,adc0809與51單片機連接電路分析
    adc0809是採樣頻率為8位的、以逐次逼近原理進行模—數轉換的器件。其內部有一個8通道多路開關,它可以根據地址碼鎖存解碼後的信號,只選通8路模擬輸入信號中的一個進行A/D轉換。   1.主要特性   1)8路8位A/D轉換器,即解析度8位。   2)具有轉換起停控制端。
  • SAR ADC與Sigma Delta ADC有什麼不一樣?
    工程師郭婷 發表於 2018-08-16 00:15:00 sigma-delta adc的原理
  • 何謂ADC ― 全方位學習模數轉換器(ADC)
    在電子領域中模擬技術是被公認的最難的技術,眾多資深的模擬工程師無一不是從百上千次的實踐中不斷學習,不斷摸索。但是作為初級的模擬工程師呢?如何能夠快速的上手並在模擬技術領域快速的成長呢?
  • 賽普拉斯新增5款基於ARM Cortex-M 內核的微控制器系列產品
    作為嵌入式處理解決方案領域的領導者,賽普拉斯半導體公司今日宣布推出五款基於ARM® Cortex®-M為內核的微控制器產品,為其FM4 MCU系列新增3款高性能靈活MCU(S6E2C系列、S6E2G系列以及S6E2H系列),並且為FM0+產品線新增2款高能效MCU(S6E1B系列和S6E1C系列
  • ...F2系列微控制器 能夠滿足工廠自動化苛刻要求的高速Cortex-M3微...
    IXXAT自動化技術有限公司開發的IEEE 1588協議軟體讓設備廠商能夠輕鬆、快速地開發IEEE 1588兼容設備,這款軟體的原始碼採用C語言,可實現在任何平臺上。為了在意法半導體的STM32-F2系列微控制器上實現IEEE 1588協議,IXXAT為STM32-F2用戶提供一個定製版協議軟體,該解決方案大幅簡化並加快了協議的實現過程。
  • RT-Thread ADC設備學習筆記
    1、實踐需求1.1 硬體配置LED、煙感模塊1.2 軟體需求設備開機,當在串口終端輸入adc_cmd on時,adc數據開始列印,LED燈熄滅,當在串口終端輸入adc_cmd off,adc數據關閉列印,LED燈開始閃爍。本節,我們將會學習到RT-Thread ADC設備的基本使用。接下來,我們將基於RT-Thread Studio來構建。
  • 多數SAR ADC即將被淘汰,勝出的需要哪些性能?
    DAC通常由一組二進位加權元件組成,在本例中使用的是電容。一些應用中通常需要能夠對極性未知的差分輸入信號進行轉換。轉換差分信號也有助於通過共模噪聲抑制來提高結果的精度。ls0ednc實現差分ADC常面臨諸多限制因素,其中一個是需要在逐次逼近期間將比較器的輸入保持在其共模範圍內。
  • 交織型採樣ADC的基本原理
    在通信基礎設施中,存在著一種推動因素,使ADC的採樣速率不斷提高,以便支持多頻段、多載波無線電,除此之外滿足DPD(數字預失真)等線性化技術中更寬的帶寬要求。在軍事和航空航天領域,採樣速率更高的ADC可讓多功能系統用於通信、電子監控和雷達等多種應用中——此處僅舉數例。工業儀器儀表應用中始終需要採樣速率更高的ADC,以便充分精確地測量速度更高的信號。
  • STM32 ADC 模數轉換的簡單實現
    //掃描通道數ADC_Init(ADC1, &ADC_InitStructure);ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_1Cycles5);//通道X,採樣時間為
  • 正點原子-戰艦V3第二十二章 ADC 實驗
    STM32F103 系列最少都擁有 2 個 ADC,我們選擇的 STM32F103ZET 包含有 3 個 ADC。ADC 的轉換時間可以由以下公式計算:Tcovn=採樣時間+12.5 個周期其中:Tcovn 為總轉換時間,採樣時間是根據每個通道的 SMP 位的設置來決定的。
  • 關於ADC中幾種通用的輸入採樣結構
    由此看來, 模數(A/D)轉換器的設計是一項艱巨的挑戰,因為必須在系統級考慮各種不同的輸入採樣結構,並做出正確的選擇。本文將探討幾種通用的輸入採樣結構,並討論每種結構對系統其他部分的影響。 輸入採樣基本電路結構 隨著數位化的普及和技術的發展,A/D轉換器的應用無處不見。在目前使用的眾多 CMOS A/D轉換器中,一種常用解決方案是使用 開關電容結構實現輸入採樣。
  • 第51節:利用ADC0832採集電壓信號進行濾波處理
    片選信號置為低電平 */adc0832_cs_dr = 0;/* 第一個脈衝,開始位 */adc0832_data_sr_dr = 1;adc0832_clk_dr = 0;delay_short(1);adc0832_clk_dr = 1;/* 第二個脈衝,選擇通道 */adc0832_
  • 基於12位採樣精度ADC晶片ADC12062實現數據採集測控系統的設計
    基於12位採樣精度ADC晶片ADC12062實現數據採集測控系統的設計 馬立軍 發表於 2020-12-25 10:31:43 1 前言 隨著計算機技術的飛速發展和普及
  • adc0832
    相比之前一直使用的也是8位的AVR相比,感覺STM8更為強大,晶片特點如下:  內核:具有3級流水線的哈佛結構、擴展指令集  程序存儲器:8K字節Flash;RAM:1K字節  數據存儲器:640 字節真正的數據EEPROM;可達30萬次擦寫  更重要的一點就是STM8系列若使用庫編程的話,可以方便的不同晶片的程序移植。甚至可以方便的移植到STM32上面,大大減輕了更新硬體的重寫程序的工作量。
  • 採用ARM(R) Cortex(TM)-M3 處理器的流明諾睿微電子新型 Stellaris...
    30款獲獎的 Stellaris 系列新產品增添了 USB 連接、卓越的運動控制性能、更小巧的封裝選擇以及綠色應用能效 德克薩斯州奧斯汀2008年4月16日電 /新華美通/ -- 基於 ARM Cortex(TM)-M3 獲獎的 Stellaris(R) 系列微控制器開發商流明諾睿微電子 (Luminary