Skip to content

[LibOpenCM3 × STM32教學-1] 用LibOpenCM3來開發STM32-LED閃爍範例

發佈

我在 2022 年 9 月重新寫了與本文內容相近的文章,建議可以觀看新文章:

前言

LibOpenCM3 是一個 Open-Source(LGPL) 的 ARM Cortex-M3 微控制器底層硬體函式庫,支援包含 STM32、NXP LPC1000、Atmel SAM3U 等各種微控制器。

本篇文章將會示範如何以 LibOpenCM3 寫出可以在 STM32 上執行的 LED 閃爍程式。本文的程式也有一併放在 GitHub 上:ziteh/stm32-examples

正文

環境與專案

我使用的 IDE 為 PlatformIO IDE for VSCode(Visual Studio Code),並安裝了 ST STM32 Ver 15.0.0 平臺。有關 PlatformIO 的介紹可以看我寫的另一篇文章:[STM32學習記錄-6] 在VS Code與PlatformIO上開發STM32

安裝完相關軟體後就可以建立一個 PlatformIO 專案。我示範使用的開發板為「ST Nucleo-F103RB(STM32F103RB)」,並選擇「Framework」為「libopencm3」。

程式全文

在「src」資料夾中新增檔案「main.c」,並在加入以下的程式:

/**
 * @file   main.c
 * @brief  Blinking LED example.
 */
 
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
 
#define RCC_LED_PORT (RCC_GPIOA)
#define LED_PORT     (GPIOA)
#define LED_PIN      (GPIO5)
 
void delay(unsigned int value)
{
  while(value--)
  {
    __asm__("nop"); /* Do nothing. */
  }
}
 
int main(void)
{
  /* Enable clock. */
  rcc_periph_clock_enable(RCC_LED_PORT);
 
  /* Configure GPIO as push-pull output and maximum speed of 2 MHz. */
  gpio_set_mode(LED_PORT,
                GPIO_MODE_OUTPUT_2_MHZ,
                GPIO_CNF_OUTPUT_PUSHPULL,
                LED_PIN);
 
  /* Start blinking. */
  while (1)
  {
    gpio_toggle(LED_PORT, LED_PIN); /* LED on/off. */
    delay(500000);                  /* Wait a bit. */
  }
 
  return 0;
}

程式說明

接下來會依序介紹各部分程式。

引入函式庫

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>

就如同其它程式一樣,首先要做的是引入要用的 LibOpenCM3 函式庫。在本範例中需要用到 rcc.hgpio.h 這兩個檔案,因此將其引入。

其中 rcc.h 的「RCC」是「Reset and Clock Controller」的意思,基本上所有 STM32 的功能都與它有關,通常一定會用到。而 gpio.h 的「GPIO」當然就是「General-Purpose Input/Output」的意思,要控制 IO 接腳的話就會需要。

PlatformIO 在建立專案的時候就會依照設定來準備好 LibOpenCM3 的相關檔案了,因此不用另外下載和設定,直接打 #include 就可以了。

設定接腳

#define RCC_LED_PORT (RCC_GPIOA)
#define LED_PORT     (GPIOA)
#define LED_PIN      (GPIO5)

因為每個開發板的板載 LED 腳位可能不同,因此透過 #define 的方式宣告要使用的腳位,這樣要修改腳位的話只要修改一個地方,會比較方便且不易出錯。

我使用的 Nucleo-F103RB 的板載 LED 位於「PA5」,因此需要設定 Port 與 Pin 為 GPIOAGPIO5。另外 RCC 也會需要 Port 的設定,因為一併設定一個 RCC_GPIOA

Delay 函數 delay()

void delay(unsigned int value)
{
  while(value--)
  {
    __asm__("nop"); /* Do nothing. */
  }
}

這是一個最簡單的 Delay 函數,雖然它基本上無精準可言,但以本範例來說也不需要精確的定時。

其中 __asm__("nop") 代表的是嵌入組合語言「nop」指令,也就是無操作(No Operation)。

如果想要把 Delay 函數放在主程式 main() 之後,記得要宣告函數原型或使用標頭檔。

主程式 main()

int main(void)
{
  /* Enable clock. */
  rcc_periph_clock_enable(RCC_LED_PORT);
 
  /* Configure GPIO as push-pull output and maximum speed of 2 MHz. */
  gpio_set_mode(LED_PORT,
                GPIO_MODE_OUTPUT_2_MHZ,
                GPIO_CNF_OUTPUT_PUSHPULL,
                LED_PIN);
 
  /* Start blinking. */
  while (1)
  {
    gpio_toggle(LED_PORT, LED_PIN); /* LED on/off. */
    delay(500000);                  /* Wait a bit. */
  }
 
  return 0;
}

結語

本次文章內介紹的程式我也有放在 GitHub 上,可以直接載下來並使用 PlatformIO 開始專案。

各位也可以參考 PlatformIO 所提供的範例

相關文章


如果幸福有顏色
[STM32學習記錄-6] 在VS Code與PlatformIO上開發STM32

留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)