2021年1月30日土曜日

ロードバイクを購入しました Carrera ER-01

Carrera ER01というカーボンロードを購入しました。ERはエンデュランス・レーシングの略らしいです。フレームとコンポ以外はお店への納品ごとにちょこちょこ変わるそうです。

ロードバイク初心者なので、フラットペダルで、両足がつくぐらいのセッティングです。慣らしサイクリングしましたが、さすがにサドルが低すぎました。

納車時

フレーム



コンポ Shimano 105




サドル Cinelli製


ペダル MKS CT-LITE


ライト

ライトはLezyneの前後セット品にしました。




初サイクリング時



2021年1月29日金曜日

STM32CubeIDE: General-purpose Timerを使う

STM32F446REには汎用的なGeneral-purpose Timerが8個搭載されています。PWM、入力キャプチャ、出力コンペアなど機能がいろいろありますが、Basic Timerと同じように単に割り込みを発生させるタイマーとして使ってみます。

General-purpose Timerの諸機能については
  • STM32シリーズ タイマ概要 AN4013
  • トランジスタ技術 2020年 3月号 別冊付録1 STM32F Armマイコン・プログラミング・ガイドブック
が参考になると思います。

STM32CubeIDE: Version 1.5.1
Target board: Nucleo-F446RE

MXの設定

Timers
  Mode
    Clock Source: Internal Clock
  Configuration
    Parameter Settings
      Counter Settings
        Prescaler: 8400-1
        Counter Period: 1000-1
    NVIC Settings
        TIM global interrupt: Enabled: ✓

Clock Sourceでクロック源に内蔵クロックを割り当てます。

Prescalerに8400、Counter Periodに1000を設定します(STM32Fの仕様上-1する)。BoardにNucleo-F446REを指定して初期化するとクロックは84MHzに設定されるので84MHz / (8400 * 1000) = 10Hzとなり、100msごとにタイマ割り込みが発生します。

NVIC SettingsでTIM2の割り込みを有効化します。

main.cにコードを追加


  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);
  /* USER CODE END 2 */

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef * htim)
{
	if (htim == &htim2) {
		HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
}
/* USER CODE END 4 */

General Purpose Timerをタイマ割り込みで使う場合、前回のBasic Timerと異なるのはClock Sourceを設定する必要がある点だけです。

LD2の出力波形


実行するとボード上のLED(LD2)が200ms(High:100ms+Low:100ms)周期で点滅します。

オシロで観測
 

2021年1月26日火曜日

STM32CubeIDE: Basic Timerを使う

STM32F446REには
  • Advanced-control Timer
  • General purpose Timer
  • Basic Timer
の3種類のTimerが搭載されています。この中でBasic Timerが最も機能が少なく設定も簡単です。

STM32F446REのBasic TimerはTIM6、TIM7の2つです。Basic Timer主に内蔵DACトリガーと波形生成に使われます。もし内蔵DACを使う場合はTIM6、TIM7は使わないほうが無難だと思います。

TIM6の割り込みでLチカを駆動する


メインループ内でHAL_Delay()を使ってLチカさせるのではなく、Timer割り込みでLチカします。タイミングが正確になり、メインループではLチカを気にすることなく他の仕事に専念できます。

STM32CubeIDE: Version 1.5.1
Target board: Nucleo-F446RE

MXの設定


Timers
  TIM6
    Configuration
      Prameter Settings
        Counter Settings
          Prescaler(PSC - 16 bits value): 42000-1
          Counter Period(AutoReload Register -16 bits value): 1000-1
     
    NVIC Settings
      NVIC Interruput Table
        TIM6 global interruput and DAC1, DAC2 underrun error interrupts: ✓

Nucleo-F446REを指定して初期化するとデフォルトではクロック(APB1/APB2 Timer Clocks)は84MHzになります。Prescalarに42000を設定すると2kHzになり、Counter Periodが1000なので2Hz→0.5sの周期で割り込みがかかります。

PrescalerとCounter Periodは-1した値を設定する必要があるそうです。

参考: トランジスタ技術 2020年3月号 別冊付録1 P38

TIM6のCounter Settingsにはauto-reload preloadという項目がありますが、これはCounter Periodを動的に設定した際に、値を反映させるタイミングを設定するもののようです。

参考: RM039: 19.3.2 Basic timers - Counting Mode

割り込みを使用する際にはNVICで割り込みを有効にする必要があります。結構忘れがちですw

main.cにコードを追加


  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim6);
  /* USER CODE END 2 */

