フォト
2017年4月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
無料ブログはココログ

ARM

2017年4月20日 (木)

次はSTM32ボードを積極的に使ていきたい(15)

移植&機能追加中のBlue Pill用豊四季タイニーBASIC、
コマンド等を追加しました。

豊四季タイニーBASIC for Arduino STM32 V0.7
https://github.com/Tamakichi/ttbasic_arduino/tree/ttbasic_arduino_ps2_ntsc

色々と遊べるようになってきました。

ビットマップ表示



スクロール表示


試しに、簡単な下記のプログラムでIchigoJamとBlue Pillボードで性能比較してみました。

10 FOR I=0 TO 30000
20 A=(12345/67+89)*10
30 NEXT I

;結果次の通りです。

処理にかかった時間(TICK()で測定)
  IchigoJam       84.3秒
  Blue Pillボード  0.8秒
マイコンレベルのスペックでIchigoJamの3倍くらいの性能が出ればいいと思っていたところ、
なんと100倍近い性能!

この理由は、IchigoJamが中間コード形式を採用していないためだと思われます。
IchigoJamが"12345"を30,000回文字列から2バイト整数に変換してから計算するのに対し、
tinyBASICでは、最初に中間コードに変換した状態でプログラムを実行します。
"12345"は実行時に2バイト整数に変換されている状態です。
中間コード変換はかなり、効果があることが分かりました。


Blue Pillボードを使った TinyBASICの構成は次のような感じです。

接続図(クリックで拡大表示します)

02

利用可能市販パーツ
 

2017年4月13日 (木)

次はSTM32ボードを積極的に使ていきたい(14)

豊四季版tiny BASIC をBlue Pill用に移植&機能追加中です。

02

オリジナル版は、シリアル接続で行単位のプログラム入力でしたが、
ビデオ出力とPS/2キーボード対応、フルスクリーンエディタ対応等の機能追加して
IchigoJamのような感じで利用出来るようになってきました。

03

04

グラフィック描画や、GPIOを使った入出力、I2C、シリアル通信、RTC対応等
色々と詰め込中です。

豊四季タイニーBASIC for Arduino STM32 V0.6
https://github.com/Tamakichi/ttbasic_arduino/tree/ttbasic_arduino_ps2_ntsc

2017年4月 9日 (日)

次はSTM32ボードを積極的に使ていきたい(13)

コントローラーにILI9341を使った液晶モジュールの動作確認
メモしておかないと結線忘れるので記録に残しておきます。

Dscn6523


Arduino STM32にはILI9341を使った液晶モジュールを使うためのライブラリが用意されています。

ライブラリ
   Adafruit_GFX_AS         Adafruit GFX Graphics Library(Arduino版の修正版 _ASが付く)
   Adafruit_ILI9341_STM   ILI9341搭載液晶モジュールコントローラ

ライブラリのサンプルスケッチを使って、手持ちのILI9341搭載液晶モジュールを
動作させてみました(SDカード、タッチパネルも使えるのですが今回は表示のみです)。


  接続(クリックすると拡大表示します)

01


サンプルスケッチはそのままでは動かす、ピン割り付け部分の修正が必要です。
下記のように接続しました。CS、RESET、D/Cは任意のピンが利用出来ます。
SPI接続のピンA5,A6,A7は変更できません。

    02


graphicstest.inoの修正箇所

#include "SPI.h"
#include "Adafruit_GFX_AS.h"
#include "Adafruit_ILI9341_STM.h"

#define TFT_CS  PA0                  
#define TFT_RST PA1
#define TFT_DC  PA2

            
//Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC);
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  Serial.begin(115200);
  delay(3000);
  Serial.println("ILI9341 Test!"); 
 
  tft.begin();

RESETをBlue Pillのリセットと連動させる場合はBlue PillのRSTへの接続でもOkです。
その場合は、TFT_RSTを-1にするか、コメントアウトしているコンストラクタの方を
利用して初期化します。

Adafruit GFX Graphics Libraryを使って自分で好きなように動かしたい場合は、
Adafruitのサイトの公開情報が参考になります。
  ・Adafruit GFX Graphics Library
   https://learn.adafruit.com/adafruit-gfx-graphics-library/

Arduino STM32に付属しているAdafruit GFX Graphics Libraryは、フォントが削られているので、
上記リンクからライブラリをダウンロードしてフォントだけコピーしたほうがよいかも。
(訂正) Arduino Stm32版では、setFont()が削られていて使えないようです。

