AVR GCC-类型转换故障

AVR GCC-类型转换故障,c,casting,bit-manipulation,avr,C,Casting,Bit Manipulation,Avr,我使用AVR微控制器通过I2C总线写入可编程分频器芯片。在某些时间间隔,我试图调用以下函数来更新芯片的频率输出: void 1077WriteDiv(int16_t data) { uint8_t upperByte = (uint8_t)((uint16_t)data>>2); i2c_start(DS1077_BASE_ADDRESS); i2c_write(DIVIDE_REGISTER); i2c_write(upperByte);

我使用AVR微控制器通过I2C总线写入可编程分频器芯片。在某些时间间隔,我试图调用以下函数来更新芯片的频率输出:

void 1077WriteDiv(int16_t data)
{
    uint8_t upperByte = (uint8_t)((uint16_t)data>>2);

    i2c_start(DS1077_BASE_ADDRESS);
    i2c_write(DIVIDE_REGISTER);
    i2c_write(upperByte);
    i2c_write(0x0);
    i2c_stop();
}
我试图得到“data”变量中10位值的前8位,然后把它写出来。第二个“写入”命令将“除法”寄存器的低8位写入芯片,在这种情况下为0

作为一个测试用例,我将“data”变量(由于某些原因必须对其进行签名)从零递增,将其左移2位,每次调用此函数。我把垃圾拿出来。但是,当我这样做时:

 void 1077WriteDiv(int16_t data)
    {
        //uint8_t upperByte = (uint8_t)((uint16_t)data>>2);
            static uint8_t thing = 0;     

        i2c_start(DS1077_BASE_ADDRESS);
        i2c_write(DIVIDE_REGISTER);
        i2c_write(thing++);
        i2c_write(0x0);
        i2c_stop();
    }
一切正常。很明显,我在转换和类型转换原始“数据”变量时遇到了一些问题,但我尝试了各种排列,得到了相同的结果。如果有人能指出我可能出错的地方,我将不胜感激。

试试看

uint8_t upperByte = (uint8_t) ((data & 0x3FC) >> 2);
您不能依靠对较小int的强制转换来删除要删除的高阶位

i2c_write(thing++);
这意味着你的分频器会增加每次通话。如果您增加“数据”并将其右移2,则您的除法器会每调用四次就增加一次。您的两个代码部分并不相同

您调用此函数的时间间隔是多少?什么是“垃圾桶”?如何知道传递到函数中的值是正确的?您如何知道发送到DS1077的值是错误的

检查所有假设。

我觉得演员和班次都不错。至少我认为它们可以在我使用过的任何C编译器中工作。从C标准的角度来看,您可以参考此草案(6.3转换):

否则,如果新类型是无符号的,则该值将由 重复地加上或减去一个大于最大值 可以在新类型中表示,直到值在 新型


这是我现在唯一能接触到的。也许其他人可以插话回答这个标准问题。编译器可能不符合标准…

您能告诉我们执行递增和左移位的代码吗?可能代码不好。请告诉我们调用代码…gcc不允许您使用
1077WriteDiv
作为标识符,是吗?你能给我们看一下你的真实代码吗?你确定你指的是
>2
而不是
CHAR\u BIT
8
?@ephemient他说10位值的前8位…不幸的是,这似乎更可能是一些模糊的硬件问题。我花了几个小时仔细地研究了反汇编程序,并在模拟器上逐步完成了代码,在模拟中,一切都很完美。我真的很难找到软件不能正常工作的原因。@Bitrex用您的详细发现修改问题,也许有人可以帮助您。。。不幸的是,大多数问题在“duh”时刻之前都是模糊的:-)