HAL_TIM_Base_Start_IT()でタイマーを開始し、割り込みを有効にします。

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef * htim)
{
	if (htim == &htim6) {
		HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
}
/* USER CODE END 4 */

HAL_TIM_PeriodElapsedCallback()で割り込みハンドラを記述します。LD2の出力をトグルします。

これでボード上のLED2が1秒間隔で点滅します。

オシロで波形を観測


2021年1月24日日曜日

STM32CubeIDE: SPIをInterruptで使う

STM32CubeIDE: Version 1.5.1
Target board: Nucleo-F446RE

SPI通信の終了時に割り込みを発生させる方法です。

非同期なのでSPI通信中はペリフェラルに仕事を任せてその間MPUは他のことができます。今回は、割り込みでSPI通信を行い、メインループではLチカを行います。


Nucleo-F446REのPin機能の割り当て

MX(Device Configuration Tool)の設定


今回はSPI2を使い、MXのデフォルトのピンアサインにしてみます。Hardware NSSは使っていませんが同じピン割り当てにしました。

Pinout


ピン割り当て


ピン名 機能
PB10 SPI2_SCK
PC1 SPI2_MOSI
PB12 SPI2_CS (Software)
PA5 LD2(LED)

SPIの設定

Prameter Settingsで基本的なパラメータを設定します。


NVIC Settingsで割り込みベクタを設定します。


変更点


Connectivity
  SPI2
    Parameter Settings
      Prescaler (for Bud Rate) 256
    NVIC Settings
      SPI2 global interrupt Enabled ✓

GPIOの設定

CS(PB12)をSoftware制御するためにGPIOを設定します。



LD2(ボード上のLED)はMXでBoardを指定して初期化すれば、自動的に設定されます。

変更点

System Core
  GPIO
    PB12
      GPIO output level: High  // CSはActive Lowのため初期値はHigh
      Maximum output speed: Very High
      User Label: SPI2_CS

main.cにコードを追加

初期化


/* USER CODE BEGIN PV */
uint8_t data[2] = { 0x55, 0xAA };
/* USER CODE END PV */

送信するデータを定義します。

  /* USER CODE BEGIN 2 */
  HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET);  // CS線をLowに
  if (HAL_SPI_Transmit_IT(&hspi2, data, 2) != HAL_OK) {
	Error_Handler();
  }
  // SPI通信が終わっていないのでここではCS線をHighにしない
  /* USER CODE END 2 */

割り込みを発生させるにはHAL_SPI_Transmit_IT()を使います。

メインループ


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  // SPI通信と非同期にLチカ
	  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	  HAL_Delay(100);
  }
  /* USER CODE END 3 */

メインループ内ではGPIOを100msごとにH/Lさせます。これによってSPI通信が非同期に行われていることが確認できます。

割り込み処理ルーチン


/* USER CODE BEGIN 4 */
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
	HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_SET);    // SPI通信が完了したのでCS線をHighに
	HAL_GPIO_WritePin(SPI2_CS_GPIO_Port, SPI2_CS_Pin, GPIO_PIN_RESET);  // 次のSPI通信のためにCS線をLowに
	if (HAL_SPI_Transmit_IT(&hspi2, (uint8_t*)data, 2) != HAL_OK) {
		Error_Handler();
	}
	// SPI通信が終わっていのでここではCS線をHighにしない
}
/* USER CODE END 4 */

割り込み処理ルーチン内で再度SPI通信を開始します。繰り返しSPI通信が行われることになります。

出力信号の観測


Analog Discovery 2のScope機能でLチカの波形、Logic機能でSPI信号とLチカの様子を見ています。

メモ:


STM32CubeIDEのTextEditorではコメントの日本語が文字化けするようです。日本語は使わないほうが無難だと思います。

2021年1月15日金曜日

STM32CubeIDE: SPIをPollingで使う

STM32CubeIDE: Version 1.5.1
Target board: Nucleo-F446RE

MX(Device Configuration Tool)の設定

今回は、Half-Duplex(半二重通信)とします。また、NucleoにはArduino互換のヘッダがあるので、Arduino UNOのSPIと同じ割り当てにしてみます。

MX(Device Configuration Tool)の設定

ピンの割り当て

SPI Pin Function Arduinoピン名
SCK PA5 SPI1_SCK D13
MOSI PA7 SPI1_MOSI D11
CS PB6 GPIO_OUTPUT D10

デフォルトではPB3がSWO(SYS_JTDO_SWO)に割り当てられていてSPI1が使えなくなっています。PB3を「Reset_State」します。

ハードウェア制御のNSS(CS)はうまく動作しないので、GPIOを割り当てソフトウェアで制御することにします。


