?? f280x adc implementation.c
字號:
// TI File $Revision: /main/5 $
// Modified by Pradeep Shinde
//###########################################################################
//
// FILE: F28xx ADC setup Example.c
//
// TITLE: Interfacing 28xx ADC.
//
/* ***********************************************************
* THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
* REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
* INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
* COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
* TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
* POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
* INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
* YOUR USE OF THE PROGRAM.
*
* IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
* THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
* OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
* EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
* REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
* OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
* USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
* AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
* YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
* (U.S.$500).
*
* Unless otherwise stated, the Program written and copyrighted
* by Texas Instruments is distributed as "freeware". You may,
* only under TI's copyright in the Program, use and modify the
* Program without any charge or restriction. You may
* distribute to third parties, provided that you transfer a
* copy of this license to the third party and the third party
* agrees to these terms by its first use of the Program. You
* must reproduce the copyright notice and any other legend of
* ownership on each copy or partial copy, of the Program.
*
* You acknowledge and agree that the Program contains
* copyrighted material, trade secrets and other TI proprietary
* information and is protected by copyright laws,
* international copyright treaties, and trade secret laws, as
* well as other intellectual property laws. To protect TI's
* rights in the Program, you agree not to decompile, reverse
* engineer, disassemble or otherwise translate any object code
* versions of the Program to a human-readable form. You agree
* that in no event will you alter, remove or destroy any
* copyright notice included in the Program. TI reserves all
* rights not specifically granted under this license. Except
* as specifically provided herein, nothing in this agreement
* shall be construed as conferring by implication, estoppel,
* or otherwise, upon you, any license or other right under any
* TI patents, copyrights or trade secrets.
*
* You may not use the Program in non-TI devices.
* ********************************************************* */
// ASSUMPTIONS:
//
// This program requires the DSP280x header files and setup source files
// for the peripherals used. These are default settings. This files allows
// to modify the ADC parameters.
//
// Make sure the CPU clock speed is properly defined in
// DSP280x_Examples.h before compiling this example.
//
// Connect the signal to be converted to channel A0.
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 280x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// Boot GPIO18 GPIO29 GPIO34
// Mode SPICLKA SCITXDA
// SCITXB
// -------------------------------------
// Flash 1 1 1
// SCI-A 1 1 0
// SPI-A 1 0 1
// I2C-A 1 0 0
// ECAN-A 0 1 1
// SARAM 0 1 0 <- "boot to SARAM"
// OTP 0 0 1
// I/0 0 0 0
//
//
// DESCRIPTION:
//
// As an example, Channel A0 is converted forever and logged in a buffer (SampleTable)
// Sequencer1 is used and SEQ1INT interrupt used for transferring counts to buffer.
//
// Open a memory window to SampleTable to observe the buffer
// RUN for a while and stop and see the table contents.
//
// Watch Variables:
// SampleTable - Log of converted values.
//
//###########################################################################
//
// Original source by: S.S.
//
// $TI Release: DSP280x V1.30 $
// $Release Date: 2007 $
//###########################################################################
#include "DSP280x_Device.h" // DSP280x Headerfile Include File
#include "DSP280x_Examples.h" // DSP280x Examples Include File
interrupt void seq1int_isr(void);
// Values for ADC setup parameters
#define ADC_MODCLK 0x4 // Divider for high-speed peripheral clock. HSPCLK = SYSCLKOUT/2*ADC_MODCLK
// If this value =4, for CPU clock = 100 MHz. HSPCLK will be = 100/(2*4) = 12.5MHz
#define ADC_CKPS 0x0 // Divider for ADC module clock. ADC_Fclk = HSPCLK/2*ADC_CKPS.
//If ADC_CKPS=0, ADC_Fclk=HSPCLK. Here =12.5MHz
#define ADC_CPS 0x0 // Additional prescaler for ADC Core clock. ADCCLK = ADC_Fclk/ 1+ADC_CPS
// ADC_CPS can be either 0 or 1. Other values are not valid.
#define ADC_SHACQ 0x1 // S/H period (pulse-width) in ADC module periods. Sample switch is open for
//1+ADC_SHACQ number of ADCCLK cycles.
#define BUF_SIZE 2048 // Sample buffer size
// Global variable for this example
Uint16 SampleTable[BUF_SIZE]; // Buffer for storing ADC counts
Uint16 LoopCount = 0;
Uint16 BufCount = 0;
main()
{
Uint16 i;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP280x_SysCtrl.c file.
InitSysCtrl();
// Specific clock setting for this example:sets HSPCLK = 12.5 MHz as SYSCLK is set to 100 MHz.
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;
// Step 2. Clear all interrupts, initialize PIE vector table and set ADC interrupt vector
// Disable CPU interrupts
DINT;
// Initialize the 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 DSP280x_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 DSP280x_DefaultIsr.c.
// This function is found in DSP280x_PieVect.c.
InitPieVectTable();
// Now, change SEQ1INT vector to PieVectTable
EALLOW;
PieVectTable.SEQ1INT = &seq1int_isr;
EDIS;
// Step 3: Initialize all the Device Peripherals:
// Selects Internal/External Vref and switches on ADC
// NOTE: Power-on sequence for F280x is different from F281x
// Select required function call and check DSP28xx_Adc.c file
// to ensure that power-up Delays are correctly set for the selected CPU clock.
Init280xAdc(); //Note: different function for F281x
// Step 4: Now, set specific ADC parameters and clear buffer:
// a. setting ADC Clock and Sample period (set required sampling rate)
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; // Set divider for HSPCLK
AdcRegs.ADCTRL1.bit.CPS = 0; // Final scaler to Set ADCCLK (ADC Clock = HSPCLK/(ADC_CKPS+1*CPS)
// Here, ADCCLKPS and CPS are both =0. So, ADCCLK = 12.5 MHz
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHACQ; // Set sample period i.e. Period for which sample cap is charged
// Here, SH=1+1=2 ADC cycles
// So with these values and if Sequencer is set for just one conversion,
// Sample Rate = ADC Clock/(Delay time from event trigger + SH + Delay time for first result)
// = 12.5/(2.5+2+4) = 1.47 Msps.
// Note: If Sequencer is set for >1 conversion, sample rate will be better.
// b. Select between Sequential and Simultaneous (Ax/Bx) mode
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; //0=Sequential sampling mode
//1=Simultaneous sampling mode
// c. If SEQ1 and SEQ2 to be cascaded?
AdcRegs.ADCTRL1.bit.SEQ_CASC = 0; // 0=Dual mode (SEQ1 and SEQ2 as two 8-state sequencers)
// 1=Cascaded mode (SEQ1 and SEQ2 as a single 16-state sequencer)
// d. Should conversion 'Stop' and wait for next trigger or 'Continue', at the End of Sequence (EOS)?
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // 0=Start-stop mode. Sequencer stops after reaching EOS and requires next SOC to retrigger
// 1=Continuous run. Additional flexibility with SEQ_OVRD
// bit of ADCTRL1 register (to select channel at EOS)
// e. Configure the ADC channels for Seequencer(s)
AdcRegs.ADCMAXCONV.all = 0x0000; // Setup 'maximum number of conversion' per sequence for SEQ1+SEQ2:
// 0x0000 sets 1 conversion/sequence
// Max. 8 channels/sequencer or 16 channels in cascade mode
AdcRegs.ADCCHSELSEQ1.all = 0x0; // Assign the ADC input channel for the Sequencer
// ADCCHSELSEQ1 is for first 4 Conversions -CONV00 to CONV03
// Here, CONV00 (= 0x0) will select ADCINA0 as 1st channel in SEQ1
// This also sets the resultant ADC count to go into ADCRESULT0 register.
// AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x8; // For example, Select ADCINB0 as 2nd conversion in SEQ1
// AdcRegs.ADCCHSELSEQ2.all = 0x0; // For Conversions # 4 to 8 and so on
// Note: If Simutaneous sampling mode is used; each CONVnn bit setting selects two channels (Ax and Bx)
// f. Select the signal to trigger ADC sequencer (SOC)
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 0=INT_SEQ1 request is disabled
// 1=Enable SEQ1 interrupt (every EOS) request
// AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// If PWM is a SOC signal, enable SOCA from ePWM to start SEQ1
// Step 5: Clear data buffer
// Clear buffer area
for (i=0; i<BUF_SIZE; i++)
{
SampleTable[i] = 0;
}
// Step 6: Next, start the action:
// First, enable required interrupt path for SEQ1 interrupt
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable PIE INT1.1
IER = 0x0001; // Enable CPU INT1
EINT;
// Now, ADC peripheral is ready for task and waiting for Start-of-conversion (SOC) signal.
// Note, the SOC starts the 'Sequencer'. With every trigger, it will convert all the selected
// channels of the Sequencer.
// For this example, a Software trigger is selected to start conversions for SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // 0=clears pending SOC
// 1=SW trigger - start SEQ1 from current position
// Wait for SEQ1 interrupt, Take ADC data and log in SampleTable array
for(;;)
{
LoopCount++; // dummy operation - User specific code could be added
}
}
interrupt void seq1int_isr(void)
{
SampleTable[BufCount] =((AdcRegs.ADCRESULT0>>4) ); //Count from ADCINA0 transferred to buffer
BufCount++;
// If more channels are added in SEQ1, following lines can be added:
// SampleTable[BufCount] =((AdcRegs.ADCRESULT1>>4) ); //Count from ADCINTB0 (as an example)
// BufCount++;
// and so on ....
// Restart filling up buffer, if full
if (BufCount > BUF_SIZE)
BufCount = 0;
else;
// Reinitialize for next ADC sequence
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1- brings to CONV00
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit - peripheral flag
//This must be done, so that next interrupt is passed to CPU
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
// AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Retrigger Sequncer1. This needs to be done, if Start/Stop mode is selected.
// It can be done here or in application area, per the project requirement.
return;
}
//===========================================================================
// No more.
//===========================================================================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -