引自免费微信小程序:皆我百晓生
经过分析您的问题,似乎有以下可能的原因和解决方案:
-
引入串口擦除操作导致程序烧录错误:
- 引入
u3_printf
函数用于打印字符并插入一个空行,此行为可能会造成串口设置为只读模式,从而禁止后续的数据输入。 - 若尝试读取烧录文件的前一行(作为发送缓冲),可能存在未清除擦除操作导致当前字符被保留的问题。解决方法是在使用
USART_ClearError()
函数对串口设置为只读模式后,再调用USART_TransmitData()
函数将之前写入的字符通过串口发送。 - 如果使用的是
USART3_MODE,则手动清理或设置串口为只读模式可能会引发串口访问异常。此时应先判断串口的工作模式,如果是异步方式,则可以选择
USART3_FEATURE_oneShotTransmission = 0,并检查是否清除已发送的数据(通过
USART_ClearError()`)后再进行后续操作。 - 对于特定烧录库,如串口3库,可能还提供了特殊的内部擦除机制。建议查阅烧录库的官方文档,了解相关编程接口和函数细节,理解其对烧录工作的影响,以及在需要的情况下进行适当的处理。
- 引入
-
缺少单独的串口连接信息设置:
- 在使用ST-link烧录过程中,编译器未包含相应头文件或初始化函数,可能导致在某个步骤时初始化的串口仅在烧录完成后被擦除而无法继续使用。
- 如果在程序启动时未能正确配置或初始化串口,应确保在
esp_Init()
函数中提供与目标串口相关的有效设置,例如启动模式、波特率、同步模式等。 - 对于使用STM32F103C8T6芯片,部分器件内部设置在烧录前已进行擦除,因此在早期版本的硬件条件下,直接设置串口可能难以实现。
- 对于最新版本的STM32系列,可以使用指定板件上的内部存储空间来挂载和初始化串口,通过函数
STM32Cube_ID::uc_i2s_init()
或STM32Cube_ID::uc_i2s_register_device()
进行相关操作。对于更复杂的STM32架构,可能需要依赖外部库(如stm32 CubeMX
)提供的初始化方法和功能,以便更好地配置串口和处理烧录过程中的各种细节。
综上所述,要解决上述问题,首先需从串口擦除操作开始排查,尝试解除相关错误信息并恢复串口读写状态。接着,在程序编写阶段充分考虑烧录文件格式和控制台通信流程,正确配置并初始化串口连接信息。若必要,还需查阅烧录库的官方文档,深入了解内部擦除机制,并结合STM32系列芯片特性及最新的开发环境优化相关处理。以下是一个示例串口擦拭清除向量以及STlink相关设置的参考代码:
#include
#include
#define PORT USART3
#define PIN USART3_PINS[0]
#define BUF_SIZE 1024
#define BURSE_ALL 0
// 引入串口擦除功能
void clean_USART3(void)
{
// 设置串口为只读模式
switch (PORT)
{
case USART3:
GPIO_SetBits(PIN, GPIO_BIT_OPS.RCC_PERIPH/bit2);
break;
default:
break;
}
// 擦除串口的所有寄存器和数据流
GPIO_WriteBits(PIN, GPIO_BIT_OPS.RCC_PERIPH | GPIO_BIT_OUTPUT, 0x0f);
// 启动断电定时器,释放串口资源
RCC_APB1PeriphClockCmd(RCC_APB1Periph_GPIOA|GPIOAPB1Periph_GPIOB, ENABLE);
// 避免未来串口重置或关闭
BURSE_ALL &= ~(BURSE_CLEAR_INT);
// 清理串口号寄存器和链路状态标志
GPIO_clear_pin_bit_array(PIN, GPIO_PIN_SET);
// 将系统复位到初始值
__HAL_RCC_PEENDBRK();
}
接下来,使用以下指令在串口0上执行擦拭清除操作:
clean_USART3();
// 初始化STlink
Uart_InitTypeDef init_config = {0};
init_config.BaudRate = 115200;
init_config.Fifos = UART_FIFOS_3;
init_config.Mode = UART_Mode_Tx | UART_Mode_Rx;
init_config.Stopbits = UART_StopBitsOne;
init_config.Parity = UART_Parity_N ; // N = No parity
init_config.DataSize = sizeof(UartConfig_t)/sizeof(UartConfig_t[0]);
init_config.WordLength = UART_WordLength_8bit;
/* 设置串口引脚选择 */
UART_SerialPrefered_Baudrate = port_id;
UART_Config_Init(&init_config);
/* 将设备注册到STLink */
if (!STLink_IsDefault(stl_index)) {
/* 如果是QJTAG设备,增加数据表(也称为触发器列表) */
STLink_RegisterDevice(&init_config);
} else {
/* 初始设置 */
if (!STLink_Empty(Bluetooth_addr))
{
STLink_DisableBluetooth();
/* 创建触发器表 */
for (int i = 0; i < sizeof(Bluetooth_addr)-1; ++i)
{
stl_add_uart_callback(port_id, Bluetooth_addr[i], Bluetoothaddr[i+1]);
}
STLink_EnableBluetooth();
}
}
// 连接STLink
STLink_AttachDevice(port_id, Bluetooth_addr);
// 开启所有功耗模式
STLink_Cmd(port_id, ENABLE,HAL*>* HAL);
// 确保设备已成功连接到STLink
if (!STLink_Test(port_id, TRUE))
{
printf("Failed to connect STLink.\n");
exit(-1);
}
以上代码在初始化STlink、连接STLink以及擦除串口初始化向量后,通过执行STLink_Cmd(port_id, ENABLE,HAL*>* HAL)
命令启用STLink功能,并在终端提示符中检查是否成功连接到STLink。如果有任何未定义的操作,例如调试器中断或其他原因导致中断,代码会捕获异常并退出。
请根据实际工程需求和相关宿主机平台的硬件驱动接口调整上述代码,确保满足您的目标板上的具体设置要求,并遵循底层硬件接口规范和STLink API文档进行详细的设置和管理。在进行串口擦除操作后,重新启动STLink、更新STLink库,然后通过STLink配置工具检查串口功能是否正常运行。
请确保在实际应用中考虑以下几点:
- 针对不同应用场景(如物联网、嵌入式系统、工业自动化等),可能需要针对不同类型的设备(如UART、I2C、SPI等)采用不同的擦拭清除向量和STlink配置方法。
- 串口擦除后,应确认所有先前的数据已被清除,包括可读数据、清洗过的中断标志位、连接到STLink的数据表结构等,以避免后续串口初始化问题的发生。
- 在恢复串口读写功能的过程中,注意防止不必要的内存操作和栈溢出风险,通过适当的数据结构和边界检查来减少这些潜在问题的发生。
- 考虑到未正确配置串口连接属性和模式,可能出现串口未识别或丢失连接的情况。在实际操作中,应确保各种情况下都能正确地开启、终止、切换和锁定串口,以保证稳定且高效的串口通信性能。