Arduino UNOに比べると描画速度が非常に速いです。
Arduino UNOではSPIのクロックが8MHzなのに対して、Blue Pillはで36MHzです。

次のYoutubeの動画によると、Arduino Unoの12倍の速度で描画出来るようです。
 
   Generic STM32 vs Arduino Pro Mini/Nano speed comparison
   

2017年4月 4日 (火)

Arduino IDEでのchar型の変数の振舞

最近のArduino IDEでは従来のAVRマイコンほ他に、ARM系のボードもサポートしています。
スケッチもある程度、他のマイコンボードへの流用が出来ます。

私もAVR系のArduino UnoのスケッチをSTM32のボードに流用したりするのですが、

動作が異なる不可解な現象が発生し、ちょっとハマりました。

色々と突き詰めていくと、
AVRマイコンとARMマイコンではchar型の扱いが異なることが判明しました。
次のスケッチはchar型の変数aに-1を格納して表示する例です。
void setup() {
  Serial.begin(115200);

  char a;
  a= -1;
  Serial.print("a=");
  Serial.println(a,DEC);
  Serial.print("-1=");
  Serial.println(-1,DEC);

}

void loop() {

}

Arduino UNOの実行結果   Arduino Duo、M0、Bulle Pillボードの実行結果

Arduino          Arduinom0

if 文判定でも差異は明確に現れました。

まあ、char型の変数にマイナス値を使うようなプログラムはあまりないですが、
先日、ゲームの移植でちょっとハマってしまいました。

同じ開発環境でこの不統一はちょっとやめてほしいなぁ

char型についてはちょっと気を付ける必要があります。
私は、int8_t、uint8_tとC99的に記述しています。

2017年3月30日 (木)

次はSTM32ボードを積極的に使ていきたい(12)

Bule Pillボード(STM32F103C8T6)の内部RTCを使った時刻表示

スケッチ

//
// FILE: stm_RTC_sample.ino
// Arduino STM32 内部RTCを利用して時刻を表示する
// 作成日 2017/03/30 by たま吉さん
//

#include <RTClock.h>
#include <time.h>

RTClock rtc(RTCSEL_LSE);
char *wday[] = {"Sun","Mon","Tue","Wed","Thr","Fri","Sat"};

// セットアップ
void setup() {
  struct tm t;  
  Serial.begin(115200);
     while (!Serial.isConnected()) delay(100);

  t.tm_isdst = 0;             // サーマータイム [1:あり 、0:なし]
  t.tm_year  = 2017-1900;     // 年   [1900からの経過年数]
  t.tm_mon   = 3-1;           // 月   [0-11] 0から始まることに注意
  t.tm_mday  = 30;            // 日   [1-31]
  t.tm_wday  = 4;             // 曜日 [0:日 1:月 2:火 3:水 4:木 5:金 6:土]
  t.tm_hour  = 22;            // 時   [0-23]
  t.tm_min   = 10;            // 分   [0-59]  
  t.tm_sec   = 0;             // 秒   [0-61] うるう秒考慮
  rtc.setTime(&t); // 時刻の設定
}

void loop() {
   time_t tt; 
   struct tm* st;
   char str[64];

   tt = rtc.getTime();   // 時刻取得
   st = localtime(&tt);  // 時刻型変換
    
   sprintf(str, "%04d/%02d/%02d [%s] %02d:%02d:%02d",
      st->tm_year+1900,   // 西暦年
      st->tm_mon+1,       // 月
      st->tm_mday,        // 日
      wday[st->tm_wday],  // 曜日
      st->tm_hour,        // 時
      st->tm_min,         // 分
      st->tm_sec          // 秒
   );
   Serial.println(str);
   delay(1000);
}

実行結果

01


Blue Pillボードでは動作しますが、Black Pillボードでは動作しませんでした。
動かすとフリーズします。


2017/04/01 追記

Black Pillボードでも動作するようです。
SNSにて上記プログラムが動作することを確認して頂きました。
私の持っているBlack Pillボードが調子悪い(不良)みたです。


2017年3月23日 (木)

次はSTM32ボードを積極的に使ていきたい(11)

Blue PillでIchigoJamのような、BASICインタプリタを動かしたいと思い、
vintagechipsさんが公開している豊四季タイニーBASICを動かしてみました。

関連情報
   ・電脳伝説 Vintagechips - 豊四季タイニーBASIC確定版

