2

我的 C 代码有问题。我有一个 ADC,它将用于确定是否关闭(跳闸区)我正在使用的 PWM。但我的计算似乎没有按预期工作,因为 ADC 在错误的电压电平下关闭了 PWM。我将变量初始化为:

float32 current = 5;
Uint16 shutdown = 0;

然后我计算为:

// Save the ADC input to variable
adc_info->adc_result0 = AdcRegs.ADCRESULT0>>4;              //bit shift 4 steps because adcresult0 is effectively a 12-bit register not 16-bit, ADCRESULT0 defined as Uint16

current = -3.462*((adc_info->adc_result0/1365) - 2.8);

// Evaluate if too high or too low
if(current > 9 || current < 1)
{
    shutdown = 1;
}
else
{
    shutdown = 0;
}

之后我使用这个 if 语句:

if(shutdown == 1)
{
    EALLOW;                                                 // EALLOW protected register
    EPwm1Regs.TZFRC.bit.OST = 1;                // Force a one-shot trip-zone interrupt
    EDIS;                                                   // end write to EALLOW protected register
}

因此,如果电流高于 9 或低于 1,我想触发 PWM,这应该分别与 <273 (0x111) 和 >3428 (0xD64) 的 adc 结果一致。ADC 值分别对应于电压 0.2V 和 2.51V。ADC 在电压 0 和 3V 之间以 12 位精度进行测量。

然而,这种情况并非如此。相反,跳闸区在大约 1V 和 2.97V 时关闭。那么我做错了什么?

4

1 回答 1

4
adc_info->adc_result0/1365

假设浮点数时您是否在这里进行了整数除法?

试试这个修复:

adc_info->adc_result0/1365.0

另外,@pmg 的建议很好。当您可以立即将 ADC 值与已知界限进行比较时,为什么还要花费周期来计算电压?

if (adc_info->adc_result0 < 273 || adc_info->adc_result0 > 3428)
{
    shutdown = 1;
}
else
{
    shutdown = 0;
}

如果您不想硬编码计算的界限(这是完全可以理解的),那么将它们定义为从您想要硬编码的值计算得出:

#define VOLTAGE_MIN 0.2
#define VOLTAGE_MAX 2.51
#define AREF 3.0
#define ADC_PER_VOLT (4096 / AREF)

#define ADC_MIN (VOLTAGE_MIN * ADC_PER_VOLT) /* 273 */
#define ADC_MAX (VOLTAGE_MAX * ADC_PER_VOLT) /* 3427 */

/* ... */
    shutdown = (adcresult < ADC_MIN || adcresult > ADC_MAX) ? 1 : 0;
/* ... */

当您确定掌握了C 中的整数除法规则后,请考虑对您的代码风格进行一些补充:始终使用小数编写常数系数和除数(以确保它们获得浮点类型),例如,10.0而不是10-除非您特别表示带有截断的整数除法。有时,使用适当的后缀指定浮点字面量精度也是一个好主意。

于 2014-04-09T11:14:38.033 回答