2013年10月17日木曜日

CooCox CoIDE で STM32 の開発環境を作ってみた(その2)

台風と初雪が同時にやってきたのは初めてだよ・・・う~寒い
こんばんは syncton です。

前回で printf() デバッグができるようになったので、今回は USART の割り込みを使って MIDI 入力する部分を作っていきます。
今後も STM32 を使う予定があるので調べた事をまとめておきます。

[2013.10.18 追記] クロックの設定漏れがあったので6.1に追記


1.MIDIのハードウェア規格


  • 転送方式:非同期方式シリアル転送
  • 転送速度:31.25 kbit/s(±1%)
  • データ長:8 bit
  • パリティ:なし
  • ストップビット:1 bit
  • フロー制御:なし
JIS X6054-1:「電子楽器ディジタルインタフェース (MIDI) -第1部:総則
P.2 ハードウェア より

2.USARTとGPIO

[UM0919] STM32VL Discovery User Manual(Rev.2) P.8/24
Figure 6. STM32F100RBT6B block diagram より

2.1.GPIOの設定

「UM0919 STM32VL Discovery User Manual P.17 Table.6 P3 pinout」 で USART3 で使用するポートとピンを調べる。今回は APB2 のポートBのピン10,11を使用。
前回作成したMIDIインターフェースは5Vで動作しているので、これらのピンが5V耐性かどうかも調べておきます。
「STM32F100RB Datasheet(Rev.7)」に載っています。
I/O level が FT(5 V tolerant)なのでOKですね。
「STM32F100RB Datasheet(Rev.7)」 P.24
「Table 4. Low & medium-density STM32F100xx pin definitions」 より

GPIO のモードは「RM0041 Reference manual(Rev.4) P.107 Table 22. USARTs」によると、
入力は「Input floating」または「Input pull-up」が選択可能ですが、インターネット上のサンプルはほとんど「Input floating」を指定しているようです。
出力は「Alternate function push-pull」を指定します。

MIDI入力時の最大出力速度の設定は不要だと思うのですが、GPIO_InitTypeDef 構造体の GPIO_Speed に何らかの値をセットしないといけないのですが、調べても良くわかりませんでした。
そこで、ポート設定レジスタのリセット時の初期状態が0(ゼロ)なので、そうしてみました。

また、今回のサンプルではMIDI出力は使用しませんがピンの設定だけしておきます。
GPIO の最大出力速度は 2MHz、10MHz、50MHz から選べるのですが、STM32F100RB のクロックの最高速度は 24MHzなので、それより速い 50MHzは意味がないような気がします。
MIDIはそれほど高速ではないので、GPIOの最大出力速度は一番遅い 2MHz としてみました。

詳細は 「RM0041 Reference manual(Rev.4)」 の 「P.110 7.2.1 Port configuration register low」 および 「P.111 7.2.2 Port configuration register high」 参照

 GPIO_InitTypeDef GPIO_InitStruct;
 // GPIOB にクロックを供給
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

 // Pin11 を入力用に設定
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_InitStruct.GPIO_Speed = 0;
 GPIO_Init(GPIOB, &GPIO_InitStruct);

 // Pin10 を出力用に設定
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOB, &GPIO_InitStruct);

2.2.USART3 の設定

同様に APB1 の USART3 を使用する。
「1.MIDIのハードウェア規格」に従って USART を設定します。

 USART_InitTypeDef USART_InitStructure;
 // USART3 にクロックを供給
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

 // USART3 ボーレートなどを設定
 USART_InitStructure.USART_BaudRate = 31250;
 USART_InitStructure.USART_HardwareFlowControl =
   USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // USART3 に設定を反映
 USART_Init(USART3, &USART_InitStructure);
 // USART3 を起動する
 USART_Cmd(USART3, ENABLE);


3.STM32の割り込み


