TMS320F28027之ADC

TMS320F28027之ADC

參考文檔SPRUGE5F

TMS320F28027的ADC功能:

1.12位雙採樣保持電路。

2.同時採樣和序列採樣方式。

3.全範圍電壓輸入,0V到3.3V固定,或者VREFLO到VREFHI可調。

4.系統時鐘全頻運行,無需分頻。

5.16輸入通道。

6.16個SOC配置,設置觸發,採樣窗口,通道。

7.16個獨立保存轉換結果的結果寄存器。

8.多觸發源。

9.9個靈活的PIE中斷。

 

 

SOC操作原理:

與以往的ADC類型不同,TMS320F28027的ADC爲3型,它是基於SOC的而不是基於序列的。SOC可以配置定義一個單獨通道的獨立轉換。包括三種配置:開始轉換的觸發源,轉換的通道,採樣窗口的大小。每個SOC是獨立配置的,可以有很多種觸發源,通道,採樣窗口大小的組合。如果需要,多個SOC可以配置成一樣的觸發源,通道,採樣窗口大小。這提供了一種靈活的配置方法。可以配置轉換在不同通道用不同的觸發獨立採樣。可以用一個單獨的觸發過採樣一個相同的通道。可以創建同一個觸發不同通道的轉換序列。

SOCx的觸發源由ADCSOCxCTL寄存器中的TRIGSEL和ADCINTSOCSEL1或 ADCINTSOCSEL2 寄存器配置。軟件可以通過ADCSOCFRC1寄存器產生一個SOC事件。通道和採樣窗口大小可以通過ADCSOCxCTL寄存器的CHSEL和ACQPS配置。

      

採樣保持窗口:

     外部驅動能力的不同影響推動模擬信號速度和有效性。有一些電路需要更長的時間,使電荷正確地轉移到ADC的採樣電容。爲了滿足需求,ADC可以在SOC中獨立地控制採樣窗口的寬度。每個ADCSOCxCTL寄存器都有6位域,ACQPS,用來決定採樣保持窗口的大小。寫到這個位域的值要比期望的採樣保持窗口的包括的週期要少1。例如:位域的值爲15,那就需要16個週期來採樣。允許最少的採樣週期是7(ACQPS=6)。完成一次轉換的時間由採樣時間加轉換時間(13個ADC時鐘)組成。

 

 

ONESHOT單次轉換支持

       該模式將允許你在循環計劃的下一個SOC觸發時,執行一次循環轉換。這種模式只適用於循環輪中的通道。那些沒有配置在循環輪中觸發的通道,將會基於ADCSOCPRIORITYCTL寄存器中的SOCPRIORITY確定優先級。

       ONESHOT模式對順序和同時採樣方式作用如下:

順序模式:只有在RR模式中的下一個激活的soc才允許生成。觸發其它所有的soc均會被忽略。

同時模式:如果當前RR指針指向的SOC使能了同時採樣方式,激活的SOC會從當前的指針增加到二個,這是因爲同時採樣方式會產生SOCx和SOCx+1的結果,而且SOCx+1不會被用戶觸發。

 

 

 

AD轉換的優先級:

       當數個SOC標誌同時被設置,兩種形式的優先級順序中的一種決定它們轉換的順序。默認的決定方式是輪轉。在這種策略中,沒有某個SOC會有比其它更高的優先級。優先級由輪轉指針決定。ADCSOCPRIORITYCTL寄存器中的RRPOINTER指向最後轉換的SOC。最高優先級SOC就是下一個比RRPOINTER值大的SOC,在SOC0到SOC15中輪迴。復位時的值是32,因爲0表示轉換已經發生。當RRPOINTER值爲32,最高優先級的是SOC0。當ADCCTL1.RESET被置位或者SOCPRICTL寄存器被寫入,RRPOINTER被設備復位。

       ADCSOCPRIORITYCTL寄存器的SOCPRIORITY可用於配置所有SOC的優先級。如果一個SOC被設置成高優先級,它將會當前轉換完成之後中斷輪轉,把自己插入到下一次轉換中。當轉換完成,輪轉在被中斷處繼續。如果兩個高優先級的SOC同時被觸發,編號較低的SOC被優先考慮。

 

 

 

同時採樣模式:

       在某些應用中,保持兩個採樣的信號之間的最小延遲是非常重要的。ADC模塊包括雙採樣保持電路,允許兩個不同的通道同時採樣。同時採樣模式是通過ADCSAMPLEMODE寄存器爲兩個soc配置的。偶數SOC與接着的奇數SOC作爲一對,使用同一個使能位。這一對的動作如下:

1.     其中一個SOCx的觸發將開始一對的轉換。

2.     一對通道的轉換包括A和B對應的CHSEL的值(0-7)。

3.     兩個通道同時採樣。

4.     A通道先轉換。

5.     A通道轉換結束,偶數EOCx將會產生一個脈衝。B通道轉換結束,奇數EOCx將會產生一個脈衝。

