STM32F103C8T6 マイコン

STM32F103C8T6 が載った基板を購入したので、まずはST社からSTM32CubeF1をダウンロードして開発環境を整えてみます。
流用できるプロジェクトファイルは、STM32F103RB-Nucleoでイケます。main関数は基板固有コードばかりなので空関数にしますが、
使用するソースファイルやヘッダファイル、コンパイルオプションは、まずは同じでOKです。後から精査しましょう。

STM32CubeF1内のDrivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.hに使用するマイコン名を#defineするように記載されていますが、私はコンパイルオプション(-Dプリプロセッサ定義)でSTM32F103xBを指定します。(何故なら敢えてオリジナルファイルを変更しなくても対応可能な方法だから、ソースの変更管理しなくて済みます。
私の統合開発環境(IDE)は、IAR社のEWARMを使用しているから、iarフォルダ下にプロジェクトファイルがあります。このプロジェクトファイルをEWARMで開けば、必要なソースファイルが分かりますが、ココにも載せておきます。本サイトのSTM32F303K8でも取り上げています。

---STM32Cube_F1 フォルダ構成---
STM32Cube_FW_F1_V1.6.0
+Drivers
 +CMSIS
 |+Device
 ||+ST
 || +STM32F1xx
 ||  +Include   :includeパスにセットするフォルダ
 ||  +Source
 ||   +Templates   :以下(2)にコピーされている
 ||    +iar
 |+Include
 +STM32F1xx_HAL_Driver
  +Inc           :includeパスにセットするフォルダ
  +Src           :以下(1)参照
+Projects
 +STM32F103RB-Nucleo
  +Templates_LL
   +EWARM       :IAR用ファイルのフォルダ
   +Inc         :includeパスにセットするフォルダ
   +Src         :以下(3)参照
+Middlewares
 +Third_Party
  +FreeRTOS      :リアルタイムOS


---(1)Drivers\STM32F1xx_HAL_Driver\Src---
stm32f1xx_hal_XXXX.c  :HALドライバ
stm32f1xx_ll_XXXX.c   :LLドライバ

---(2)Projects\STM32F103RB-Nucleo\Templates_LL\EWARM---
startup_stm32f103xb.s  :ベクタテーブル、リセットハンドラ
stm32f103xb_flash.icf  :IARリンカの設定ファイル

---(3)Projects\STM32F103RB-Nucleo\Templates_LL\Src---
main.c
stm32f1xx_it.c     :割り込みハンドラ(無くても良い。各ハンドラはweakでstartup_stm32f103xb.sに定義済み)
system_stm32f1xx.c :boot初期処理

外部クロックHSE(8MHz)を用いて動作させるために必要なファイル一覧を以下に記載します。
ちなみにCMSISのLLドライバを使用しました。

---STM32Cube_F1 外部クロックで動作させるために必要なファイル一覧---
main.c
startup_stm32f103xb.s
system_stm32f1xx.c
(stm32_assert.h)
stm32f103x8.icf
stm32f1xx_ll_gpio.c
stm32f1xx_ll_rcc.c

STM32マイコンは、Power ONで内部クロックHSI(8MHz)により動作します。従って、ベクタテーブルのリセットハンドラさえあればmain()迄実行され、main(){while(1);}だけの空転関数でも動作します。
しかし、次のmain()ではFreeRTOSを盛り込み、外部クロックHSE(8MHz)を用いて動作するように設定した実装例も載せておきます。省電力のため動作クロックはSYSCLK 48MHz、HCLK 24MHzに落としてます。

---main.c---
#include "stm32f1xx_ll_rcc.h"
#include "stm32f1xx_ll_system.h"
#include "stm32f1xx_ll_gpio.h"
#include "stm32f1xx_ll_bus.h"
#include "FreeRTOS.h"	//FreeRTOS用
#include "task.h"	//FreeRTOS用

void SystemClock_Config(void);
void createOsResource(void);	//FreeRTOS用

/* テストピン(LED1)定義 */
#define LED1_GPIO		GPIOC
#define LED1_PIN		LL_GPIO_PIN_13

/**
 * @brief   Main program
 * @param   None
 * @retval  None
 */
int main(void)
{
	/* setup system clocks */
	SystemClock_Config();

	/* テストピン(LED1)をEnable */
	LL_APB2_GRP1_EnableClock( LL_APB2_GRP1_PERIPH_GPIOC );
#if 0	// LL_GPIO_Init()にBUGあり
	{
	LL_GPIO_InitTypeDef  pin_cfg;
		/* ポートCをEnableにする */
		LL_GPIO_DeInit(LED1_GPIO);

		/* テストピン(LED1)をセットアップする */
		pin_cfg.Pin		= LED1_PIN;
		pin_cfg.Mode		= LL_GPIO_MODE_OUTPUT;
		pin_cfg.Speed		= LL_GPIO_SPEED_FREQ_LOW;
		pin_cfg.OutputType	= LL_GPIO_OUTPUT_PUSHPULL;
		pin_cfg.Pull		= LL_GPIO_PULL_UP;
		LL_GPIO_Init(LED1_GPIO, &pin_cfg);
	}
#else
	/* Pin Mode configuration */
	LL_GPIO_SetPinMode( LED1_GPIO, LED1_PIN, LL_GPIO_MODE_OUTPUT );
	/* Pull-up Pull down resistor configuration*/
	LL_GPIO_SetPinPull( LED1_GPIO, LED1_PIN, LL_GPIO_PULL_UP );
	/* Speed mode configuration */
	LL_GPIO_SetPinSpeed( LED1_GPIO, LED1_PIN, LL_GPIO_SPEED_FREQ_LOW );
	/* Output mode configuration*/
	LL_GPIO_SetPinOutputType( LED1_GPIO, LED1_PIN, LL_GPIO_OUTPUT_PUSHPULL );
#endif

	/* OSリソース生成 */
	createOsResource();	//FreeRTOS用

	/* Start the scheduler */
	vTaskStartScheduler();	//FreeRTOS用

	while(1);
}

