PIC C18: чтение битов из байта - PullRequest
2 голосов
/ 06 февраля 2012

У меня очень элементарный вопрос.Однако, что бы я ни пытался, я не смог успешно это реализовать.

У меня есть сдвиговый регистр ( 74LS164 ), подключенный к PIC18F2550 со следующей аппаратной конфигурацией:

// Data pin
#define SCLCD_DATA          LATBbits.LATB7
#define SCLCD_DATA_TRIS     TRISBbits.TRISB7

// Clock pin
#define SCLCD_CLOCK         LATBbits.LATB6
#define SCLCD_CLOCK_TRIS    TRISBbits.TRISB6

Светодиоды подключены к выходным контактам 74LS164 для просмотра его состояния.У меня есть 8-битная переменная, объявленная как unsigned char.Я хочу отправить биты этой переменной в регистр сдвига.Сдвиговый регистр имеет внутренние триггеры, выходы которых называются Q0-Q7.Первый отправленный бит загружается в Q0, когда вы отправляете второй бит, предыдущий Q0 смещается в Q1, а вновь отправленный бит поступает в Q0, и это продолжается при отправке последующих битов.Когда отправка завершена, младший бит переменной должен быть в Q0 регистра сдвига, а MSB - в Q7.

Мой код такой (язык C18):

void SCLCD_SendSerialBits(unsigned char unRegister)
{
    // ucRegister is always passed as 0b10101010 for test
    for (i=0; i<8; i++)
    {
        SCLCD_CLOCK = 0;
        SCLCD_DATA = ((ucRegister & 0b10000000) == 0b10000000) ? 1 : 0;
        ucRegister = ucRegister << 1;
        SCLCD_CLOCK = 1;
    }
}

Код выше не работает так, как я хочу.Когда я его запускаю, все светодиоды горят, как будто я загрузил 0b11111111 в переменную ucRegister.

Однако, следующий работает очень хорошо:

void SCLCD_SendSerialBits(void)
{
    SCLCD_CLOCK = 0;    SCLCD_DATA = 1;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 0;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 1;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 0;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 1;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 0;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 1;     SCLCD_CLOCK = 1;
    SCLCD_CLOCK = 0;    SCLCD_DATA = 0;     SCLCD_CLOCK = 1;
}

Что не так с моим кодом?Я думаю, что ошибка, скорее всего, находится на линии SCLCD_DATA = ((ucRegister & 0b10000000) == 0b10000000) ? 1 : 0;, но, как бы я ни смотрел на нее, она выглядит для меня совершенно нормально.Что не так с моим кодом?

Любая помощь будет оценена.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2012

Ваш код выглядит так, как будто он должен работать. Я бы написал так, чтобы это было более читабельно и эффективно (при условии, что в вашей системе имеется переключатель барреля):

for (i=7; i>=0; i--)
{
    SCLCD_CLOCK = 0;
    SCLCD_DATA = ((ucRegister >> i) & 1);
    SCLCD_CLOCK = 1;
}

Для систем без бочкообразного механизма, вариант вашего кода

unsigned char ucMask = 0x80;

    for (i=0; i<8; i++)
    {
        SCLCD_CLOCK = 0;
        SCLCD_DATA = (ucRegister & ucMask) ? 1:0;
        ucMask >>= 1;
        SCLCD_CLOCK = 1;
    }

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

0 голосов
/ 07 февраля 2012

Может быть просто опечатка, но ваш параметр unRegister, а не ucRegister.Возможно ли, что ucRegister является глобальным, который является 0b11111111?

...