6.     A通道的轉換結果將會存放在偶數ADCRESULTx寄存器中,A通道的轉換結果將會存放在偶數ADCRESULTx寄存器中。

 

 

 

 

轉換結束和中斷操作:

       由於有16個獨立的SOCx配置,所以有16個EOCx標誌。在序列採樣中,EOCx是直接與SOCx相關聯的。在同時採樣模式中,如上5所述。根據ADCCTL1.INTPULSEPOS的設定,EOCx脈衝將會發生在轉換開始或者結束時。

       ADC模塊包括9個能被PIE標誌或者通過PIE的中斷,每個中斷都可以配置接受EOCx信號作爲中斷源。哪個EOCx信號作爲中斷源是在INTSELxNy寄存器中配置的。另外,ADCINT1和ADCINT2信號可作爲一個SOCx的觸發。這有利於建立一個連續的轉換。

 

 

 

 

上電序列:

ADC復位後是關閉狀態。在寫任意ADC寄存器之前必須置位PCLKCR0寄存器中的ADCENCLK位。啓動ADC的操作序列如下:

1.     如果希望使用外部參考源,在ADCCTL1寄存器的ADCREFSEL中使能這種模式。

2.     在ADCCTL1寄存器(5-7位ADCPWDN,ADCBGPWD,ADCREFPWD)中一起啓動參考源,帶隙和模擬電路。

3.    通過設置ADCCTL1寄存器的ADCENABLE使能ADC。

4.    在首次轉換之前延時1毫秒。

 

 

 

ADC校準:

任何轉換器都固有一個零偏移誤差和滿量程的增益誤差。該ADC出廠校時在25攝氏度校正兩者,同時允許用戶修改任何偏移量的校正應對應用程序環境的影響,如環境溫度。除非處在某些仿真環境下,或者需要修改出廠設置,用戶不需要執行任何特定的操作。ADC將會在設備引導過程中得到合適的校正。

 

 

 

廠家設定與校準功能:

       在製造和測試過程中,德州儀器伴隨着一對內部晶振的設置,校正一些ADC設置。這些設置內嵌在保留的OTP memory中,作爲一個C語言可調用函數Device_cal(),在Boot ROM啓動引導過程中,程序調用這個函數寫出廠設置到各個有效寄存器。在這種情況發生時,ADC和內部振盪器不會保留他們的指定參數。如果引導程序在仿真過程中被跳過,用戶必須確保校準設置能被寫入各寄存器,以確保ADC和內部振盪器滿足在數據手冊中的要求。這可以手動調用Device_cal(),或者在應用程序中設定。

 

 

 

ADC零點偏移校準:

零點偏移誤差被定義爲,當轉換一個在VREFLO電壓時得到的結果。這個基本誤差會影響ADC的所有轉換,包括滿刻度的增益和線性度指標,決定了轉換器的直流精度。零點偏移誤差可能是正的,或者是負的,正的意味着轉換VREFLO時得到一個正的結果。負的意味着轉換一個高於VREFLO的電壓結果仍會是0。爲了更正這種錯誤,兩種誤差的補碼都會被寫入ADCOFFTRIM寄存器。這個寄存器的值在AD轉換結果保存到ADC結果寄存器之前會被用到。此操作被完全包含在ADC內核,所以結果的定時將不會受到影響,ADC能夠保持全動態範圍通過修改微調值。調用Device_cal()把廠家校正的零點偏移寫到ADCOFFTRIM寄存器,用戶能夠修改ADCOFFTRIM的值以減少環境造成偏移誤差。這個可以通過設置ADCCTRL1的VREFLOCONV位實現,不需要任何一個ADC通道。

如下步驟重新校準ADC偏移:

1.     Set ADCOFFTRIM to80 (50h)

2.     SetADCCTL1.VREFLOCONV to 1

3.     Perform multiple conversions on B5 (i.e. sampleVREFLO) and take an average to account for board noise

4.     Set ADCOFFTRIM to 80 (50h) minus the averageobtained in step 3

5.     SetADCCTL1.VREFLOCONV to 0.

文件DSP2802x(3x)_Adc.c中的AdcOffsetSelfCal()函數實現了以上操作。

 

 

 

ADC滿量程增益校準:

       增益錯誤是一個增量,隨着輸入電壓的增加。滿量程增益錯誤發生在輸入電壓最大值的時候。如同偏移誤差一樣,增益誤差可能是正的也可能是負的。一個正的滿量程增益誤差,意味着輸入未來最大值之前轉換結果就已經到達最大值。一個負的滿量程增益誤差,意味着轉換結果永遠達不到最大值。校正函數Device_cal()會寫一個廠家調整值到ADCREFTRIM寄存器以矯正ADC的滿量程增益誤差。這個寄存器在調用Device_cal()之後不應該被改動。

 

 

 

ADC偏移電流校正:

