STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案相关的知识,希望对你有一定的参考价值。
STM32F103VET6基于Arduino开发框架下串口和软串口输出乱码解决方案
⛳昨天在测试过程中就已经发现了,后面无意间尝试选择了
STM32F10ZET6
单片机进行烧录测试,结果串口输出正常了。STM32F10ZET6
单片机的话是144
引脚的,容量一样,STM32F103VET6
是100
个引脚的。
- 📝在
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频率