STM32はピンごとに割り当て可能な機能が決まっていて、STM32CubeIDEのPinout Viewでピンをクリックすると選択可能な一覧が表示されます。

また、MCUのデータシート(例えば「STM32F446 Datesheet」でググると見つかります)の「Pinout and pin description」の「Alternate function」表で割り当て可能な機能が確認できます。

変更するパラメータ



Categories
  System Core
    GPIO
      PB6
        GPIO output level: High
        Maximum output speed: Very High
        User Label: SPI1_CS

SPIのCSはActive Lawなので初期値としてGPIO output levelをHighにします。わかりやすいように、SPI1_CSというUser Labelをつけます。


Categories
  Connectivity
    SPI1
      Mode: Half-Duplex Master
    Parameter Settings
      Clock Prameters
        Prescaler (for Baud Rate): 256

SPIのクロックは低速のほうが動作確認しやすいのでプリスケーラを256に設定します。

main.cにコードを追加

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  uint8_t data[2] = { 0x55, 0xAA };
	  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
	  if (HAL_SPI_Transmit(&hspi1, data, 2, 100) != HAL_OK) {
		  Error_Handler();
	  }
	  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);
  }
  /* USER CODE END 3 */

出力信号の観測


Analog Discovery 2のLogic機能でSPI信号を観測しました。


 Analog Discovery 2はアナログ入力とデジタル入力が独立しているので、Scope機能とLogic機能を同時に利用することができます。



ウィンドウの上半分が波形をアナログ波形としてみたところ、下半分がデジタル信号として見たところです。

2021年1月10日日曜日

STM32CubeIDE: 覚え書き

個別の記事にするほどでもない事柄のメモです。

STM32CubeIDEがインストールできない


ルートディレクトリ(D:\など)にインストーラーを置いて実行するとうまくいく場合がある。


サンプルプロジェクトの所在


<ユーザーフォルダ>\STM32Cube\Repository\STM32Cube_FW_Fx_Vx.xx.x\Projects

例えば、C:\Users\<ユーザー名>\STM32Cube\配下など。

日本語版ドキュメント

STM32/STM8 デザイン/サポート https://www.stmcu.jp/design/

書籍

Interface 2016年12月号 別冊付録「定番ARMマイコン STM32便利帳 2016」
トランジスタ技術 2020年3月号別冊付録1「STM32F Armマイコン・プログラミング・ガイドブック」

Datasheet


STM32F303K8: DS10362 STM32F303x6/x8 Datasheet
STM32F446RE: DS10693 STM32F446xC/E Datasheet
STM32F767ZI: DS11532 STM32F767xx Datasheet
STM32G431KB: DS12589 STM32G431x6 STM32G431x8 STM32G431xB Datasheet

Reference Manual


STM32F303K8: RM0316
STM32F446RE: RM0390
STM32F767ZI: RM0410
STM32G4 Series: RM0440

Nucleoボードのユーザーマニュアル


Nucleo-32:  UM1956 User Manual STM32 Nucleo-32 boards (MB1180)
Nucleo-32 STM32G4: User Manual STM32G4 Nucleo-32 board (MB1430)
Nucleo-64:  UM1724 User Manual STM32 Nucleo-64 boards (MB1136)
Nucleo-144: UM1974 User Manual STM32 Nucleo-144 boards (MB1137)

HAL / LLのユーザーマニュアル


F3: UM1786 User Manual Description of STM32F3 HAL and low-layer drivers
F4: UM1725 User Manual Description of STM32F4 HAL and low-layer drivers
G4: UM2570 User Manual Description of STM32G4 HAL and low-layer drivers 
F7: UM1905 User Manual Description of STM32F7 HAL and low-layer drivers

STM32CubeMXのユーザーマニュアル


UM1718 STM32CubeMX for STM32 configuration and initialization C code generation

STM32CubeIDEのユーザーマニュアル


UM2609 STM32CubeIDE user guide

Buildの設定


Project - Properties
C/C++ Build > Settings


MCU Serttings: fpuの設定など
MCU GCC Compiler > Optimization: 最適化レベルなど

Timer


STM32シリーズ タイマ概要 AN4013
汎用タイマ クックブック AN4776

SPIのハードウェアNSS


うまく動作しないようだが、Pullupするとうまくいくかも?

2021年1月9日土曜日

STM32CubeIDE: Projectを複製