爲了增加ADC的精度,Device_cal()函數同樣會向ADC的一個寄存器寫入廠家調整值矯正偏移電流,這個寄存器在調用Device_cal()之後不應該被修改。

 

 

 

程序設計:

       以CPU TIM0爲觸發,同時採樣兩路電壓。



程序:

/*********************************************
    標題:ADC_test.c
    軟件平臺:CCS v5.2
    硬件平臺:C2000 LaunchPad
    主頻:60M

      描述:練習ADC,同時採樣模式,ADCINA4與ADCINB4

      基於2802x C/C++ Header Files V1.26


    author:小船
    data:2012-10-08

    As supplied, this project is configured for "boot to SARAM"
    operation.  The 2802x Boot Mode table is shown below.

    $Boot_Table
    While an emulator is connected to your device, the TRSTn pin = 1,
    which sets the device into EMU_BOOT boot mode. In this mode, the
    peripheral boot modes are as follows:

      Boot Mode:   EMU_KEY        EMU_BMODE
                   (0xD00)	     (0xD01)
      ---------------------------------------
      Wait		 !=0x55AA           X
      I/O		   0x55AA	         0x0000
      SCI		   0x55AA	         0x0001
      Wait 	       0x55AA	         0x0002
      Get_Mode	   0x55AA	         0x0003
      SPI		   0x55AA	         0x0004
      I2C		   0x55AA	         0x0005
      OTP		   0x55AA	         0x0006
      Wait		   0x55AA	         0x0007
      Wait		   0x55AA	         0x0008
      SARAM		   0x55AA	         0x000A	  <-- "Boot to SARAM"
      Flash		   0x55AA	         0x000B
	  Wait		   0x55AA            Other

   Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
   according to the Boot Mode Table above. Build/Load project,
   Reset the device, and Run example

   $End_Boot_Table
**********************************************/
#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include "LEDs.h"

interrupt void tim0_isr(void);
interrupt void ADC_convered(void);

Uint16 ADCINA4_Voltage_sum = 0;
Uint16 ADCINB4_Voltage_sum = 0;
Uint16 ADCINA4_Voltage = 0;
Uint16 ADCINB4_Voltage = 0;
char convered_count = 0;

void main(void)
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO:
// This example function is found in the DSP2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example


// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2802x_DefaultIsr.c.
// This function is found in DSP2802x_PieVect.c.
   InitPieVectTable();


// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2802x_InitPeripherals.c
// InitPeripherals(); // Not required for this example

// Step 5. User specific code:

   InitAdc();

   EALLOW;

   AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0 = 1; //同時採樣
   AdcRegs.ADCSOC0CTL.bit.CHSEL = 4;       //soc通道選擇
   AdcRegs.ADCSOC1CTL.bit.CHSEL = 12;
   AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;     //採樣時間
   AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;
   AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 1;    //soc觸發選擇,TIM0
   AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;  //結果存入寄存器才產生中斷

   PieVectTable.ADCINT1 = &ADC_convered;
   AdcRegs.INTSEL1N2.bit.INT1SEL = 1;    //中斷線1選擇soc1
   AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;
   AdcRegs.INTSEL1N2.bit.INT1E	= 1;	//中斷使能

   PieCtrlRegs.PIEIER1.bit.INTx1 = 1;	//使能int1.1
   EDIS;

/****************設置定時器,用以觸發ADC*****************/
   CpuTimer0Regs.TPR.bit.TDDR = 59;
   CpuTimer0Regs.TPRH.bit.TDDRH = 0; //對輸入時鐘60分頻,60M/60=1M
   CpuTimer0Regs.PRD.all = 500000;//定時0.5s
   CpuTimer0Regs.TCR.bit.TRB = 1; //reload
   CpuTimer0Regs.TCR.bit.TIE = 1; //使能中斷
   CpuTimer0Regs.TCR.bit.TSS = 0; //開始計數

   EALLOW;
   PieVectTable.TINT0 = &tim0_isr;
   PieCtrlRegs.PIECTRL.bit.ENPIE = 1;	//使能PIE
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;	//使能int1.7
   IER |= 0x0001;//使能GROUP1
   EINT;
   EDIS;

   LEDs_init();
   while(1)
   {
   };
}

interrupt void ADC_convered(void)
{

	LED_toggle(LED2);
	ADCINA4_Voltage_sum += AdcResult.ADCRESULT0;
	ADCINB4_Voltage_sum += AdcResult.ADCRESULT1;
	AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
	convered_count++;
	/*********轉換16次,取平均值*********/
	if(convered_count > 15)
	{
		ADCINA4_Voltage = ADCINA4_Voltage_sum >> 4;//相當於除以16
		ADCINB4_Voltage = ADCINB4_Voltage_sum >> 4;
		ADCINA4_Voltage_sum = 0;
		ADCINB4_Voltage_sum = 0;
		convered_count = 0;
	}
}

interrupt void tim0_isr(void)
{
	LED_toggle(LED0);
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//===========================================================================
// No more.
//===========================================================================

程序運行結果:







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章