シンプルなプログラムでいい感じです。
対話型 BASICインタプリタの売り、「トライ&RUN」を行うには編集機能がちょっと弱いです。
そこで、IchigoJamのような感じでプログラム入力が出来るよう、ちょっと機能追加しました。

動画はtinyBASIC 起動直後の表示メッセージに行番号とPRINT文付けて
プログラム化してしまう操作デモです。
フルスクリーン編集対応しているからこそ出来る操作です。


MCURSESを使って手を加えただけで、結構イケてる環境にビフォー&アフターしました。
MCURSESスバラシイ..

スクリーン制御が出来ると凝ったプログラムが作れますね。
次のコマンドを追加しました。

CLS,LOCATE,COLOR,ATTR,WAIT

02_2

こんな感じで指定した位置の文字を色を付けて表示出来ます。

修正版を下記にて公開します

・Tamakichi/ttbasic_arduino 豊四季タイニーBASIC for Arduino 修正版 V0.1
  https://github.com/Tamakichi/ttbasic_arduino
まだまだ、ガンガン修正していきます.

Blue Pillでは、USBでのシリアル接続での利用となります。
Arduino MEGAでも動作しました。Arduno UNOはメモリ不足で動きません。

01_2

2017年3月16日 (木)

次はSTM32ボードを積極的に使ていきたい(10)

Blue Pillボードのフラッシュメモリの容量の確認

Blue PillボードにはARMマイコン STM32F103C8が搭載されています。

STM32F103C8は、公式にはフラッシュメモリ容量は64kバイトなのですが、
実際には128kバイトのものが流通しているとのことです。

実際にどうなのか、ちょっと確かめてしました。
まずは、搭載マイコンの刻印のチェック



STM32F103C8T6」と明記されています。

データシートにより、このマイコンのフラッシュメモリサイズは64kバイトのはずです。

03

次に、実際にフラッシュメモリサイズを128kバイトと仮定して、
その領域の最終領域のアドレス 0x801FC00 に書き込みを行ってみました。
フラッシュメモリはページ単位(1kバイト)で消去、16ビット単位で書き込みが出来ます。

04

書き込み確認用スケッチ

特定の文字列をフラッシュメモリ上の指定アドレスに書き込んで、その内容を
確認するプログラムです。
64kバイト目のページと128kバイト目のページに異なる文字列を書きこんで、
シリアル接続にて内容を確認します。

//
// FILE stm31_testFlash
// フラッシュメモリ書き込みテスト for Arduino STM32
// 作成日 2017/03/16 by たま吉さん
//

#define FLASH_PAGE_SIZE        1024
#define FLASH_START_ADDRESS    ((uint32)(0x8000000))

#include <string.h>
#include "stm32_hexedit.h"
#include "TFlash.h"

uint8_t str1[] = "1234567890A";
uint8_t str2[] = "abcdefghij";

void Arduino_putchar(uint8_t c) {
  Serial.write(c);
}

char Arduino_getchar() {
  char c;
  while (!Serial.available());
  return Serial.read();
}

uint32_t adr0 = FLASH_START_ADDRESS + FLASH_PAGE_SIZE *  63;
uint32_t adr1 = FLASH_START_ADDRESS + FLASH_PAGE_SIZE *  127;

void setup() {
  Serial.begin(115200);
  while (!Serial.isConnected()) delay(100);
  setFunction_putchar(Arduino_putchar); 
  setFunction_getchar(Arduino_getchar); 
  initscr();

  // フラッシュメモリ書き込みテスト
  TFlash.unlock();
  TFlash.eracePage(adr0);
  TFlash.write((uint16_t*)adr0, str1, strlen((char*)str1));
  TFlash.eracePage(adr1);
  TFlash.write((uint16_t*)adr1, str2, strlen((char*)str2));
  TFlash.lock();
}

void loop() {
  // 64kバイトフラッシュメモリ最終ページの参照
  clear();
  hexedit2 (adr0, false);

  // 128kバイトフラッシュメモリ最終ページの参照
  clear();
  hexedit2 (adr1, false);  
}

スケッチを実行して確認すると、64kバイト目のページ、128kバイト目のページに
それぞれちゃんと書き込めていました。

ページ63、64kバイト目のページへの書込みの確認

06

ページ127、128kバイト目のページへの書込みの確認

05

ということで、STM32F103C8T6 ですが128kバイト利用出来ます。
ただし、生産ロット・時期により64kバイトの可能性もあります。

