STM32F103VET6基于Arduino开发框架下FreeRTOS串口1不能正常工作解决方案

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103VET6基于Arduino开发框架下FreeRTOS串口1不能正常工作解决方案相关的知识,希望对你有一定的参考价值。

STM32F103VET6基于Arduino开发框架下FreeRTOS串口1不能正常工作解决方案


✨通过搜索发现这个bug存在了这么多年了,在百度经验《STM32F103+FreeRTOS串口模块不能正常工作》就记录了STM32F10x外设固件库v3.5 + FreeRTOS v7.0.2存在这个问题,没想到今天在Arduino框架下还是遇到了同样的一个问题。

🛠解决方案

🔨1. 不能使用串口1作为调试信息输出。

🍁像STM32F103VET6芯片有4个串口,在Arduino框架下,可以根据使用情况调整到其他串口上。

HardwareSerial Serial1(PC11,PC10);
HardwareSerial Serial3(PA3,PA2);
HardwareSerial Serial4 (PC11, PC10); 
......
HardwareSerial Serial10 (PC11, PC10); 

✅串口和引脚号可以任意指定,只要不使用Serial,可以使用Serial1 - Serial10.

🔧2. 不使用基于FreeRTOS提供的延时函数。

可以使用delay()来替代 vTaskDelay((200L * configTICK_RATE_HZ);//200ms延时函数。

🔑经测试,以上两种方法都可行。

FreeRTOS依赖库

  • STM32FreeRTOS:- 在IDE里面打开管理库(Ctrl + Shift + I)页面搜索FreeRTOS关键字

🌼示例代码

#include <STM32FreeRTOS.h>//点击这里会自动打开管理库页面: http://librarymanager/All#FreeRTOS


HardwareSerial Serial3(USART3);
// Define the LED pin is attached
const uint8_t LED_PIN = PE5;

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();
  



// Declare a semaphore handle.
SemaphoreHandle_t sem;
//------------------------------------------------------------------------------
/*
 * Thread 1, turn the LED off when signalled by thread 2.
 */
// Declare the thread function for thread 1.
static void Thread1(void* arg) 
  UNUSED(arg);
    pinMode(PB5, OUTPUT);
  while (1) 
    digitalToggle(PB5);
    Serial3.println("PB5 LED TURN Toggle");
     vTaskDelay((200L * configTICK_RATE_HZ) / 1000L);//200ms
//   delay(500);
    // Wait for signal from thread 2.
    xSemaphoreTake(sem, portMAX_DELAY);

    // Turn LED off.
//    digitalWrite(LED_PIN, LOW);
  

//------------------------------------------------------------------------------
/*
 * Thread 2, turn the LED on and signal thread 1 to turn the LED off.
 */
// Declare the thread function for thread 2.
static void Thread2(void* arg) 
  UNUSED(arg);
  pinMode(LED_PIN, OUTPUT);

  while (1) 
    // Turn LED on.
//    digitalWrite(LED_PIN, HIGH);
      digitalToggle(LED_PIN);
 //     delay(500);
    // Sleep for 200 milliseconds.
    vTaskDelay((200L * configTICK_RATE_HZ) / 1000L);
Serial3.println("PE5 LED TURN Toggle");
    // Signal thread 1 to turn LED off.
    xSemaphoreGive(sem);

    // Sleep for 200 milliseconds.
   // vTaskDelay((200L * configTICK_RATE_HZ) / 1000L);
  

//------------------------------------------------------------------------------
void setup() 
  portBASE_TYPE s1, s2;
  Serial3.setRx(PC11); // using pin name PY_n
  Serial3.setTx(PC10); // using pin number PYn
  Serial3.begin(115200);

  delay(3000);
  Serial3.println("STM32F103VET6");

  // initialize semaphore
  sem = xSemaphoreCreateCounting(1, 0);

  // create task at priority two
  s1 = xTaskCreate(Thread1, NULL, configMINIMAL_STACK_SIZE, NULL, 2, NULL);

  // create task at priority one
  s2 = xTaskCreate(Thread2, NULL, configMINIMAL_STACK_SIZE, NULL, 1, NULL);

  // check for creation errors
  if (sem== NULL || s1 != pdPASS || s2 != pdPASS ) 
    Serial3.println(F("Creation problem"));
    while(1);
  

  // start scheduler
  vTaskStartScheduler();
  Serial3.println("Insufficient RAM");
  while(1);


//------------------------------------------------------------------------------
// WARNING idle loop has a very small stack (configMINIMAL_STACK_SIZE)
// loop must never block
void loop() 
  // Not used.

以上是关于STM32F103VET6基于Arduino开发框架下FreeRTOS串口1不能正常工作解决方案的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

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

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