在将带符号的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位,但是后来用除法取反),它向右移了8位,然后隐式转换为uint8_t。
第二个版本具有32位整数,将其显式转换为int16_t,然后将其右移8位,然后隐式转换为uint8_t。这些产生不同结果的方法有什么不同?