The ADCs used in the projects I have worked on are all on-chip ADCs of DSP. The advantage of using on-chip ADCs is that they have fast conversion speeds and save costs, which are advantages over off-chip ADCs.
The ADC accuracy of DSP_28069 is 12 bits, and the ADC accuracy of DSP_28377D can be selected as 12 bits or 16 bits. The author uses 12 bits here. The sampling modes of both DSPs are single-ended mode.
The ADC sampling accuracy of DSP is closely related to the reference voltage. Generally, an external reference voltage is selected, and an RC filtering circuit must be added to the reference voltage.
The calculation formula is as follows:
The principles of other aspects of ADC will not be introduced here. If readers want to know more, they can search other blogs.
The author uses ADC in the project, basically only involving the following aspects:
ADC Initialization
ADC initialization is mainly divided into two parts: ADC mode selection (precision mode, sampling method (differential or single-ended)), interrupt trigger time, enabling interrupts, etc.
void InitAdcPart1(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
(*Device_cal)();
EDIS;
EALLOW;
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
AdcRegs.ADCCTL1.bit. ADCREFPWD = 1; // Power reference
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC
AdcRegs.ADCCTL1.bit.ADCREFSEL = 1; // External VREFHI or VREFLO pins used for
//reference generation
EDIS;
DELAY_US(1000L); // Delay before converting ADC channels
EALLOW;
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 0; //ADCCLK = SYSCLK = 80Mhz
EDIS;
DELAY_US(1000L); // Delay before converting ADC channels
}
void InitAdcPart2(void)
{
EALLOW;
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1; // Overlap of sample is not allowed
AdcRegs.ADCSAMPLEMODE.all = 0; // Single sample mode
//Physical sampling channel selection
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; //ADCINA0
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1;
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2;
AdcRegs.ADCSOC3CTL. bit.CHSEL = 3;
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4;
AdcRegs.ADCSOC5CTL.bit.CHSEL = 5;
AdcRegs.ADCSOC6CTL.bit.CHSEL = 6;
AdcRegs.ADCSOC7CTL.bit.CHSEL = 7; //ADCINA7
AdcRegs.ADCSOC8CTL.bit.CHSEL = 8; //ADCINB0
AdcRegs.ADCSOC9CTL.bit.CHSEL = 9;
AdcRegs.ADCSOC10CTL. bit.CHSEL= 10;
AdcRegs.ADCSOC11CTL.bit.CHSEL= 11;
AdcRegs.ADCSOC12CTL.bit.CHSEL= 12;
AdcRegs.ADCSOC13CTL.bit.CHSEL= 13;
AdcRegs.ADCSOC14CTL.bit.CHSEL
= 14; bit.CHSEL= 15; //ADCINB7
//Sampling and holding time
//Sample window =(19 + 1 clock cycles).
AdcRegs.ADCSOC0CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC1CTL.bit.ACQPS = 19
;
AdcRegs.ADCSOC2CTL.bit.ACQPS = 19
; .ADCSOC4CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC5CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC6CTL.bit.ACQPS
= 19;
AdcRegs.ADCSOC7CTL.bit.ACQPS = 19
; .ADCSOC9CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC10CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC11CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC12CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC13CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC14CTL.bit.ACQPS = 19;
AdcRegs.ADCSOC15CTL.bit.ACQPS = 19;
//ADC trigger source
//4// set
SOC0
start
trigger on .TRIGSEL = 4; //4;
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC8CTL. bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 4; // 4;
AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 4; //4;
AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 4; //4;
EDIS;
}
void InitAdcINT(void)
{
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2. bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 15; // EOC15 is trigger for ADCINT1
EALLOW;
}
void EnableAdcInterrupt(void)
{
EALLOW;
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
EDIS;
}
The trigger source of ADC, that is, how to start ADC conversion. Generally, PWM is used to start ADC, or external GPIO is used to start ADC, such as FPGA external trigger ADC.
ADC conversion result ADCRESULT
ADCRESULT represents the source of data acquisition. Various voltages and currents are obtained through this formula (ADCRESULT - zero drift) * coefficient.
The interrupt is triggered after the ADC conversion is completed.
The interrupt triggered by the ADC is generally the main interrupt in the entire DSP system. This interrupt will run some functions with high real-time requirements, such as data acquisition, algorithms, fault protection, etc.
void InitInterrupt(void)
{
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT1 = &Interrupt_Adc1;
EDIS; // This is needed to disable write to EALLOW protected registers
PieCtrlRegs.PIEIFR1.bit.INTx1 = 0;
PieCtrlRegs .PIEIER1.bit.INTx1 = 1; // Enable ADC1 INT 1.1 in the PIE
PieCtrlRegs.PIEACK.all = 0x0FFF; //set all ack to 0
}
__interrupt void Interrupt_Adc1(void)
{
ServeMainInt();
AdcRegs.ADCINTFLGCLR.bit .ADCINT1 = 1; //Clear ADCINT1 flag reinitialize
//for next SOC
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1; // Acknowledge interrupt to PIE
}
|