PIC C18:从一个字节读取位
问题描述:
我有一个非常基本的问题。然而,我曾经尝试过的,我无法成功实现这一点。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;
,但无论我看多少,它对我来说都是完全合适的。我的代码有什么问题?
任何帮助将不胜感激。
答
你的代码看起来应该可以工作。我会写它像这是更具可读性和效率的(假设你的系统有一个桶式移位器):
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;
}
如果一个变化我第一个或第二个例子工作,那么它听起来像编译器不处理常量值或在您的原始代码中正确比较。
答
可能只是一个错字,但你的参数是unRegister不是ucRegister。 ucRegister是全球性的,可能是0b11111111?
通过MBLAB模拟器运行代码,并按预期开启和关闭位。我建议你也这样做,以确认你的编译器版本正在生成指令,将按照预期打开输出。如果编译器生成错误的代码,那么我会升级到最新的编译器。如果模拟器工作正常,那么更恶毒的事情正在发生。它可能是计时问题吗?你工作的代码将会比没有工作的代码快得多。不过,我会认为,感谢更快的代码在更慢之前会失败。 – user957902 2012-02-07 23:55:44