将带符号的 long 传递给函数后,我遇到了 uint8 值不正确的问题。您可以在右侧轴的原始数据值中看到发生溢出(?)的峰值
我正在使用 MPLABX 5.0 和 XC8 编译器为 PIC 编写这个。我的代码的简化版本如下:
int16_t ADCOutput[6];
signed long ADCOutputAvg[6];
uint8_t USARTRxLSB = 6;
void MOVING_AVERAGE_ADC(void)
{
READ_ADC();
for ( int i = 0 ; i < 6 ; ++i)
{
ADCOutputAvg[i] = (ADCOutputAvg[i]*4) - ADCOutputAvg[i];
ADCOutputAvg[i] += ADCOutput[i];
ADCOutputAvg[i] = ADCOutputAvg[i] /4;
}
SERIAL_WRITE(0x45,(ADCOutputAvg[(USARTRxLSB-1)]>>8), (ADCOutputAvg[(USARTRxLSB-1)]));
}
SERIAL_WRITE 是函数:
void SERIAL_WRITE(uint8_t Control, uint8_t MSB, uint8_t LSB)
{
uint8_t Checksum = 0;
Checksum = NextHeader ^ Control ^ MSB ^ LSB;
EUSART1_Write(NextHeader);
EUSART1_Write(Control);
EUSART1_Write(MSB);
EUSART1_Write(LSB);
EUSART1_Write(Checksum);
if(NextHeader == 0x5A)
{
NextHeader = 0xA5;
}
else
{
NextHeader = 0x5A;
}
}
我设法通过修改它来修复它,如下所示:
int16_t ADCOutput[6];
signed long ADCOutputAvg[6];
uint8_t USARTRxLSB = 6;
int16_t ADCOutputAvgHolder[6];
void MOVING_AVERAGE_ADC(void)
{
READ_ADC();
for ( int i = 0 ; i < 6 ; ++i)
{
ADCOutputAvg[i] = (ADCOutputAvg[i]*4) - ADCOutputAvg[i];
ADCOutputAvg[i] += ADCOutput[i];
ADCOutputAvg[i] = ADCOutputAvg[i] /4;
ADCOutputAvgHolder[i] = (int16_t) ADCOutputAvg[i];
}
SERIAL_WRITE(0x45,(ADCOutputAvgHolder[(USARTRxLSB-1)]>>8), (ADCOutputAvgHolder[(USARTRxLSB-1)]));
}
现在给出以下输出:
问题是,我不明白它是如何解决的。在第一个实例中,我有一个 32 位有符号整数(最多只有 16 位;由于它的乘法,它必须进入 32 位,但这后来用除法取反),它被右移八位并且然后隐式转换为 uint8_t。
第二个版本有一个 32 位整数,它被显式转换为 int16_t,然后将其右移八位,然后隐式转换为 uint8_t。这些给出不同结果的方法有什么不同?