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

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
  

  • ⛳在不修改源文件的前提下,可以在程序前面放置时钟函数:
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();
  


示例代码

#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);   //创建中断


以上是关于STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案的主要内容,如果未能解决你的问题,请参考以下文章

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

STM32F103VET6基于STM32CubeMX RTC时钟报警中断使用示例

STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁

STM32F103VET6基于STM32CubeMX利用EXTI外部中断测量PWM频率

STM32F103VET6基于STM32CubeMX创建EXTI外部中断工程

STM32F103VET6基于STM32CubeMX RTC时钟秒更新中断使用示例