2012-02-05 2 views
2

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

У меня есть регистр сдвига (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, и это происходит так же, как вы отправляете последующие биты. Когда отправка завершена, LSB переменной должен находиться на Q0 регистра сдвига, а MSB будет на Q7.

Мой код выглядит так (Язык С18):

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;, но независимо от того, насколько я смотрю на нее, мне все отлично. Что не так с моим кодом?

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

+0

Пронумеровать код через симулятор MBLAB, а бит включить и выключить, как ожидалось. Я предлагаю вам сделать то же самое, чтобы подтвердить, что ваша версия компилятора генерирует инструкцию, которая будет включать выходы, как ожидалось. Если компилятор генерирует плохой код, я бы обновился до последнего повторителя. Если симулятор работает нормально, происходит нечто более зловещее. Это могут быть проблемы с синхронизацией? Ваш код, который работает, собирается синхронизировать сдвиговый резистор намного быстрее, чем код, который не работает. Тем не менее, я бы подумал, что более быстрый код провалится раньше, чем медленнее. – user957902

ответ

2

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

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

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