2011-10-29 29 views
2

我正在使用AVR微控制器通过I2C总线写入可编程分频器芯片。在一定的时间间隔,我想有以下函数被调用来更新芯片的输出频率:AVR GCC - 类型转换问题

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(); 
} 

我试图得到一个10位的值的顶部8位中的“数据”变量并写出来。第二个“写入”命令写入芯片上“分”寄存器的低8位,在这种情况下为0。

作为一个测试用例,我从零开始递增“数据”变量(必须对其进行签名),将其左移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(); 
    } 

一切都按预期工作。在我如何移动和类型化原始“数据”变量方面显然存在一些问题,但我尝试了各种排列方式,结果相同。如果有人能指出我可能会出错的地方,我将非常感激。

+1

你能告诉我们正在做增量和左移的代码吗?也许这个代码很糟糕。 –

+0

请给我们打电话的代码... –

+0

gcc不是*真的*让您使用'1077WriteDiv'作为标识符,是吗?你能告诉我们你的真实代码吗? –

回答

1

尝试

uint8_t upperByte = (uint8_t) ((data & 0x3FC) >> 2); 

你不能靠强制转换为更小的int删除您正试图摆脱高序位。

1
i2c_write(thing++); 

这意味着你的分频器会增加每个呼叫。如果增加“数据”并将其右移两位,则您的分频器每增加一个四个调用。你的两个代码段不相同。

你在什么时间间隔调用这个函数?什么是“垃圾出”?你怎么知道传入函数的值是正确的?您如何知道发送给DS1077的值是错误的?

检查您的所有假设。

演员和轮班对我来说很好。至少我认为他们可以在我以前使用的任何C编译器中工作。从C标准立体可以参考此草案(ISO/IEC 9899:TC2 6.3换算):

否则,如果新类型是无符号的,所述值是通过 转换反复加上或减去小于最大值即 一个更可以用新类型表示,直到值在 的范围内

这是我现在唯一可以访问的一个。也许别人可以在标准问题上加入。编译器可能不符合标准...

+0

不幸的是,这似乎更有可能是一个模糊的硬件问题。我花了几个小时仔细查看反汇编程序,并在模拟器上逐步完成代码,并且在模拟中一切正常。我真的无法找到_software_无法正常工作的原因。 – Bitrex

+0

@Bitrex通过您的详细调查结果修正了问题,也许有人可以帮助您...不幸的是,大多数问题都是模糊的,直到“duh”momemnt :-) –