2012-02-05 67 views
2

我有一个非常基本的问题。然而,我曾经尝试过的,我无法成功实现这一点。PIC C18:从一个字节读取位

我具有连接到PIC18F2550具有以下硬件配置的移位寄存器(74LS164):

// 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; 
    } 
} 

上面的代码不运行,我想。当我运行它时,所有指示灯亮起,就好像我已将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 2012-02-07 23:55:44

回答

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?