PIC C18:从一个字节读取位

时间:2012-02-05 21:28:36

标签: bit-manipulation bitwise-operators pic pic18 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

LED连接到74LS164的输出引脚以查看其状态。我有一个8位变量声明为unsigned char。我想将此变量的位发送到移位寄存器。移位寄存器具有内部触发器,其输出命名为Q0-Q7。第一个发送的位加载到Q0,当您发送第二个位时,先前的Q0转移到Q1,新发送的位转到Q0,这样就会在发送后续位时继续。发送完成后,变量的LSB应该位于移位寄存器的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;
    }
}

上面的代码没有按我的意愿运行。当我运行它时,所有LED都亮起,好像我已将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 个答案:

答案 0 :(得分: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;
    }

如果我的第一个或第二个例子有效,那么听起来好像编译器没有处理常量值或在原始代码中正确比较。

答案 1 :(得分:0)

可能只是一个错字,但你的参数是unRegister而不是ucRegister。是否有可能ucRegister是全局的0b11111111?