工具与软件:
您好!
我希望 在我的代码中运行任何初始化之前、有一个定制的系统定时器滴答声、这样我就可以使循环超时以避免出于安全目的停止处理器。 由于 ADC 例程在初始化期间等待一些标志稳定、因此我希望在初始化 ADC 本身之前让该计时器运行。
我已将 CPU 定时器1配置为每1us 作为节拍定时器运行一次。 与 CPU 定时器1相关的中断函数每1us 中断一次。 接下来、我会在启用 CPU 计时器中断后尝试初始化 ADC、但 AdcRegs.ADCINTFLG.bit.ADCINT1 中断位 没有设置为1、这意味着我的 ADC 初始化例程会 卡住。 (即 while (AdcRegs.ADCINTFLG.bit.ADCINT1 =0);)
我的观察结果:
ADC 卡住的代码确切部分是在偏移校准期间。 这肯定是由 CPU 计时器中断导致的、因为当我禁用 计时器时、 "AdcRegs.ADCINTFLG.bit.ADCINT1"标志设置为 1.
不过、当我向该循环添加退出条件时、似乎 ADC 顺利进行初始化。 完成 ADC 设置后、我启动 ADC 转换、同时我的计时器在后台中断、并且我能够在不陷入此循环的情况下提取电压值、"while (AdcRegs.ADCINTFLG.bit.ADCINT1 = 0);"
近况如何? 在偏移校准期间、但在转换 ADC 时、如何陷入同一环路? 计时器仍在后台运行
此外,我注意到,当计时器关闭,我 在 ADC_CALIBRATION()函数内遇到一个断点时,会发生同样的情况。 这让我认为 CPU 定时器中断函数在校准期间增加了大量的延迟、这会破坏初始化。 是否有解决方法?
我的主函数:
int main(void)
{
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint16)&RamfuncsLoadSize);
InitFlash();
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.TINT1 = &cpu_timer1_isr;
EDIS;
timer_service_init();
IER |= M_INT13; // Enable CPU Interrupt 11
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
adc_init();
for(;;)
{
}
}
ADC 卡在偏移校准例程中:
static Uint16 adc_conversion(void)
{
Uint16 index, SampleSize, Mean, ACQPS_Value;
Uint32 Sum;
index = 0; // initialize index to 0
SampleSize = 256; // (**NOTE: Sample size must be multiples of 2^x where is an integer >= 4)
Sum = 0; // set sum to 0
Mean = 999; // initialize mean to known value
//
// Set the ADC sample window to the desired value
// (Sample window = ACQPS + 1)
ACQPS_Value = 6;
AdcRegs.ADCSOC0CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC1CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC2CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC3CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC4CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC5CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC6CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC7CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC8CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC9CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC10CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC11CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC12CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC13CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC14CTL.bit.ACQPS = ACQPS_Value;
AdcRegs.ADCSOC15CTL.bit.ACQPS = ACQPS_Value;
//
// Enable ping-pong sampling
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT2E = 1; // Enable ADCINT2
/** Disable Continuous Sampling for ADCINT1 & ADCINT2 */
AdcRegs.INTSEL1N2.bit.INT1CONT = 0;
AdcRegs.INTSEL1N2.bit.INT2CONT = 0;
/** ADCINTs trigger at end of conversion */
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;
/** Setup ADCINT1 and ADCINT2 trigger source */
AdcRegs.INTSEL1N2.bit.INT1SEL = 6; // EOC6 triggers ADCINT1
AdcRegs.INTSEL1N2.bit.INT2SEL = 14; // EOC14 triggers ADCINT2
/** Setup each SOC's ADCINT trigger source */
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 2; // ADCINT2 starts SOC0-7
AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 2;
AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 2;
AdcRegs.ADCINTSOCSEL2.bit.SOC8 = 1; // ADCINT1 starts SOC8-15
AdcRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC14 = 1;
AdcRegs.ADCINTSOCSEL2.bit.SOC15 = 1;
for(int i=0; i<5000;i++); //delay
/** Force Start SOC0-7 to begin ping-pong sampling */
AdcRegs.ADCSOCFRC1.all = 0x00FF;
for(index = 0; index < SampleSize; index+=16)
{
while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0)
{
}
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Must clear ADCINT1 flag since INT1CONT = 0
Sum += AdcResult.ADCRESULT0;
Sum += AdcResult.ADCRESULT1;
Sum += AdcResult.ADCRESULT2;
Sum += AdcResult.ADCRESULT3;
Sum += AdcResult.ADCRESULT4;
Sum += AdcResult.ADCRESULT5;
Sum += AdcResult.ADCRESULT6;
//
// Wait for SOC9 conversion to start, which gives for SOC7
// conversion result
//
while( AdcRegs.ADCSOCFLG1.bit.SOC9 == 1)
{
}
Sum += AdcResult.ADCRESULT7;
//
// Wait for ADCINT2 to trigger, then add ADCRESULT8-15 registers to sum
//
while (AdcRegs.ADCINTFLG.bit.ADCINT2 == 0)
{
}
/// Must clear ADCINT2 flag since INT2CONT = 0
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
Sum += AdcResult.ADCRESULT8;
Sum += AdcResult.ADCRESULT9;
Sum += AdcResult.ADCRESULT10;
Sum += AdcResult.ADCRESULT11;
Sum += AdcResult.ADCRESULT12;
Sum += AdcResult.ADCRESULT13;
Sum += AdcResult.ADCRESULT14;
//
// Wait for SOC1 conversion to start, which gives time for
// SOC15 conversion result
//
while( AdcRegs.ADCSOCFLG1.bit.SOC1 == 1)
{
}
Sum += AdcResult.ADCRESULT15;
}
//
// Disable ADCINT1 and ADCINT2 to STOP the ping-pong sampling
//
AdcRegs.INTSEL1N2.bit.INT1E = 0;
AdcRegs.INTSEL1N2.bit.INT2E = 0;
//
// Wait for any pending SOCs to complete
//
while(AdcRegs.ADCSOCFLG1.all != 0)
{
}
// Clear any pending interrupts
//
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1;
AdcRegs.ADCINTOVFCLR.bit.ADCINT1 = 1;
AdcRegs.ADCINTOVFCLR.bit.ADCINT2 = 1;
//
// reset RR pointer to 32, so that next SOC is SOC0
//
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 1;
while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 1)
{
}
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0;
while( AdcRegs.SOCPRICTL.bit.SOCPRIORITY != 0)
{
}
if ( 0 != SampleSize)
{
Mean = Sum / SampleSize; // Calculate average ADC sample value
}
else
{
Mean = 0;
}
return Mean; // return the average
}
ADC 转换函数:
float get_28_voltage(void)
{
float voltage;
Uint16 adc_div = 4096;
AdcRegs.ADCSOCFRC1.all = 0x01;
while(AdcRegs.ADCINTFLG.bit.ADCINT1 == 0)
{
}
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1
if( 0 != adc_div)
{
voltage = 3.3 * (AdcResult.ADCRESULT0)/adc_div;
}
else
{
voltage = 0;
}
return voltage
}