動作確認で利用した、フラッシュメモリ書き込みは色々と使えそうなので
ライブラリ化しました。

   ・Arduino STM32用 内部フラッシュメモリ書き込みライブラリ
     https://github.com/Tamakichi/ArduinoSTM32_TFlash

     まだ、ドキュメント等は未作成です。

     動作確認したスケッチはそのまま、ライブラリのサンプルとして入れています。
     別途、mcursesライブラリ(https://github.com/ChrisMicro/mcurses)が必要です。

 

2017年3月14日 (火)

次はSTM32ボードを積極的に使ていきたい(9)

TVoutライブラリと互換性の高いライブラリ

「次はSTM32ボードを積極的に使ていきたい(7)」で作成した、
「Arduino STM32用 NTSCビデオ出力ラブラリ」の上位層のライブラリを作成しました。

Arduino用のTVoutライブラリと互換性の高いAPIを実装しました。
TVoutのソースの一部を利用しています。

02

GitHubの方に登録&公開しました。
  ・Arduino STM32 TVoutライブラリ - TTVout
   https://github.com/Tamakichi/ArduinoSTM32_TVout


サンプルスケッチの動作の様子です
(だだし、古いバージョンのものです)




回路図(接続図)は次のような感じとなります。

01
使い方等については、公開ページの説明を参照願います。


ライブラリの実装において、ARM cortex-M3のビットバンド機能を使ってみました。
メモリ上のデータをビット単位で効率よく操作する仕組みです。

具体的には、1ビット毎にワードアドレス(32ビット)を割り付け、
そのアドレスへの読み書きでビット単位の読み書きが出来る仕組みです。

ビット操作を行うドット描画部分関数sp()に適用しました。
このsp()は、直線や円等の描画にも利用しています。
以下がその関数の実装部分です。

//
// ドット描画
// 引数
//  x:横座標
//  y:縦座標
//  c:色 0:黒 1:白 それ以外:反転
//
static void inline sp(uint16_t x, uint16_t y, uint8_t c) {
#if BITBAND==1
  if (c==1)
    _adr[_width*y+ (x&0xf8) +7 -(x&7)] = 1;
  else if (c==0)
    _adr[_width*y+ (x&0xf8) +7 -(x&7)] = 0;
  else 
    _adr[_width*y+ (x&0xf8) +7 -(x&7)] ^= 1;
#else
  if (c==1)
    _screen[(x/8) + (y*_hres)] |= 0x80 >> (x&7);
  else if (c==0)
    _screen[(x/8) + (y*_hres)] &= ~0x80 >> (x&7);
  else
    _screen[(x/8) + (y*_hres)] ^= 0x80 >> (x&7);
#endif
}

BITBANDが1の場合、ビットバンドを利用してフレームバッファのビットを操作します。
BITBANDが1でない場合は、ビットバンドを利用しません。かわりにビットシフト等にて
ビット操作を行います。

上記ソースでビットバンドを利用している場合と利用していない場合で
フレームバッファのアドレスが_adr、_screenといった具合に異なるのは、ビットバンドでの
アドレス操作が32バイト単位のため、型変換とアドレス変換を行っているためです。
    _adr = (volatile uint32_t*)(BB_SRAM_BASE + ((uint32_t)_screen - BB_SRAM_REF) * 32);

画面224x216ドットを1点ずつ点を描画して全面白色処理を行った場合、
ビットバンド機能を利用すると、全体で10%くらいパフォーマンスが向上しました。
10%は大きいです。

このビットバンド機能、ARMでもCortex-M3、Cortex-M4しかないようです。

2017年3月12日 (日)

次はSTM32ボードを積極的に使ていきたい(8)

Arduino STM32環境 Blue PillボードでPWMを使った単音演奏

01

Blue Pillボード(STM32F103C8)でPWMを使った「こいのぼり」の単音演奏をやってみました。
音の出力には圧電スピーカー(圧電サウンダ)を使いました。
ゲームなんかの効果音には使えますね。

演奏の様子
(ちょっと音が小さいです)


回路図

02

スケッチ

「こいのぼり」の演奏部分はスイッチサイエンスさんのサンプルスケッチを流用させていただきました。
SWICHI SCIENCE MAGAZINE - Arduinoで童謡「鯉のぼり」を流してみよう

/*
 *  Arduino STN32
 *  Stm32ボード(STM32F103C8T6)で PWMで任意の周波数を生成する
 *  作成日 2017/01/17 by たま吉さん

 *  説明
 *  ・PB9端子の圧電スピーカーを接続することで任意の周波数を音を出す
 *  ・Timer4 チャンネル 4 を利用しているため、PWM出力ピンはPB9固定

 *  参考にした情報
 *  ・Topic: DUE PWM Frequency (Read 51962 times) 
 *    https://forum.arduino.cc/index.php?topic=131323.15
 *    
 *  サンプル作成に参考にしたサイト
 *  ・Arduinoで童謡「鯉のぼり」を流してみよう
 *    http://mag.switch-science.com/2015/04/29/gwprojact_koinobori/
 */

//
// 音出し
// 引数
//  pin     : PWM出力ピン (現状はPB9固定)
//  freq    : 出力周波数 (Hz) 15~ 50000
//  duration: 出力時間(msec)
//
const int pwmOutPin = PB9;  // PWM出力ピン
void _tone(uint8_t pin, uint16_t freq, uint16_t duration = 0) {
  if (freq < 15 || freq > 50000 ) {
     _notone(pin);
  } else {
    uint32_t f =1000000/(uint16_t)freq;
    Timer4.setPrescaleFactor(72); // システムクロックを1/72に分周
    Timer4.setOverflow(f);
    Timer4.refresh();
    Timer4.resume(); 
    pwmWrite(pin, f/2);  
    if (duration) {
      delay(duration);
      Timer4.pause(); 
    }
  }
}

//
// 音の停止
// 引数
// pin     : PWM出力ピン (現状はPB9固定)
//
void _notone(uint8_t pin) {
    Timer4.pause();  
}

//HardwareTimer pwmtimer(2);
#define PIN pwmOutPin
void setup() {  
  pinMode(pwmOutPin, PWM);
  _tone(pwmOutPin,440, 100);
  _tone(pwmOutPin,880,100);  
  delay(500);

  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 294, 150);
  delay(150);
  _tone(PIN, 262, 300);
  delay(300);
  _tone(PIN, 294, 300);
  delay(300);
  _tone(PIN, 330, 300);
  delay(300);
  _tone(PIN, 440, 300);
  delay(300);
  _tone(PIN, 392, 150);
  delay(300);
  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 330, 150);
  delay(150);
  _tone(PIN, 330, 300);
  delay(300);
  _tone(PIN, 294, 150);
  delay(150);
  _tone(PIN, 262, 150);
  delay(150);
  _tone(PIN, 294, 300);
}