STM32CubeIDEのProject Explorer上でCopy&PasteすればProjectを複製できますが、そのままではBuildできません。以下の手順でうまく複製できるようです。
  1. Project Explorerで複製するProjectを選択
  2. メニューの「Edit」-「Copy」
  3. メニューの「Edit」-「Paste」
  4. .iocファイルをプロジェクト名に合わせてRename
  5. Debug.launchファイルをDelete
  6. メニューの「Project」-「Clean...」(表示されるダイアログで複製したProjectを選択)
  7. .iocファイルをダブルクリックしてDevice Configuration Toolを開く
  8. メニューの「Project」-「Generate Code」
  9. メニューの「Project」-「Build Project」
  10. メニューの「Run」-「Run As」-「STM32 Cortex-M C/C++ Application」
STM32CubeIDE: Version: 1.5.1


注意


上記手順の8. Generate Codeで、コピー元のmain.cが消え、Genrate Codeで生成されたコードの整合性も取れなくなるようです。実行する前に少なくとも元のプロジェクトのmain.cを退避しておいたほうが良いです。

2021.01.11追記

2021年1月8日金曜日

STM32CubeIDE: UARTでprintfを使う(浮動小数点数型あり)

STM32のネイティブな環境で開発しようと思って、STM32CubeMXとEclipseベースのIDEのSW4STM32やTrueStudioを試していましたが、STMicroよりCubeMXを含めた統合開発環境のSTM32CubeIDEが提供されているので、改めて各種機能を試してみたいと思います。ほぼほぼ自分用のあんちょこです。

トランジスタ技術2020年3月号でSTM32が特集されているので参考になります。



UARTでprintf()を使う


PCとのシリアル通信でprintf()を使う方法です。printf()内部で呼ばれる関数を定義してやることで、mbedのprintf()のように使えます。

STM32CubeIDE: Version: 1.5.1
Target Board: Nucleo-F446RE

手順


ボードを指定してプロジェクトを新規作成します。

特に設定しなくてもUART2が有効化されています。

そのまま「Project」-「Generate Code」(または ツールバーの「ギア」のアイコン)でコードを生成します。

コードが生成されたら「Project Exploer」で<project名>/Core/Src/main.cをダブルクリックして編集します。(すでにEditorで開かれていると思いますが)

printf()を使うために<stdio.h>をインクルードします。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

printf()内で間接的に呼ばれる__io_putchar()を定義します。

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
 HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
 return ch;
}
/* USER CODE END 0 */

メインループ内でprintf()を呼び出します。

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  const char msg[] = "COUNT:";
  int cnt = 0;
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  float fv = cnt * 0.01f;
	  printf("%s\t%d\t%f\r\n", msg, cnt, fv);
	  cnt++;
	  HAL_Delay(1000);
  }
  /* USER CODE END 3 */

printf()の書式でfloat型を使う


浮動小数点フォーマットのサポートが有効になっていない」とのエラーメッセージが表示されます。

The float formatting support is not enabled, check your MCU Settings from "Project Properties > C/C++ Build > Settings > Tool Settings", or add manually "-u _printf_float" in linker flags.

以下のようにプロジェクトを設定します。

メニューの「Project」-「Properties」で表示されるダイアログで


画像のように「Use float with printf from newlib-nano(-u _puritf_float)」にチェックを入れます。

プロジェクトのビルドと実行


メニューの「Project」-「Build project」 (またはツールバーの「🔨」のアイコン)でビルドします。

メニューの「Run」-「Run As」-「Stm32 Application」(またはツールバーの「▷」のアイコン)で実行します。

PC上のターミナルで文字列を受信


PC上のターミナルソフトRLoginで受信している様子


ビットレートはDevice Configuration Tool(MX)のConnectivity > USART2 > Parameter Settingsで変更できます。
 

2021年1月7日木曜日

CV_HUB パッシブCVハブの試作

使用目的で名前をつけましたが、なんのことはない3.5Φモノジャック4個を並列につないだものです。



1つのEGやLFOの出力を分岐して複数のモジュールをモジュレーションできます。

もう一つの目的は、CVでモジュールをモジュレーションしながらオシロで波形を観測することです。


モノラルプラグに短いケーブルとQIピンをつないでおくとジャックに挿してオシロで波形を見たりテスタで導通をチェックするときに便利です。


試用してみると出力チャネルごとに
  • 利得可変
  • バイアス可変
  • 位相反転
みたいなことがしたくなりますね。かんたんなものですのでいずれ作るかもしれません。

2021年1月3日日曜日

ジャック/プラグのピンアウト

あけましておめでとうございます。

いつもはんだ付けするときにテスタで測定して極性を調べていて面倒なのでメモです。

DCジャック マル信 MJ-40

モノラルミニジャック マル信 MJ-355



※ステレオのMJ-355WもTip/Sleeveの位置は同じ。

ステレオ標準ジャック マル信 MJ-189(LP)


AliExpress ロータリースイッチ