AVR GCC - проблема с типизацией - PullRequest
2 голосов
/ 29 октября 2011

Я использую микроконтроллер 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 битов десятибитового значения в "переменная "data" и запишите ее.Вторая команда «write» записывает младшие 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();
    }

Все работает как положено.Очевидно, есть какая-то проблема в том, как я перемещаю и типизирую исходную переменную «data», но я пробовал все виды перестановок с одинаковыми результатами.Было бы очень признательно, если бы кто-нибудь мог указать, где я могу пойти не так.

Ответы [ 2 ]

1 голос
/ 29 октября 2011
i2c_write(thing++);

будет означать, что ваш делитель увеличивает каждый вызов.Если вы увеличиваете «данные» и сдвигаете их вправо на два, то ваш делитель увеличивает каждые четыре вызова.Ваши две секции кода не эквивалентны.

В каком интервале вы вызываете эту функцию?Что такое "мусор"?Откуда вы знаете, что значение, переданное в функцию, является правильным?Откуда вы знаете, что значение, отправленное на DS1077, неверно?

Проверьте все свои предположения.

Состав и сдвиг выглядят хорошо для меня.По крайней мере, я думаю, что они будут работать в любом компиляторе C, который я когда-либо использовал.С точки зрения стандарта C вы можете обратиться к этому черновику ( ISO / IEC 9899: преобразования TC2 6.3):

В противном случае, если новый тип является беззнаковым, значение преобразуетсяпутем многократного сложения или вычитания более одного максимального значения, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне нового типа

Который является единственным, к которому у меня есть доступ прямо сейчас,Возможно, кто-то еще может ответить на стандартный вопрос.Компилятор может не соответствовать стандарту ...

1 голос
/ 29 октября 2011

Попробуйте

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

Вы не можете полагаться на приведение к меньшему целому, чтобы удалить старшие биты, от которых вы пытаетесь избавиться.

...