void loop() {
  
}


Arduino STM32では音を出すためのAPIとしてtone()関数があります。
  参考:  ・Arduino for STM32 - tone() and notone() have been added to the libmaple core

使ってみると音がちょっと汚いです。濁ったような音です。
原因はタイマー割り込みを使って、出力をオン・オフしているためです。
他の様々な割り込みの影響により、タイミングがずれたりして濁った音になっています。
(USBシリアル、SysTicの時間処理等)

また、このやり方だとCPU負荷もそれなりにかかります。
今後のビデオ出力を使ったゲーム作成なんかに使うにはちょと問題ありです。

そこで、PWM出力に置き換えて綺麗な音が出るようにしました。
音が出ている間はCPU負荷がかかりません。

問題点としては、利用するピンが固定となることです。標準のtone()では任意のピン
を使って音が出せます。

2017年2月28日 (火)

次はSTM32ボードを積極的に使ていきたい(7)

「次はSTM32ボードを積極的に使ていきたい(5)」でやったNTSCビデオ出力を改良しました。
水平同期パルス、垂直同期パルスをPWM出力を使って実装しました。
これで、利用する割り込み処理を少し減らせました。

02

画面は縦を192ドットから216ドットに広げました。 

03

同期信号はPWM出力に変更したため、利用ピンをA1に変更しました。

01

このNTSCビデオ出力はライブラリ化して、GitHubの方に登録&公開しました。
  ・Arduino STM32用 NTSCビデオ出力ラブラリ
   https://github.com/Tamakichi/ArduinoSTM32_TNTSC

ただし、このライブラリはフレームバッファ内のデータをただ表示するだけの機能しかありません。
別途描画処理を行う上位のライブラリが必要となります。 


2017/03/03 追記

画面解像度を5パターン対応しました。

https://github.com/Tamakichi/ArduinoSTM32_TNTSC の公開版は
V2.2にバージョンアップしました。

02

添付のサンプルスケッチも差し換えました。
画面解像度を動的に変更します。

05

04