【发布时间】:2019-04-14 03:41:25
【问题描述】:
我正在为 MSP430 微控制器编写嵌入式 C 代码,但我遇到了返回错误值的函数。当我使用调试器单步执行代码时,它显示函数应该返回 1,但它在设置的 int 上返回 0。
代码:
void sendUart(unsigned char string[], int length){
if(string != 0){
while(~responseAOK()){
int BLEstatus = BLEReadyForData(); **//Function called here**
if(BLEstatus){ **//At this point, BLEstatus is 0 (incorrect)
unsigned int i;
for(i=0;i<length-1;i++){
while(!(IFG2 & UCA0TXIFG));
UCA0TXBUF = string[i];
send[sendIndex] = string[i];
sendIndex++;
}
sendIndex = 0;
}
}
}
}
int BLEReadyForData(){
if(P2DIR & BIT3){
P2DIR &= ~BIT3;
}
if(P2IN & BIT3){
return 1; //debugger step-through reaches this line of code
}
else return 0;
}
【问题讨论】:
-
@DonPiano 所以它们是内存映射寄存器。它们反映了硬件的某些状态,因此它们可能会随着时间的推移而自发变化
-
我敢打赌,调试器并不能完美地反映代码的执行。例如,编译器可能已将
return 1;和return 0;优化为单个内部语句,有点像int a = (P2IN & BIT3) != 0; return a;,因此它通过向您显示以下行之一来表明您处于该合并的内部语句中对应的 C 代码。这可能是一项重要的优化,因为它消除了在某些 CPU 上成本很高的流控制语句(条件分支)。 -
你说的都对。我现在只是在查看寄存器列表,而我正在轮询的是 0。直到现在我才知道我可以这样查看寄存器的值。谢谢!
-
寄存器可以通过读取来改变,尤其是状态位。我不知道 this 寄存器,但这是一个不正确的全面陈述。此外,您正在使用 UART 并检查“准备数据”。使用调试器可能会影响时序,因为在断点处字符传输可能还没有完成,但是当检查寄存器时,它已经完成了。
-
在调试器中读取硬件寄存器时的注意事项,因为正如@WeatherVane 所说,它们可以通过读取而改变——包括被调试器读取。结果是您的代码可能完全因为您使用的是调试器而表现不正确!此外,请确保您没有应用 任何 优化。如果代码似乎仍然在做一些不正确的事情,请切换到汇编程序视图并逐步确定正在做出哪些决定以及使用哪些值。