2014-04-09 38 views
2

我在使用C代码时遇到了一些麻烦。我有一个ADC,用于确定是否关闭(跳闸区)我正在使用的PWM。但是我的计算似乎不能按预期工作,因为ADC会在错误的电压电平下关闭PWM。我开始我的变量:用C语言计算C2000设备

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 
} 

所以我想跳闸PWM如果当前高于9或低于1,这应该分别与< 273(0x111)和> 3428(0xD64)的adc结果重合。 ADC值分别对应于电压0.2V和2.51V。 ADC在电压0和3V之间以12位精度进行测量。

但是,情况并非如此。相反,脱扣区的电压约为1V和2.97V。那么我做错了什么?

+1

为什么不直接使用'adc_info-> adc_result0'? 'if((273.0 <= adc_info-> adc_result0)&&(adc_info-> adc_result0 <= 3428.0))shutdown = 0; else shutdown = 1;' – pmg

+0

'如果电流高于9或低于1,哪里是单位? “安培”或“毫安”还是什么? – SGG

+0

pmg - 只要我想改变它们,就可以更容易地设置限制。如果不先把它们转换成放大器,样品不会告诉我任何东西。 SGG - 单位是安培。 1/1365是V/sample,-3.462是A/V – user3514815

回答

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中的integer division rules时,考虑一下你的代码风格:总是写一个带有小数的常数系数和除数(以确保它们获得浮点类型),例如10.0而不是10 - ,除非您明确指带截断的整数除法。有时,指定具有适当后缀的float literal precision也是一个好主意。

+0

adc_result0被定义为结构中的Uint32。 – user3514815

+0

所以我说得对。你做整数除法,它截断结果的小数部分。通过使'1365'浮动常量而不是整数来强制它浮动。 – ulidtko

+0

它现在可以直接使用边界。但它仍然不能解释我在计算中做了什么错误。我在matlab中完成了完全相同的计算,并得到了我期望的结果。 – user3514815