• STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案


    STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案


    ⛳昨天在测试过程中就已经发现了,后面无意间尝试选择了STM32F10ZET6单片机进行烧录测试,结果串口输出正常了。STM32F10ZET6单片机的话是144引脚的,容量一样,STM32F103VET6100个引脚的。

    在这里插入图片描述

    • 📝在VSCode平台PIO下,编译上传的,也是同样如此。为什么确信是bug,是因为在使用Hal库开发的时候,串口打印都正常的,通过Arduino框架上传的代码,串口输出就是乱码。

    怀疑应该是时钟参数配置出问题了。

    🚩当前使用的固件版本:2.3.0

    • bug已提交到:https://github.com/stm32duino/Arduino_Core_STM32/issues 编号:#1856
    🛠今天已经找到解决此bug问题,已在github上提交了解决此bug的方法。

    修改时钟配置函数

    • 找到ST STM32核心库的文件的位置:C:\Users\Administrator\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.3.0\variants\STM32F1xx\F103V(C-D-E)(H-T)\generic_clock.c
    WEAK void SystemClock_Config(void)
    #if defined(USBCON)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
    
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;//12
    
    
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                    | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
        Error_Handler();
      }
      PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
      PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL;
      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
        Error_Handler();
      }
    }
    #else
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
    
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {};//新增内容
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      //注释以下内容
      // RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      // RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      // RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      // RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      // RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
      // RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
    //新增以下内容
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                    | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
        Error_Handler();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • ⛳在不修改源文件的前提下,可以在程序前面放置时钟函数:
    extern "C" void SystemClock_Config(void){
    
      RCC_OscInitTypeDef RCC_OscInitStruct = {};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                    | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
        Error_Handler();
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    示例代码

    #define led4  PC13
    
    #define led1  PE5
    #define led2  PB5
    #define led3  PE6
    
    #define button1  PE8
    #define button2  PE7
    extern "C" void SystemClock_Config(void){
    
      RCC_OscInitTypeDef RCC_OscInitStruct = {};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {};//新增内容
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                    | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
        Error_Handler();
      }
    
    }
    void count() {
      Serial.println("PE8 BUTTON KEYPRESS");
    }
    
    void count2() {
     Serial.println("PE7 BUTTON KEYPRESS");
    }
    //                     RX    TX
    //HardwareSerial Serial(PA10, PA9);//将串口1的管脚指定到PA10,PA9引脚上
    // the setup function runs once when you press reset or power the board
    void setup() {
    //  Serial.setRx(PC11); // using pin name PY_n
    //  Serial.setTx(PC10); // using pin number PYn
      Serial.setRx(PA10); // using pin name PY_n
      Serial.setTx(PA9); // using pin number PYn
      delay(200);
      Serial.begin(115200, SERIAL_8N1);//PA3,PA2
      delay(200);
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(led4, OUTPUT);
        pinMode(led1, OUTPUT);
         pinMode(led2, OUTPUT);
         pinMode(led3, OUTPUT);
         digitalWrite(led1, HIGH);
         digitalWrite(led2, HIGH);
         digitalWrite(led3, HIGH);
           pinMode(button1, INPUT_PULLUP);
         pinMode(button2, INPUT_PULLUP);
         attachInterrupt(digitalPinToInterrupt(button1), count, FALLING);   //创建中断
         attachInterrupt(digitalPinToInterrupt(button2), count2, FALLING);   //创建中断
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
  • 相关阅读:
    【c语言】编译链接--详解
    javascript学习之数据类型转换
    酷开科技生态内容价值+酷开系统的开放性和可塑性,实现品效合一
    (一)shell编程
    Integer和int
    【ACK秒级部署】20万用户在10秒处理所有请求每个用户每秒5次请求
    Zuul使用总结
    GBase 8c结果集类型
    经典/最新计算机视觉论文及代码推荐
    C++:STL--List
  • 原文地址:https://blog.csdn.net/weixin_42880082/article/details/127624099