尘世- 2024-03-30 23:12 采纳率: 80%
浏览 8
已结题

必须使用串口擦除Flash后才能继续连接,另外使用串口3进行通讯时,整合后串口负责的ES8266-01S连接阿里云平台的相关代码也处于崩溃状态,请问这两者之间有没有直接联系,如何解决?

STM32F103C8T6芯片在做基于串口1、2、3 的多设备通讯时发现集成后的项目程序一旦用ST-link烧录,烧录一次程序就被写保护了,这导致后面ST-LINK崩溃,再次使用连接错误。必须使用串口擦除Flash后才能继续连接,另外使用串口3进行通讯时,功能正常,整合后串口负责的ES8266-01S连接阿里云平台的相关代码也处于崩溃状态,请问这两者之间有没有直接联系。
串口3程序

__align(8) u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];                     //接收缓冲,最大USART2_MAX_RECV_LEN个字节.
void u3_printf(char* fmt, ...)  ;

void u3_printf(char* fmt, ...)  
{  
    u16 i, j;
    va_list ap;
    va_start(ap, fmt);
    vsprintf((char*)USART3_TX_BUF, fmt, ap);
    va_end(ap);
    i = strlen((const char*)USART3_TX_BUF);//此次发送数据的长度
    for (j = 0; j < i; j++)//循环发送数据
    {
        while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);  //等待上次传输完成 
        USART_SendData(USART3, (uint8_t)USART3_TX_BUF[j]);            //发送数据到串口3 
    }
}

char esp_Init(void)
{
    memset(RECS,0,sizeof(RECS));
    u3_printf("AT+RST\r\n");  //重启
    Delay_ms(2000);
    
    memset(RECS,0,sizeof(RECS));
    u3_printf("ATE0\r\n");    //关闭回显
    Delay_ms(10);
    if(strcmp(RECS,"OK"))
        return 1;
    
    u3_printf("AT+CWMODE=1\r\n"); //Station模式
    Delay_ms(1000);
    if(strcmp(RECS,"OK"))
        return 2;
    在这个部分崩溃
    memset(RECS,0,sizeof(RECS));
    u3_printf("AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI,WIFIASSWORD); //连接热点
    if(strcmp(RECS,"OK"))
        return 3;

img

img


运行到串口3负责的通讯ST-LINK直接断开无法调试。

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-30 23:12
    关注

    引自免费微信小程序:皆我百晓生

    经过分析您的问题,似乎有以下可能的原因和解决方案:

    1. 引入串口擦除操作导致程序烧录错误:

      • 引入u3_printf函数用于打印字符并插入一个空行,此行为可能会造成串口设置为只读模式,从而禁止后续的数据输入。
      • 若尝试读取烧录文件的前一行(作为发送缓冲),可能存在未清除擦除操作导致当前字符被保留的问题。解决方法是在使用USART_ClearError()函数对串口设置为只读模式后,再调用USART_TransmitData()函数将之前写入的字符通过串口发送。
      • 如果使用的是USART3_MODE,则手动清理或设置串口为只读模式可能会引发串口访问异常。此时应先判断串口的工作模式,如果是异步方式,则可以选择USART3_FEATURE_oneShotTransmission = 0,并检查是否清除已发送的数据(通过USART_ClearError()`)后再进行后续操作。
      • 对于特定烧录库,如串口3库,可能还提供了特殊的内部擦除机制。建议查阅烧录库的官方文档,了解相关编程接口和函数细节,理解其对烧录工作的影响,以及在需要的情况下进行适当的处理。
    2. 缺少单独的串口连接信息设置:

      • 在使用ST-link烧录过程中,编译器未包含相应头文件或初始化函数,可能导致在某个步骤时初始化的串口仅在烧录完成后被擦除而无法继续使用。
      • 如果在程序启动时未能正确配置或初始化串口,应确保在esp_Init()函数中提供与目标串口相关的有效设置,例如启动模式、波特率、同步模式等。
      • 对于使用STM32F103C8T6芯片,部分器件内部设置在烧录前已进行擦除,因此在早期版本的硬件条件下,直接设置串口可能难以实现。
      • 对于最新版本的STM32系列,可以使用指定板件上的内部存储空间来挂载和初始化串口,通过函数STM32Cube_ID::uc_i2s_init()STM32Cube_ID::uc_i2s_register_device()进行相关操作。对于更复杂的STM32架构,可能需要依赖外部库(如stm32 CubeMX)提供的初始化方法和功能,以便更好地配置串口和处理烧录过程中的各种细节。

    综上所述,要解决上述问题,首先需从串口擦除操作开始排查,尝试解除相关错误信息并恢复串口读写状态。接着,在程序编写阶段充分考虑烧录文件格式和控制台通信流程,正确配置并初始化串口连接信息。若必要,还需查阅烧录库的官方文档,深入了解内部擦除机制,并结合STM32系列芯片特性及最新的开发环境优化相关处理。以下是一个示例串口擦拭清除向量以及STlink相关设置的参考代码:

    #include <reg53.h>
    #include <stdio.h>
    
    #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的数据表结构等,以避免后续串口初始化问题的发生。
    • 在恢复串口读写功能的过程中,注意防止不必要的内存操作和栈溢出风险,通过适当的数据结构和边界检查来减少这些潜在问题的发生。
    • 考虑到未正确配置串口连接属性和模式,可能出现串口未识别或丢失连接的情况。在实际操作中,应确保各种情况下都能正确地开启、终止、切换和锁定串口,以保证稳定且高效的串口通信性能。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 4月15日
  • 已采纳回答 4月7日
  • 创建了问题 3月30日

悬赏问题

  • ¥15 郑州牧原测试岗值得去吗
  • ¥100 复现论文:matlab仿真代码编写
  • ¥15 esp32驱动GC9A01循环播放视频
  • ¥15 惠普360g9的最新bios
  • ¥30 这个功能用什么软件发合适?
  • ¥60 微信小程序,取消订单,偶尔订单没有改变状态
  • ¥15 用pytorch实现PPO算法
  • ¥15 关于调制信号的星座图?
  • ¥30 前端传参时,后端接收不到参数
  • ¥15 这是有什么问题吗,我检查许可证了但是显示有呢