【发布时间】:2012-10-02 10:51:57
【问题描述】:
我正在尝试将 char 变量转换为 Unsigned int。我的代码是
char spi(char data)
{
//Start transmision
SPDR = data;
//Wait for transmision complete
while(!(SPSR & 0x80));
return SPDR;
}
unsigned int ReadAd(void)
{
unsigned int data;
ChipSelectAd(1);
//Read data
CheckStatus();
spi(0x58);
data = (spi(0xFF)<< 8);
data |= spi(0xFF);
return data;
}
其实我的问题是 spi 函数返回一个 8 位的字符,所以上面的代码将 char 变量左移 8 位,然后将其分配给一个 16 位的变量,结果总是 0。 为了将数据实际向左移动,我需要先将它们类型转换为 16 位类型变量。我试过这样的
char spi(char data)
{
//Start transmision
SPDR = data;
//Wait for transmision complete
while(!(SPSR & 0x80));
return SPDR;
}
unsigned int ReadAd(void)
{
unsigned int data;
ChipSelectAd(1);
//Read data
CheckStatus();
spi(0x58);
data = (unsigned int)((unsigned char)spi(0xFF)<< 8);
data |= (unsigned int)((unsigned char)spi(0xFF));
return data;
}
void CheckStatus(void)
{
//char adcStatus;
adcStatus = 0xFF;
//Read status
while(!(adcStatus & 0x80))
{
spi(0x40);
adcStatus = spi(0xFF);
}
}
void ChipSelectAd(char s)
{
if(s == 1){
PORTB.3 = 0; //Switch on ADC
//while(PINB.3); //Wait for chip select pin
}
else
PORTB.3 = 1; //Switch off ADC
}
它不工作。请建议我必须使用哪个功能。
提前致谢。
【问题讨论】:
-
您真的从
SPDR中得到任何新数据吗?SPDR是如何定义的?是不是类似于*(char*)SOME_ADDRESS?如果是,那里有volatile,像这样吗?:*(volatile char*)SOME_ADDRESS。SPSR也是如此。 -
@AlexeyFrunze 是的,它必须定义为 volatile。这些是标准的 SPI 硬件寄存器。
-
@Lundin “必须定义”如“它们已定义”或“应定义”?
-
@AlexeyFrunze 如果您不将它们声明为易失性,您的编译器可能会完全失控并优化所有代码,或者进行模糊的优化。更糟糕的是,一些 MCU 通过读取 SPSR 寄存器来清除它,然后读取数据寄存器。如果代码不这样做,标志将永远不会被清除,程序将锁定,永远等待状态标志。
-
@Lundin 我知道如果没有
volatile会发生什么,这就是我提出这个主题的原因。我只是问你是否确定它们已经用volatile定义(例如在某些“标准”包含文件中或在编译器中硬编码)或者它们有可能不是以这种方式定义的(例如定义的 OP它们错误地或从某处/其他人那里继承了错误的定义)。