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.
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值