AVR GCC - 类型转换问题

发布于 2024-12-12 12:50:41 字数 894 浏览 3 评论 0原文

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

我试图获取“数据”变量中十位值的前 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();
    }

一切都按预期进行。显然,我如何移动和类型转换原始“数据”变量存在某种问题,但我已经尝试了各种排列,但结果相同。如果有人能指出我可能出错的地方,我将不胜感激。

I'm using an AVR microcontroller to write to a programmable frequency divider chip via the I2C bus. At certain intervals I'm trying to have the following function is called to update the frequency output of the chip:

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

I'm trying to get the top 8 bits of a ten bit value in the "data" variable and write it out. The second "write" command writes the lower 8 bits of the "divide" register on the chip, 0 in this case.

As a test case I'm incrementing the "data" variable (which has to be signed for certain reasons) from zero, shifting it left 2 bits and calling this function each time. I get garbage out. However, when I do this:

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

Everything works as expected. There's obviously some kind of problem in how I'm shifting and typecasting the original "data" variable, but I've tried all kinds of permutations with the same results. It would be much appreciated if anyone could point out where I might be going wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半步萧音过轻尘 2024-12-19 12:50:41

尝试

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

您不能依靠转换为较小的 int 来删除您试图删除的高位。

Try

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

You cannot rely on the cast to a smaller int to delete the high-order bits that you are trying to get rid of.

鹿童谣 2024-12-19 12:50:41
i2c_write(thing++);

这意味着您的除法器会在每次调用时递增。如果您增加“数据”并将其右移两位,那么您的除法器每四次调用就会增加一次。您的两个代码部分不等效。

您以什么时间间隔调用此函数?什么是“垃圾出”?你怎么知道传递给函数的值是正确的?你怎么知道发送到 DS1077 的值是错误的?

检查你所有的假设。

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

否则,如果新类型是无符号的,则该值将转换为
反复加或减 1 比最大值
可以用新类型表示,直到该值在以下范围内
新类型

这是我现在唯一可以访问的类型。也许其他人可以插话这个标准问题。编译器可能不符合标准...

i2c_write(thing++);

Would mean your divider increments every call. If you increment "data" and shift it right by two then your divider increments every four calls. Your two code sections are not equivalent.

What interval are you calling this function at? What is "garbage out"? How do you know the value passed into the function is correct? How do you know the value sent out to the DS1077 is wrong?

Check all your assumptions.

The cast and shift look fine to me. At least I think they'd work in any C compiler I've ever used. From a C standard perspective you can refer to this draft (ISO/IEC 9899:TC2 6.3 Conversions):

Otherwise, if the new type is unsigned, the value is converted by
repeatedly adding or subtracting one more than the maximum value that
can be represented in the new type until the value is in the range of
the new type

Which is the only one I have access to right now. Perhaps someone else can chime in on the standard question. The compiler may not be standard compliant...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文