3.1.USART でサポートしている割り込みの種類

  1. CTS が変化(UART4、UART5 以外) - CTS
  2. LIN(Local Interconnect Network) Break を検出 - LBD
  3. 送信データレジスタが空 - TXE
  4. 送信完了 - TC
  5. 受信完了 - RXNE
  6. アイドルラインを受信 - IDLE
  7. オーバーラン エラー - ORE
  8. ノイズ エラー - NE
  9. フレーミング エラー - FE
  10. パリティ エラー - PE
MIDI 入力で関係がありそうなのは、項番5 の「受信完了」割り込みだけです。あとはエラー関連の 7~9 に対応すればよさそうです。ただ、エラー発生時は割り込みを発生させるのではなく、受信完了割り込み時にステータスを確認し、エラーがあれば USART 関連を再初期化して処理を続行するようにしたいと思います。

3.2.データ受信時の流れ


[RM0008] リファレンスマニュアル(Rev.11) P.745 - USARTブロック図より

3.3.データ受信時の処理

  1. 受信シフトレジスタにデータがビット単位で格納されていく(図の①)
  2. 受信が完了(1byte 分のデータが揃う)したら受信データレジスタにデータが転送される(図の②)。
  3. 受信時にエラーが発生した場合はエラー・ビットをセットし、無効なデータを受信データレジスタに転送する(オーバーラン時は転送しない)。
  4. エラーの有無を確認後、受信データレジスタからデータを取り出すと受信データレジスタがクリアされる(図の③)
あとは、1~4の繰り返し。
1~3はUSARTが自動的に処理してくれるので、アプリケーションは4の処理をすれば良い。

受信完了割り込み(RXNE)を有効にしておくと、エラーの有無にかかわらず項番2または3のタイミングで受信完了割り込みが発生するので、ステータス(ORE、NE、FE ビット)を参照しエラーの有無を確認後、受信データレジスタからデータを読み出して処理すればよい。

3.4.エラーの種類と意味

受信時のエラーの有無は USART_GetFlagStatus() 関数で確認できる。エラーの種類は USART_FLAG で指定する。

似たような関数で USART_GetITStatus() があるが、これは割り込み発生時の割り込み理由を調べる関数なのでエラーの有無を確認するには適さないと思います。

オーバーラン エラー(ORE)

受信データレジスタにデータが残っている時に受信シフトレジスタから受信データレジスタに転送しようとした時に発生する。つまり、アプリケーションが受信データレジスタを読みに行く前に次のデータが到着してしまったと言うこと。
このエラーが発生した場合、次のデータを受信した段階で受信シフトレジスタが上書きされデータは失われます。ただし、受信データレジスタの内容はそのまま残っているので、アプリケーションは前のデータを読み取ることは可能。

ノイズ エラー(NE)

スタートビット検出時に読み込みが安定しなかった時に発生する。
このエラーが発生した場合は受信データレジスタに無効なデータが転送される。

フレーミング エラー(FE)

受信時にストップビットが来るべき時に来なかった場合に発生する。
このエラーが発生した場合は受信データレジスタに無効なデータが転送される。
これらのエラーをリセットするためには、USART_ReceiveData() 関数でデータを読み込んで受信データレジスタをクリアする必要があります。

詳細は PDF:[RM0041] Reference manual (Doc ID 16188 Rev 4) P.584 「23.3.3 Receiver」参照

3.5.割り込み設定(NVIC)

どの割り込みを処理するかを設定します。
今回は USART3 に関連する割り込みを使用したいので、NVIC_IRQChannel に USART3_IRQn を指定します。このシンボルは「stm32f10x.h」に定義されています。

割り込み優先順位の設定は、最高(0)にしています。今回のサンプルでは割り込みを一種類しか使用しないので何でも良いのですが、複数の割り込みを処理する場合は優先順位を設定しておくと良いのだと思います。

 NVIC_InitTypeDef NVIC_InitStruct;

 /* USART3 割り込み設定 */
 NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStruct);

3.6.割り込みの許可と禁止