/**
 * @brief   System Clock Configuration
 *          The system Clock is configured as follow : 
 *             System Clock source            = PLL (HSE)
 *             SYSCLK(Hz)                     = 48000000
 *             HCLK(Hz)                       = 24000000
 *             AHB Prescaler                  = 2
 *             APB1 Prescaler                 = 1
 *             APB2 Prescaler                 = 1
 *             HSE Frequency(Hz)              = 8000000
 *             PLL_MUL                        = 6
 *             Flash Latency(WS)              = 1
 * @param   None
 * @retval  None
 */
void SystemClock_Config(void)
{
#if 1
//	LL_APB2_GRP1_EnableClock( LL_APB2_GRP1_PERIPH_GPIOD );
//	LL_RCC_EnableIT_HSERDY(); 
	LL_RCC_HSE_EnableCSS(); 
	/* Enable HSE oscillator */
//	LL_RCC_HSE_EnableBypass();
	LL_RCC_HSE_Enable();
	while( LL_RCC_HSE_IsReady() != 1 );
#endif
	/* Set FLASH latency */
	LL_FLASH_SetLatency( LL_FLASH_LATENCY_2 );

	/* Set PLLSRC & PLLMUL */
#if 1
	LL_RCC_PLL_ConfigDomain_SYS( LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_6 );
#else
	LL_RCC_PLL_ConfigDomain_SYS( LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_12 );
#endif
	LL_RCC_PLL_Enable();
	while( LL_RCC_PLL_IsReady() != 1 );

	/* Set AHB prescaler */
	LL_RCC_SetAHBPrescaler( LL_RCC_SYSCLK_DIV_2 );
	/* Select SYSCLK by PLLCLK */
	LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_PLL );
	while( LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL );

	/* Set APB1 & APB2 prescaler */
	LL_RCC_SetAPB1Prescaler( LL_RCC_APB1_DIV_1 );
	LL_RCC_SetAPB2Prescaler( LL_RCC_APB2_DIV_1 );

	/* Set SYSTICK to 10ms */
	SysTick_Config( 48000000 / 100 );

	/* Set CMSIS variable */
	SystemCoreClock = 48000000;
}

/**
  * @brief  TICKフック of FreeRTOS
  * @param  None
  * @retval None
  */
#define TICK_HOOKCNT  20		//= 200ms=20 * os tick=10ms
int16_t   iHookCnt = TICK_HOOKCNT;
void vApplicationTickHook( void )
{
	if(--iHookCnt <= 0){
		iHookCnt = TICK_HOOKCNT;
		/* テストピン(LED1)にトグル出力 */
		LL_GPIO_TogglePin(LED1_GPIO, LED1_PIN);
	}
}

/**
  * @brief  空タスク
  * @param  None
  * @retval None
  */
void XXXXTask( void * pvParameters )
{
	for( ;; );
}

/**
  * @brief  create FreeRTOS resorce.
  *         タスクやメッセージキューを生成する
  * @param  None
  * @retval None
  */
#define	XXXXTask_STACK_SIZE		configMINIMAL_STACK_SIZE
void createOsResource(void)
{
	static uint8_t ucParameterToPass;
	TaskHandle_t xHandle = NULL;

	// Create the task, storing the handle.
	xTaskCreate( XXXXTask, "TSKNAME", XXXXTask_STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
	configASSERT( xHandle );
}

FreeRTOSを盛り込むにあたり、startup_stm32f103xb.sの実装例も載せておきます。

        PUBWEAK SVC_Handler
	EXTERN  vPortSVCHandler		;☆追加
        SECTION .text:CODE:REORDER:NOROOT(1)
SVC_Handler
        B vPortSVCHandler		;☆変更

        PUBWEAK DebugMon_Handler
        SECTION .text:CODE:REORDER:NOROOT(1)
DebugMon_Handler
        B DebugMon_Handler

        PUBWEAK PendSV_Handler
	EXTERN  xPortPendSVHandler	;☆追加
        SECTION .text:CODE:REORDER:NOROOT(1)
PendSV_Handler
        B xPortPendSVHandler		;☆変更

        PUBWEAK SysTick_Handler
	EXTERN  xPortSysTickHandler	;☆追加
        SECTION .text:CODE:REORDER:NOROOT(1)
SysTick_Handler
        B xPortSysTickHandler		;☆変更