2

将带符号的 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。这些给出不同结果的方法有什么不同?

4

0 回答 0