USART3 のどの割り込みに対して処理したいのかを指定します。
今回は「受信完了割り込み(RXNE)」を使用したいので、以下のように許可または禁止を行います。

 // 受信完了割り込みを許可する
 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

 // 受信完了割り込みを禁止する
 USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);

これを利用して・・・
  • MIDI入力の起動 → 受信完了割り込みを許可
  • MIDI入力の停止 → 受信完了割り込みを禁止
・・・を実現しようと思います。

それと、まだ調査中なのですが、受信完了割り込みを禁止した後は「受信データレジスタ」をクリアしておいた方が良さそうです。「受信データレジスタ」にデータが残っていると、次回割り込みを許可した時に残っていたデータの処理が非常に煩雑になりそうな気がしています。
ちなみに、「受信データレジスタ」は USART_ReceiveData() 関数でデータを読むとクリアされます。

3.7.割り込みハンドラー

割り込み発生時に実行したい処理を USART3_IRQHandler() 関数に書きます。
今回はMIDI受信時にデータをリングバッファに格納します。エラーが発生した場合はMIDI入力を停止(UASRT3の割り込みを禁止)し、エラー種別を記録することにします。

void USART3_IRQHandler(void) {
 // エラー発生時はMIDI-INを停止する
 if (USART_GetFlagStatus(USART3, USART_FLAG_ORE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_ORE;
 } else if (USART_GetFlagStatus(USART3, USART_FLAG_NE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_NE;
 } else if (USART_GetFlagStatus(USART3, USART_FLAG_FE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_FE;
 } else if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) {
  // データがセットされていたらリング・バッファーに格納
  g_Ptr_buf_in++;
  g_Ptr_buf_in &= (BUFSIZE - 1);
  g_RxBuf[g_Ptr_buf_in] =
   (uint8_t) USART_ReceiveData(USART3);
 }
}

割り込みハンドラーの関数名は固定で 「startup_stm32f10x_md_vl.c」 で決められています。

4.MIDI入力のサンプル・プログラム

割り込みを使った MIDI 入力に関する調査が終わったので、サンプルを作ります。

4.1.MIDI_IO

メニューから [File]-[New File] で midi_io.c と midi_io.h を作成します。

midi_io.h
#ifndef INCLUDE_GUARD_96528CA6_D624_43c7_A7C9_965CF8B6CE6C
#define INCLUDE_GUARD_96528CA6_D624_43c7_A7C9_965CF8B6CE6C
//-----------------------------------------------
// include
//-----------------------------------------------
#include "stm32f10x_conf.h"
//-----------------------------------------------
// define
//-----------------------------------------------
// MIDI-IN:受信バッファ(リングバッファ)のサイズ
#define BUFSIZE ((int16_t)8)
//-----------------------------------------------
// public functions
//-----------------------------------------------
void midi_io_init(void);
void midi_io_Start(void);
void midi_io_Stop(void);
//-----------------------------------------------
// global variables
//-----------------------------------------------
// リングバッファ(MIDI-IN):出力ポインター
extern uint8_t g_Ptr_buf_in;
// リングバッファ(MIDI-IN):入力ポインター
extern uint8_t g_Ptr_buf_out;
// リングバッファ(MIDI-IN)
extern uint8_t g_RxBuf[];
// MIDI受信エラーフラグ
extern uint16_t g_isMidiReceiveError;

#endif /* INCLUDE_GUARD_96528CA6_D624_43c7_A7C9_965CF8B6CE6C */

midi_io.c
//-----------------------------------------------
// include
//-----------------------------------------------
#include "midi_io.h"
//-----------------------------------------------
// prototype
//-----------------------------------------------
void midi_io_initGPIO(void);
void midi_io_initUART3(void);
void NVIC_Configuration(void);
//-----------------------------------------------
// global variables
//-----------------------------------------------
// @brief リングバッファ(MIDI-IN)入力ポインター
uint8_t g_Ptr_buf_in = 0;
// @brief リングバッファ(MIDI-IN)出力ポインター
uint8_t g_Ptr_buf_out = 0;
// @brief リングバッファ(MIDI-IN)
uint8_t g_RxBuf[BUFSIZE];
// @brief MIDI受信エラーフラグ
uint16_t g_isMidiReceiveError = 0;
//-----------------------------------------------
// public functions
//-----------------------------------------------
// MIDI 初期化
//-----------------------------------------------
void midi_io_init(void) {
 midi_io_initGPIO();
 midi_io_initUART3();
 NVIC_Configuration();
}
//-----------------------------------------------
// MIDI 起動
//-----------------------------------------------
void midi_io_Start(void) {
 g_Ptr_buf_in = 0;
 g_Ptr_buf_out = 0;
 g_isMidiReceiveError = 0;
 // 受信完了割り込みを許可する
 USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
//-----------------------------------------------
// MIDI 停止
//-----------------------------------------------
void midi_io_Stop(void) {
 // 受信完了割り込みを禁止し、MIDI-INを停止する
 USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
 // 受信データレジスタをクリアする
 USART_ReceiveData(USART3);
}
//-----------------------------------------------
// private functions
//-----------------------------------------------
// GPIO(PortB)設定
// MIDI-IN  : PB.11
// MIDI-OUT : PB.10
//-----------------------------------------------
void midi_io_initGPIO(void) {
 GPIO_InitTypeDef GPIO_InitStruct;
 // GPIOB にクロックを供給
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

 // Pin11 を入力用に設定
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_InitStruct.GPIO_Speed = 0;
 GPIO_Init(GPIOB, &GPIO_InitStruct);

 // Pin10 を出力用に設定
 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//-----------------------------------------------
// USART3 設定
//-----------------------------------------------
void midi_io_initUART3(void) {
 USART_InitTypeDef USART_InitStructure;
 // USART3 にクロックを供給
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

 // USART3 ボーレートなどを設定
 USART_InitStructure.USART_BaudRate = 31250;
 USART_InitStructure.USART_HardwareFlowControl =
   USART_HardwareFlowControl_None;
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 USART_InitStructure.USART_Parity = USART_Parity_No;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // USART3 に設定を反映
 USART_Init(USART3, &USART_InitStructure);
 // USART3 を起動する
 USART_Cmd(USART3, ENABLE);
}
//-----------------------------------------------
// 割り込み設定(USART3)
//-----------------------------------------------
void NVIC_Configuration(void) {
 NVIC_InitTypeDef NVIC_InitStruct;

 /* USART3 割り込み設定 */
 NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStruct);
}
//-----------------------------------------------
// Interrupt Service Routine
//-----------------------------------------------
// UASRT3(MIDI)
//-----------------------------------------------
void USART3_IRQHandler(void) {
 // エラー発生時はMIDI-INを停止する
 if (USART_GetFlagStatus(USART3, USART_FLAG_ORE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_ORE;
 } else if (USART_GetFlagStatus(USART3, USART_FLAG_NE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_NE;
 } else if (USART_GetFlagStatus(USART3, USART_FLAG_FE) == SET) {
  midi_io_Stop();
  g_isMidiReceiveError |= USART_FLAG_FE;
 } else if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) {
  // データがセットされていたらリング・バッファーに格納
  g_Ptr_buf_in++;
  g_Ptr_buf_in &= (BUFSIZE - 1);
  g_RxBuf[g_Ptr_buf_in] =
   (uint8_t) USART_ReceiveData(USART3);
 }
}

main.c
#include <stdio.h>
#include "log.h"
#include "midi_io.h"

int main(void) {
    Log_init(ub115200);
    Log_Start();
    printf("MIDI受信テスト\r\n");

    midi_io_init();
    midi_io_Start();

    while (1) {
        if (g_isMidiReceiveError != 0) {
            printf("\r\n");
            printf("MIDI受信エラー:処理をリセットし続行します\r\n");
            // エラー発生時はMIDI-INが停止しているので再起動
            midi_io_Start(); 
        } else if (g_Ptr_buf_in == g_Ptr_buf_out) { // データなし
            continue;
        } else {
            g_Ptr_buf_out++;
            g_Ptr_buf_out &= (BUFSIZE - 1);
            // リングバッファから1バイト取り出し
            if ((g_RxBuf[g_Ptr_buf_out] & (uint8_t) 0x80) != 0) {
                printf("\r\n"); // status バイトの時は改行
            }
            printf("%2X / ", g_RxBuf[g_Ptr_buf_out]);
        }
    }
}

4.2.コンパイル・オプション

このサンプルは以下のコンパイル・オプションを使用しています。
-std=c99; -fno-builtin-printf
-std=c99
CMSIS が ISO C99 準拠なので。

-fno-builtin-printf
GCC の printf() 関数の最適化抑止

5.デバッグ


CoIDE のメニュー[Degug]-[Debug]でプログラムのダウンロードとデバッグを実行する。
MIDI入力のテスト中・・・
ちょうど、USART3 の受信完了割り込みが
発生したところで停止。

6.STM32F4 Discovery への対応

簡単ですが変更箇所だけ書いておきます。

6.1.外部クロックの設定


外部クロック(8MHz) を使用するように設定します。
メニューから[View]-[Confihuration]-[Compileタブ] の Defined Symbols に
HSE_VALUE=8000000
を追加します。

[2013.10.18 追記] クロックの設定が漏れていました。
system_stm32f4xx.c の149行目にある シンボル PLL_M の値を 25 → 8 に変更
#define PLL_M     8
なお、公式サイトに STM32F4 Discovery 用のクロック設定ツール(Excel)が用意されているのでそちらを使用した方が良いと思います。

以下のURLからダウンロードできます。
STSW-STM32091 Clock configuration tool for STM32F40x/41x microcontrollers (AN3988) - STMicroelectronics
http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1533/PF257927

このツールを使用すると system_stm32f4xx.c のソースを自動生成してくれます。
簡単にクロックの設定ができ便利です。

また、Life with Computer さんのページ「CPUメインクロックの変更方法」に詳しい説明があります。MCUは異なりますがとても参考になりました。

6.2.ソースの修正箇所


シンボルはそれぞれ、
STM32F100RB が STM32VL Discovery、
STM32F407VG が STM32F4 Discovery です。

midi_io.h
#ifdef STM32F100RB
#include "stm32f10x_conf.h"
#endif
#ifdef STM32F407VG
#include "stm32f4xx_conf.h"
#endif

midi_io.c
// GPIOB にクロックを供給
#ifdef STM32F100RB
 // UART TX(PB.10) / RX(PB.11)
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
#endif
#ifdef STM32F407VG
 // UART TX(PB.10) / RX(PB.11)
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
#endif

 // Pin10 を出力用に設定
#ifdef STM32F100RB
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
#endif
#ifdef STM32F407VG
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
#endif

 // Pin11 を入力用に設定
#ifdef STM32F100RB
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
#endif
#ifdef STM32F407VG
 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
#endif

#ifdef STM32F407VG
 // GPIOBのPIN11をオルタネィテブファンクションのUSART3に割り当て
 GPIO_PinAFConfig(GPIOB , GPIO_PinSource11 , GPIO_AF_USART3);
#endif

main.c
int main(void) {

 SystemInit();


main()関数の先頭に SystemInit() 関数をコールする行を追加します。
この関数ではシステムクロックの設定を行っています。
これをコールしないとシステムで使用するクロックが適切に設定されません。

STM32VL Discovery の場合はスタートアップ時に「startup_stm32f10x_md_vl.c」内でmain()関数をコールする前に SystemInit() 関数をコールしてくれるのですが、STM32F4 Discovery のスタートアップ「startup_stm32f4xx.c」ではコールされないので処理の先頭で実行する必要があります。

6.3.MIDI受信テスト

これは STM32F4 Discovery を使って受信のテストを行っている様子です。
以前から作成中の MIDIパーサーを組み込んでターミナルに情報を出力しています。
まだ、System Exclusive の処理がバグっているようで、本当は3種類の SysEx を受信しているのにデータがゴッソリ欠落&重複&最後の F7 が・・・バグ取りしなくっちゃ!

バグ取りには CoIDE が役に立ちそう 



CoIDE は今まで使用してきたIDEの中では非常に使いやすいです。やはり、開発環境を簡単に構築でき、新規プロジェクトの作成もウィザードとリポジトリーで手間いらず、標準のドライバーでソースレベル・デバッグができるのが嬉しいです。
あと、気になる点として上げていた、「バージョン管理の仕組みがない」についてですが、以前「SWAS-G/LFOの作成・・・その2」で紹介したソース管理専用の Eclipse に CoIDE のプロジェクトをインポートする方法で対応しました。

あと、ちょっと困っているのは、コンパイルリストを出力できない事です。
これが無いとC言語のソースがどのようにアセンブラに展開されたかがわかりません。
暫定対策としてGCCのコンパイル・オプションに「-S」を付けてアセンブラーのソースを出力する方法がありますが、使い勝手が悪いですよね。
何か良い方法は無いかな?・・・

・・・で、EWICON の製作の方ですが、STM32VL Discovery は I/O の数も多く、メモリーも十分あるのでプログラム作成は楽ですよね。PSoC1 から STM32 に切り替えるのも面白いかも?
でも、PSoC1 は PWM などのペリフェラル数が多いし、アナログのモジュール(DACやフィルター)も使いたいから、PSoC1 と STM32VL Discovery の併用も視野に入れ考えてみようかな・・・

しばらくは CoIDE と PSoC Designer で似たようなことをやりながら、どうするか決めようと思います。

#著作権表示義務のないオープンソースのライセンスって無いかなぁ~

では・・・

このページに掲載したプログラム・ソースは自由に利用していただいて結構です(無保証)。

参考資料
■JIS X6054-1:「電子楽器ディジタルインタフェース (MIDI) -第1部:総則」 P.2 ハードウェア
http://www.jisc.go.jp/app/pager?%23jps.JPSH0090D:JPSO0020:/JPS/JPSO0090.jsp=&RKKNP_vJISJISNO=X6054-1
■[RM0041] Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs
(Doc ID 16188 Rev 4)
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/CD00246267.pdf
■[UM0919] STM32VL Discovery User Manual - STM32VLDISCOVERY - STM32 value line Discovery
(Doc ID 17217 Rev.2)
http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/user_manual/CD00267113.pdf
■[RM0008] リファレンスマニュアル(Rev.11) - 日本語
STM32F101xx、STM32F102xx、STM32F103xx、STM32F105xx、および STM32F107xx 高度 ARM ベース 32 ビット MCU
公式サイトには無いようです。「RM0008 リファレンスマニュアル rev.11」などのキーワードで検索すると出てきます。STM32VL Discovery用ではありませんが日本語ですので非常に参考になります。
■STM32F100RB Datasheet
(Doc ID 16455 Rev 7)
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00251732.pdf
■STM32マイコン徹底入門 - 第9章 同期/非同期シルアル通信 USART (P.247)
http://www.cqpub.co.jp/hanbai/books/49/49861.htm
■STM32F4 Discovery 用のクロック設定ツール(Excel)
STSW-STM32091 Clock configuration tool for STM32F40x/41x microcontrollers (AN3988) - STMicroelectronics http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1533/PF257927
■Life with Computer さん - CPUメインクロックの変更方法
http://www48.atpages.jp/~cent22/Electronics/STM32/ChangeMainClock/changemainclock.html

0 件のコメント:

コメントを投稿