STM32F103のフラッシュにロギングしたデータを保存するプログラムを書いている。
今日嵌ったのが構造体のアライメント、
1Word = 16bitが最低単位のつもりで
struct _DATA{
u32 a;
u16 b,c,d;
};
という構造体を宣言してサイズが10Byteのつもりで
配列を取っていたらFlash領域をはみ出してエラー、
しばらく悩んで構造体のサイズを確認してみたら16Byteになっている。
そうか、32bitCPUのコンパイラはそうなんだ。
と納得。
仕方がないから構造体を使わずにデータを詰めていくことにする。
Oct 22, 2009
Oct 13, 2009
STM32F103のADとDMA機能
その分設定はちょっとややこしいがライブラリの使い方さえ覚えれば簡単、
ADとDMAの設定をするだけで高速の連続取込ができる。
勿論H8などでもDMAは使えるが使い勝手が全然違う
40KHz超音波センサの信号も増幅回路だけでこのように直接ADに
波形がちゃんと取り込める。
この写真は取り込んだデータをテキストで吐き出してグラフ表示させたもの、
今まではコンパレータで閾値を超えたところで
タイマ入力にトリガをかけて時間を計測していたけれど
これなら直接取り込んだデータをソフトで処理できるから色々な可能性が見えてくる。
初期化の部分はこんな感じ。
/*******************************************************************************
* Function Name : ADC1_Config
* Description : DMAを使用、ADCConvertedValue[16] へ連続してAD変換を行う
* 8CH のみ
* Input : None
* Output : None
* Return : None
*******************************************************************************/
static void ADC1_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* System clocks configuration ---------------------------------------------*/
/* Enable peripheral clocks --------------------------------------------------*/
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
// 各ポートを有効にする
// ピン割り当て機能を有効にする
/* NVIC configuration ------------------------------------------------------*/
//NVIC_Configuration();
/* Enable DMA1 channel6 IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* GPIO configuration ------------------------------------------------------*/
/* Configure as analog input -------------------------*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = US_LEFT_PIN; // US-Left, US-Right
GPIO_Init(US_LEFT_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = US_RIGHT_PIN; // US-Left, US-Right
GPIO_Init(US_RIGHT_PORT, &GPIO_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
}
/*******************************************************************************
* Function Name : ADC1_Reset
* Description : ADC1を初期化(Channel0から動作を開始するようにするため)
* 8CH のみ
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void ADC1_Reset(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
ADC_Cmd(ADC1, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC1ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 4000;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 Channel6 Transfer Complete interrupt */
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, US_LEFT_ACH, 1, ADC_SampleTime_1Cycles5); //
ADC_RegularChannelConfig(ADC1, US_RIGHT_ACH, 2, ADC_SampleTime_1Cycles5); //
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
/*******************************************************************************
* Function Name : ADC1_Config
* Description : DMAを使用、ADCConvertedValue[16] へ連続してAD変換を行う
* 8CH のみ
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void ADC1_Start(void)
{
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
Oct 11, 2009
Oct 10, 2009
STM32F10xライブラリ Ver3.x
STM32F10xを使うにはstMicroから提供されているライブラリが便利、
というか、周辺機能が豊富すぎてライブラリを使わないとちんぷんかんぷん。
STM32F103RBTでDMA2を初期化するとそこで暴走してしまうので
ライブラリが悪いのかと思ってライブラリVer2.1からVer3.0に乗り換えてみた。
Ver3のリリース日はVer2とそんなに離れていない割に基本的な構造は大違い。
おかげで既存のソースを対応させるのに丸一日費やしてしまった。
新しいライブラリのスタートアップコードをみていて気がついたのが
RAM容量20KまでのミドルレンジにはDMA2の割り込みベクタが記述されていない
ということはDMA2はないのね。
データシートを眺めてもクラスによる周辺機能の有無はわかりにくかったので
一生懸命、無い機能を使おうとしていたということか、
良い勉強になりました。
ライブラリVer3.0はVer2.0に較べて構成がシンプルでわかりやすいと思う。
というか、周辺機能が豊富すぎてライブラリを使わないとちんぷんかんぷん。
STM32F103RBTでDMA2を初期化するとそこで暴走してしまうので
ライブラリが悪いのかと思ってライブラリVer2.1からVer3.0に乗り換えてみた。
Ver3のリリース日はVer2とそんなに離れていない割に基本的な構造は大違い。
おかげで既存のソースを対応させるのに丸一日費やしてしまった。
新しいライブラリのスタートアップコードをみていて気がついたのが
RAM容量20KまでのミドルレンジにはDMA2の割り込みベクタが記述されていない
ということはDMA2はないのね。
データシートを眺めてもクラスによる周辺機能の有無はわかりにくかったので
一生懸命、無い機能を使おうとしていたということか、
良い勉強になりました。
ライブラリVer3.0はVer2.0に較べて構成がシンプルでわかりやすいと思う。
Oct 9, 2009
ドライブ
すっかり iPhone に嵌っている、
iPhoneで撮った写真の位置をgooglemapで表示するアプリを入手し
画面キャプチャの技を覚えた(HOME+Sleepボタン同時押し)ので
ドライブの写真をiPhoneから発送してみた。
庄原にある道の駅ゆめさくらで美味しいピザを買って、
横にある林で犬たちを遊ばせながらひとやすみ。


広島と島根の県境にあるおろちループのレストランで昼食
ここは景色が素晴らしい&舞茸そばとコーヒーが絶品。

レストランの窓から見える鉄の彫刻、
設置された当初は違和感があったんだけど
最近色が落ち着いたせいか景色になじんで良い感じ。

出雲坂根駅の近くにある水場の川でハナが水遊び


iPhoneから発送
iPhoneで撮った写真の位置をgooglemapで表示するアプリを入手し
画面キャプチャの技を覚えた(HOME+Sleepボタン同時押し)ので
ドライブの写真をiPhoneから発送してみた。
庄原にある道の駅ゆめさくらで美味しいピザを買って、
横にある林で犬たちを遊ばせながらひとやすみ。


広島と島根の県境にあるおろちループのレストランで昼食
ここは景色が素晴らしい&舞茸そばとコーヒーが絶品。

レストランの窓から見える鉄の彫刻、
設置された当初は違和感があったんだけど
最近色が落ち着いたせいか景色になじんで良い感じ。

出雲坂根駅の近くにある水場の川でハナが水遊び


iPhoneから発送
Oct 2, 2009
Sep 26, 2009
Sep 23, 2009
九州旅行記 白鳥温泉前の足湯
Sep 22, 2009
Sep 21, 2009
Sep 20, 2009
May 19, 2009
STM32F103とH8
STM32F103シリーズを使っているとH8シリーズとの設計思想の違いを感じる。
H8シリーズでは無秩序に周辺機能を追加していった結果、系列が少しでも
違うと周辺の初期化ルーチンを大幅に書き直さなければならなかったのに対し
STM32F103ではメモリサイズ、パッケージが違っても多くのソースが共通で
使えるのがありがたい。
もちろん、STM32F103はまだ歴史が浅く品種も少ないがH8は長い歴史の
中で拡張を重ねてきたという違いはある。それでもH8がCPUコアから設計し
周辺も含めてハードウェア技術者の視点から作られているのに対し、STM32Fは
標準のARMコアを利用することが出来たおかげでソフトウェア技術者の
視点で周辺機能の仕様が作られている。だから、プログラムを作るユーザから
みるとSTM32Fシリーズの方が使いやすく思えるのだろう。
一例としてベクタテーブルをRAM上に割り付ける機能をみると
H8ではFlashのRAMエミュレーションという機能を使ってそれが可能だが
ただでさえ小さいRAMの中途半端な場所にしかベクタテーブルを配置
できないのに対し、STM32Fは位置を指定するレジスタによって
RAMの先頭にベクタテーブルを配置できる。
たぶんH8の設計陣の頭には組み込み用のワンチップCPUでは
ブートモニタによってプログラムを書き込み、起動するという使い方など
想定外なのだろう。
しかし組み込み製品のファームウェアを後からアップデートしたい
ときにはUSBやシリアルを通じてアプリケーションプログラムを書き
換えることが出来ると利便性が高くなる。
ルネサスからはブートローダプログラムも提供されているが、これがまた
使いにくい代物で無償で使用する場合は「責任を持ちません」と書いた
赤い字のメッセージが表示されるためユーザにこれをアップデートツールと
して使って貰うことはとてもできないがSTM32F103にはFlash書込み用の
関数がサンプルとして提供されていてそれを使うと簡単にアップデート機能を
持つブートモニタを作ることができてアップデートツールとして不特定多数の
ユーザに提供できる。
H8シリーズでは無秩序に周辺機能を追加していった結果、系列が少しでも
違うと周辺の初期化ルーチンを大幅に書き直さなければならなかったのに対し
STM32F103ではメモリサイズ、パッケージが違っても多くのソースが共通で
使えるのがありがたい。
もちろん、STM32F103はまだ歴史が浅く品種も少ないがH8は長い歴史の
中で拡張を重ねてきたという違いはある。それでもH8がCPUコアから設計し
周辺も含めてハードウェア技術者の視点から作られているのに対し、STM32Fは
標準のARMコアを利用することが出来たおかげでソフトウェア技術者の
視点で周辺機能の仕様が作られている。だから、プログラムを作るユーザから
みるとSTM32Fシリーズの方が使いやすく思えるのだろう。
一例としてベクタテーブルをRAM上に割り付ける機能をみると
H8ではFlashのRAMエミュレーションという機能を使ってそれが可能だが
ただでさえ小さいRAMの中途半端な場所にしかベクタテーブルを配置
できないのに対し、STM32Fは位置を指定するレジスタによって
RAMの先頭にベクタテーブルを配置できる。
たぶんH8の設計陣の頭には組み込み用のワンチップCPUでは
ブートモニタによってプログラムを書き込み、起動するという使い方など
想定外なのだろう。
しかし組み込み製品のファームウェアを後からアップデートしたい
ときにはUSBやシリアルを通じてアプリケーションプログラムを書き
換えることが出来ると利便性が高くなる。
ルネサスからはブートローダプログラムも提供されているが、これがまた
使いにくい代物で無償で使用する場合は「責任を持ちません」と書いた
赤い字のメッセージが表示されるためユーザにこれをアップデートツールと
して使って貰うことはとてもできないがSTM32F103にはFlash書込み用の
関数がサンプルとして提供されていてそれを使うと簡単にアップデート機能を
持つブートモニタを作ることができてアップデートツールとして不特定多数の
ユーザに提供できる。
May 17, 2009
STM32F103のプログラム

雨が降ったので釣りに行かず会社でSTM32F103ZET搭載制御ボード用モニタのデバッグをして遊ぶ。
半分は開発ツールJDEの改良など。
STM32F103ZETはSTM32F103-P52に使っているSTM32F103RBTのメモリがRAM64KB、ROM512KBに拡張されているのと144pinQFPパッケージで外部にメモリや周辺がバス拡張できるところが異なる。
基本部分とUSB周りはSTM32F103-P52のモニタでそのままOK、外部バスにつながった周辺ICのアクセスが今日の課題。
H8に較べて高機能なのでマニュアルを読んで一からプログラムをするのは大変だが、サンプルプログラムが良くできているのでEVAKITのFSMC用サンプルから移植して数行追加して何とか動いた。
AVRのメーカATMELが提供している組み込み用ARMのAT91SAM7Sも良くできているし、ドキュメントもまあまあだが、サンプルプログラムの質はSTMicroに軍配が上がる。
昔熱中したH8シリーズは過去の石になりつつある。
散歩
Apr 24, 2009
IC Imaging Source CAMERA with C++Builder6 & Delphi
ICIMAGINGSOURCE社のUSBカメラを使って画像処理をするために
C#、VC++、C++Builderのどれが使えるかをテストした。
出来ればGUIを簡単に構築できるC++Builderをつかいたいので
カメラ付属のVC専用クラスライブラリを使ってDLLを作り
C++Builderから呼び出そうと苦労したがDLL呼出しの段階で
原因不明のエラーが発生して断念(-.-)
VB用に用意されたActiveXを使えばDelphiからも簡単に
カメラを使えることに気がついてやってみたら、数十分の作業であっけなく成功。
それならと、C++BuilderからActiveXを呼び出してみると原因不明のエラー。
テストの結果プロジェクトオプション>パッケージ>パッケージ再構築の欄で
実行時パッケージを使って構築のチェックを外すとOKなことが判明。
DLL呼出しもたぶんこれでOKだろうがActiveXを使う方が簡単なのでこちらにした。
C++BuilderでICIMAGINGSOURCEのカメラを使う方法
1.コンポーネント>ActiveXの取込で
C:\Program Files\Common Files\IC Imaging Control 3\icimagingcontrol.ocx
を追加してインストール。
2.アプリケーションを新規作成してフォームにICImagingControlコンポーネントを貼り付け
3.カメラをつないでプロパティ Deviceでカメラを選択
4.ボタンを貼り付けて機能を呼び出す
ソースは次のとおり、C++builder だととっても簡単です。
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ICImagingControl3_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
int count=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
ICImagingControl1->LiveStart();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
ICImagingControl1->LiveStop();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ICImagingControl1ImageAvailable(TObject *Sender,
long BufferIndex)
{
Label2->Caption = IntToStr(++count);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
ICImagingControl1->ShowPropertyDialog();
}
//---------------------------------------------------------------------------
Apr 16, 2009
OpenCV with C++Builder6
OpenCV1.1をC++Builder6で使ってみることにした
参考にしたサイト
http://www18.ocn.ne.jp/~amedas/tips/opencv_borland.html
そのままでは make -f make_all_bc.mak が通らなかったので次の2点を修正
1. OpenCV\ml\src\mlsvm.cpp の186行あたりを次のように変更
// error += is_regression ? powf( resp - *(float*)true_resp, 2 )
error += is_regression ? pow( resp - *(float*)true_resp, 2 )
2. OpenCV\otherlibs\_graphics\lib\videoInput.lib をOMF形式に変換
videoInput.lib を _videoInput.lib にリネームしてから
> coff2omf _videoInput.lib videoInput.lib
参考にしたサイト
http://www18.ocn.ne.jp/~amedas/tips/opencv_borland.html
そのままでは make -f make_all_bc.mak が通らなかったので次の2点を修正
1. OpenCV\ml\src\mlsvm.cpp の186行あたりを次のように変更
// error += is_regression ? powf( resp - *(float*)true_resp, 2 )
error += is_regression ? pow( resp - *(float*)true_resp, 2 )
2. OpenCV\otherlibs\_graphics\lib\videoInput.lib をOMF形式に変換
videoInput.lib を _videoInput.lib にリネームしてから
> coff2omf _videoInput.lib videoInput.lib
Subscribe to:
Comments (Atom)































