在 for 循环中初始化的变量包含一个值,不会递增

Variable initialized in a for-loop contains a value, won't increment

我正在为 STM32 微控制器开发一个函数,它通过 uart 端口发送给定长度的字符串。为了处理 uart 通信,我创建了一个 Serial class,它有一个传输和接收缓冲区,在中断处理程序中弹出和传输。我目前正在处理的函数实际上是我之前编写的有效函数的重载。下面是工作函数:

void Serial::sendString(char* str) {
// Writes a string to txBuffer. If Transmit interrupts are enabled, and
// the Data register is empty, the txBuffer will be popped into the DR to
// prime the interrupts.

__HAL_UART_DISABLE_IT(uart, UART_IT_TXE); // Keeps our spaghetti straightened out...

while (*str != '[=10=]') { // While char is not a null terminator...
    txBuffer->push(*str); // Push first char into queue as we know it is valid
    str++; // Pointer goes to next char in string
}

 uint32_t isrflags   = READ_REG(uart->Instance->SR); // Reads the flags and control register
 //uint32_t cr1its     = READ_REG(uart->Instance->CR1); // Into variables

 // If the DR is empty and Transmission interrupts are disabled...
 if ((isrflags & USART_SR_TXE) != RESET) {
    uart->Instance->DR = txBuffer->pop(); // Reenable interrupts and prime the DR
    }

 __HAL_UART_ENABLE_IT(uart, UART_IT_TXE); // Alright, time to cook the pasta

}

过载是我遇到问题的函数。出于某种原因,调试器显示变量“i”初始化为值“14”,并且在调试器单步执行时不会递增。事实上,调试器根本不允许我进入 for 循环。这是重载:

void Serial::sendString(char* str, unsigned int len) {
// Writes a string to txBuffer. If Transmit interrupts are enabled, and
// the Data register is empty, the txBuffer will be popped into the DR to
// prime the interrupts.
// Rather than being terminated by a null character, this method instead
// sends each char in an array of a specified length. Note that this overload
// MUST be used in any situation that a null terminator might appear in a char
// array!

__HAL_UART_DISABLE_IT(uart, UART_IT_TXE); // Keeps our spaghetti straightened out...

for (unsigned int i = 0; i < len; i++) { // While char is not a null terminator...
    txBuffer->push(str[i]); // Push first char into queue as we know it is valid
    //str++; // Pointer goes to next char in string
}

 uint32_t isrflags   = READ_REG(uart->Instance->SR); // Reads the flags and control register
// uint32_t cr1its     = READ_REG(uart->Instance->CR1); // Into variables

 // If the DR is empty...
 if ((isrflags & USART_SR_TXE) != RESET) {
    uart->Instance->DR = txBuffer->pop();
    }
 __HAL_UART_ENABLE_IT(uart, UART_IT_TXE); // Alright, time to cook the pasta

}

这些函数在 main 中的终端 while 循环中调用。调试时,问题立即发生;我根本无法 运行 通过超载。我的代码似乎只是在这个位置遇到了死胡同。

我之前已经能够 运行 成功重载。这个错误只出现在我试图解决函数中的另一个错误时,字符串中的第一个字符只有一半的时间被传输。我设置了一个断点并开始调试,现在它根本不起作用....

听起来好像编译器优化掉了你的循环控制变量。

如果您启用了高级优化,则可以展开循环,或者如果您从定义它的同一文件调用该函数,则可以内联它以允许消除循环控制变量。

您实际上没有描述您尝试调试的问题是什么。与其期待完美的调试体验,不如尝试解决你遇到的问题,尽管我一直都是 14 岁!

仅查看您发布的代码,我看不出有什么大问题。您未显示的代码中当然可能存在错误。

我强烈反对认为这段代码根本就是垃圾的无益评论。打开和关闭中断以访问共享数据是老式且低效的,但也很简单,可能足以满足您的目的。

在此函数中将第一个字节写入 UART 确实可以节省一次中断的成本,但是如果您正在写入一个 20 字节的字符串,您真的关心需要 20 次还是 19 次中断吗?一个好的设计原则是,只有当代码能让你获得一些你不想没有的东西时,你才应该让代码更复杂。