将带位移位的有符号long隐式转换为无符号8位值的问题

时间:2019-01-15 19:48:42

标签: c casting pic xc8

在将带符号的long传递给函数后,我遇到了uint8值不正确的问题。您可以在右轴的原始数据值中看到发生溢出(?)的峰值

enter image description here

我正在使用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)]));
}

现在提供以下输出:

enter image description here

问题是,我不知道它是如何解决的。在第一个实例中,我有一个32位带符号整数(最多只能有16位;由于乘法,它必须变成32位,但是后来用除法取反),它向右移了8位,然后隐式转换为uint8_t。

第二个版本具有32位整数,将其显式转换为int16_t,然后将其右移8位,然后隐式转换为uint8_t。这些产生不同结果的方法有什么不同?

0 个答案:

没有答案