Category : FM3
こんばんは!
夜が冷えるようになったせいか、今朝、猛烈な腹痛に襲われたゆってぃです(涙)

さて、今日は前回に引き続きXBeeネタです。
前回は、マイコン側からPC側への通信を行いました。
今回は、PCからマイコン側にデータを送ってみましょう。

PC側は、我らがTeraTerm様があれば準備完了なので、いつものようにマイコン側のソースコードを書いていきます。
なお、今回も前回同様FIFOやフロー制御は使用しませんが、受信部は割り込みで制御します。
これは、受信に関してはいつPC側からデータが来るのかわからないためです。

それでは、前回のコードと大半は重複しますが、おさらいの意味もかねてuart_ctrl.hとuart_ctrl.cを記載します。

と、そのまえに・・・

このソフトのデバッグ中、つまらないミスにハマってしまいました。。。
よくあるミスなので、自戒の念をこめてここに書かせていただきます。

僕は開発環境にIARのEWARMを、ICEはj-link使用しています。
このIDEは他の一般的な製品同様、ペリフェラルレジスタの中身をIDE上で簡単に確認・編集することが出来ます。
つまり、受信レジスタであるRDRの中身も覗けてしまいます。
するとね、マイコンはデータが取り出されたと判断して、RDRFをクリアしてしまいますたぶん!!(汗)

これはその時のIDEのスクリーンショットですが、受信割り込みが発生してハンドラが呼ばれているのでも関わらず、レジスタエディタ内のRDRFは0クリアされていることがわかります。

ブレーク

この様に、例えば受信割り込みハンドラ内でブレークを貼って、開発環境側でRDRの中を確認してしまうと、その後の処理がうまくいかなかったりします。
(このスクリーンショットの例では、if文内の処理が実行されません)
これは、レジスタエディタを開いていなければ起こらない現象ですので、皆さんもデバッグの際は注意しましょう。
(ROMに焼くと動くけど、デバッグ中にブレーク張るとうまく動かない…という現象の典型的な例です。たぶん)

では、話をソースへ戻します。
なお、赤字で書かれた箇所が、前回からの追加部分です。



//-----
uart_ctrl.h
//------------



#ifndef __UART_CTRL_H
#define __UART_CTRL_H

#ifdef __cplusplus
extern "C" {
#endif

#include "typedefine.h"

#define XB24_UART_REG (FM3_MFS0_UART)

//------------------
//UART制御クラス
//-----------------------------
typedef struct UART_CTRL{

BOOL isMethodInitialized; //関数の初期化判別フラグ

BOOL (*initUartReg)(struct UART_CTRL *pUC); //UART関連のレジスタ初期化
BOOL (*writeUartData)(struct UART_CTRL *pUC, UINT8 *data, UINT32 size);
BOOL (*readUartData)(struct UART_CTRL *pUC, UINT8 *data);

}UART_CTRL;

extern UART_CTRL* initUartCtrl(void);

#ifdef __cplusplus
}
#endif


#endif



//-----
uart_ctrl.c
//------------



#include "mcu.h"

#include "typedefine.h"
#include "uart_ctrl.h"
#include "timer.h"

static BOOL INIT_UART_REG(UART_CTRL *pUC);
static BOOL WRITE_UART_DATA(UART_CTRL *pUC, UINT8 *data, UINT32 size);
static BOOL READ_UART_DATA(UART_CTRL *pUC, UINT8 *data);

static UART_CTRL instance_uart_ctrl;

extern UART_CTRL* initUartCtrl(){

if(!instance_uart_ctrl.isMethodInitialized){
instance_uart_ctrl.isMethodInitialized = TRUE;
instance_uart_ctrl.initUartReg = INIT_UART_REG;
instance_uart_ctrl.writeUartData = WRITE_UART_DATA;
instance_uart_ctrl.readUartData = READ_UART_DATA;
}

return &instance_uart_ctrl;

}

/*
* レジスタ設定
*/
static BOOL INIT_UART_REG(UART_CTRL *pUC){

BOOL ret = FALSE;

//端子設定
FM3_GPIO->ADE_f.AN31 = 0; //SOT0_0
FM3_GPIO->PFR2_f.P1 = 1; //SIN0_0
FM3_GPIO->PFR2_f.P2 = 1; //SOT0_0
FM3_GPIO->EPFR07 |= 0x00000050; //リロケート設定

//割り込み禁止
XB24_UART_REG->SCR_f.RIE = 0;
XB24_UART_REG->SCR_f.TIE = 0;
XB24_UART_REG->SCR_f.TBIE = 0;

//送受信禁止
XB24_UART_REG->SCR_f.RXE = 0;
XB24_UART_REG->SCR_f.TXE = 0;

//内部状態初期化(プログラマブルクリア)
XB24_UART_REG->SCR_f.UPCL = 1;

//------ SMR Setting ------//
// 動作モード設定(UART NORMAL)
// WAKE UP OFF
// STOP bit : 1 bit (ESBL = 0)
// LSBファースト
// 出力禁止
//--------------------------------//

XB24_UART_REG->SMR &= 0x00;

//------ SSR Setting ------//
// 受信エラーフラグ クリア
//--------------------------------//

XB24_UART_REG->SSR |= 0x80;

//------ ESCR Setting ------//
// ハードウェアフロー制御禁止(とりあえず)
// STOP bit : 1 bit (SBL = 0)
// NRZフォーマット
// パリティ禁止(とりあえず)
// データ長 = 8 bit
//--------------------------------//

XB24_UART_REG->ESCR &= 0x00;

//------ BGR1 BGR0 Setting ------//
// 内部クロック使用
// ボーレートは9600Hzに設定(とりあえず)@ Main = 144MHz, バスクロック = 36MHz
// リロード値:3750(0x0ea5)
//--------------------------------//

XB24_UART_REG->BGR1 = 0x0e;
XB24_UART_REG->BGR0 = 0xa5;

//受信許可(割り込み許可)
XB24_UART_REG->SCR |= 0x12;

//割り込み許可
NVIC_EnableIRQ(MFS0RX_IRQn);


ret = TRUE;

return ret;

}

/*
* 送信
*/
static BOOL WRITE_UART_DATA(UART_CTRL *pUC, UINT8 *data, UINT32 size){

BOOL ret = FALSE;
UINT8 buf;
int i;


XB24_UART_REG->SMR_f.SOE = 1;
XB24_UART_REG->SCR_f.TXE = 1;

TimerWait(10); //相手側の準備待ち

for(i=0;i < size;i++){

buf = *data;

while(XB24_UART_REG->SSR_f.TDRE == 0);

XB24_UART_REG->TDR = buf;

while(XB24_UART_REG->SSR_f.TBI == 0);

data++;

}

XB24_UART_REG->SCR_f.TXE = 0;
XB24_UART_REG->SMR_f.SOE = 0;

ret = TRUE;

return ret;

}

/*
* 受信
*/
static BOOL READ_UART_DATA(UART_CTRL *pUC, UINT8 *data){

BOOL ret = FALSE;


if( XB24_UART_REG->SSR_f.PE || XB24_UART_REG->SSR_f.FRE || XB24_UART_REG->SSR_f.ORE ){
//[TODO]エラー処理
XB24_UART_REG->SSR |= 0x80;
}else{

*data = XB24_UART_REG->RDR;

ret = TRUE;
}


return ret;

}




データを受信するだけではつまらなかったので、今回、受信データによってLEDの輝度を変えるような実装を行いました。
ASCIIコードで'a'を受信するとLEDを明るく、's'を受信すると暗くし、現在のPWMのDUTYをPC側に返してみました。
(ついでにLCDにも表示しています)



#include "mcu.h"

#include "pwm_ctrl.h"
#include "lcd.h"
#include "timer.h"
#include "uart_ctrl.h"

static UART_CTRL *pUC;
static PWM_CTRL *pPC;

int main()
{

pUC = initUartCtrl();
pUC->initUartReg(pUC);

pPC = initPwmCtrl(0x0fff, 0x00ff);
pPC->initPwmReg(pPC);
pPC->startPwmOutput();

initDisp();
printUpLine("XBee Test");

while(1);


return 0;
}

void MFS0RX_IRQHandler(){

UINT8 str[16] = {0};
UINT8 TxMsg[14] = "BRIGHTNESS = ";
UINT8 brightness[7] = {0};
UINT8 data;

pUC = initUartCtrl();

if(XB24_UART_REG->SSR_f.RDRF){
pUC->readUartData(pUC,&data);

printLowLine(&data);

if(data == 'a'){
if(pPC->mDuty < 0x0fff){
UINT16 duty = pPC->mDuty + 0x000f;
pPC->changeDuty(pPC, duty);
}
}else if(data == 's'){
if(pPC->mDuty > 0x0001){
UINT16 duty = pPC->mDuty - 0x000f;
pPC->changeDuty(pPC, duty);
}
}
sprintf(brightness,"%x\r\n",pPC->mDuty);
pUC->writeUartData(pUC,TxMsg,sizeof(TxMsg));
pUC->writeUartData(pUC,brightness,sizeof(brightness));
sprintf(str,"BRIGHTNESS:%x ",pPC->mDuty);
printLowLine(str);
}

}




無事に、TeraTerm上から明るさを変更し、そのときの明るさをターミナル上に表示することが出来ました。
ターミナル上の表示はこんな感じです。

BRIGHTNESS


マイコン側はこんな感じ。

XBee2


全然大したことはやっていないのですが、やはり無線でモノが動かせるとテンションあがりますね!(笑)

せっかく5000円出して買ったXBeeなので、これからも遊んでみたいと思います^ ^

最後までお読みいただいて、ありがとうございました!(感謝)
スポンサーサイト
こんばんは!
最近、車を買ってしまったゆってぃです!
(色々悩んだ末、結局フィットですけど…)

納車が楽しみです^ ^


話は変わりますが…


本ブログも、ついに累計10000アクセスを突破しました!

皆様、本当にありがとうございます!
皆様が懲りずにご覧になって下さるお陰で、僕自身も今まで書き続けてくることが出来ました。

有益な情報はほとんど書かれておりませんが、これからもご支援のほどをよろしくお願いいたしますm(_ _)m


さて、タイトルにもあるとおり、本ブログもいよいよ無線通信に手を出してしまいます!
満を持してといったところでしょうか?(本当か??)
(ごめんなさい。。。PWMは別の何かと組み合わせて記事を書きます)

XBeeとは、超お手軽に使える無線モジュールです。
モジュールのインターフェースはUARTなので、GNDとTX及びRXさえ接続すれば、PCからもマイコンからも、簡単に制御することが出来ます。
モジュールで技適も取得済みなので、電波法を気にする必要もありません。

という訳で、早速自作のFM3拡張ボードに接続してみました。
と言っても、もうボード上にスペースが無かったので、ちょっとカッコ悪いですが無理やりくっつけてみました。

FM3側XBeeモジュール

PC側に至っては、もはやブレッドボードです。。。
PC側XBeeモジュール


無線通信と言えば聞こえは良いですが、実際はXBeeモジュールとUARTで通信しているに過ぎません。
XBee本体に必要になる面倒くさい設定は、X-CTUというツールで、GUIベースで行うことが出来ます。
X-CTUはここからダウンロード可能です。
(Diagnostics, Utilities and MIBsって書かれてるとこにあります)
64bitOSはサポート外らしいですが、僕のWin7(64bit)上では問題なく動いているようです。

ただ、このツール、ダウンロード中に最新バージョンのダウンロードを促す画面が出てきます。
これが、ものっすごい時間がかかります。
ですが、これを乗り切らないと(少なくとも僕の買った)XBeeZBモジュールは、設定が出来ませんでした。

あと、これはZBタイプだけなのかもしれませんが、X-CTUの設定画面でMY-16-bit NetworkAddressが編集できませんでした。
そのため、Destination Addressは、モジュールの裏に書いてあるシリアルで指定するようです。
なんか他にも色々設定できる項目があるようですが、とりあえず触らぬ神に祟り無しということで、全然触っていません(笑)

とりあえず手元のボードで「マイコン → PC」という一方通行のデータ転送には成功しました。
ですので、今日はそこまでのコードを公開します。

まずは、UART通信を行うためのUART_CTRLクラスを定義します。
なお、ここでは最小限の通信しか行いませんので、皆さんで必要に応じて改良してくださいね^ ^
(そもそも一方通行という時点で不完全…。UARTもwriteしか作って無いです。FIFOも使って無いです(汗))

以下に、uart_ctrl.huart_ctrl.cの2つのコードを掲載します。
まずはuart_ctrl.hから!

因みに、開発環境はIARのEWARM ver6.30の評価版(コードサイズ制限版)です。




//----uart_ctrl.h-------//

#ifndef __UART_CTRL_H
#define __UART_CTRL_H

#ifdef __cplusplus
extern "C" {
#endif

#include "typedefine.h"

#define XB24_UART_REG (FM3_MFS0_UART)

//------------------
//UART制御クラス
//-----------------------------
typedef struct UART_CTRL{

BOOL isMethodInitialized; //関数の初期化判別フラグ

BOOL (*initUartReg)(struct UART_CTRL *pUC); //UART関連のレジスタ初期化
BOOL (*writeUartData)(struct UART_CTRL *pUC, UINT8 *data, UINT32 size);

}UART_CTRL;

extern UART_CTRL* initUartCtrl(void);

#ifdef __cplusplus
}
#endif


#endif



typedefine.hは、単に変数名を再定義しただけのヘッダですので、気にしないで下さい(笑)
つぎに、メソッドを定義したuart_ctrl.cです。



//----uart_ctrl.c-------//

#include "mcu.h"

#include "typedefine.h"
#include "uart_ctrl.h"
#include "timer.h"

static BOOL INIT_UART_REG();
static BOOL WRITE_UART_DATA(UART_CTRL *pUC, UINT8 *data, UINT32 size);

static UART_CTRL instance_uart_ctrl;

extern UART_CTRL* initUartCtrl(){

if(!instance_uart_ctrl.isMethodInitialized){
instance_uart_ctrl.isMethodInitialized = TRUE;
instance_uart_ctrl.initUartReg = INIT_UART_REG;
instance_uart_ctrl.writeUartData = WRITE_UART_DATA;
}

return &instance_uart_ctrl;

}

/*
* レジスタ設定
*/
static BOOL INIT_UART_REG(UART_CTRL *pUC){

BOOL isOk = FALSE;

//端子設定
FM3_GPIO->ADE_f.AN31 = 0; //SOT0_0
FM3_GPIO->PFR2_f.P1 = 1; //SIN0_0
FM3_GPIO->PFR2_f.P2 = 1; //SOT0_0
FM3_GPIO->EPFR07 |= 0x00000050; //リロケート設定

//割り込み禁止
XB24_UART_REG->SCR_f.RIE = 0;
XB24_UART_REG->SCR_f.TIE = 0;
XB24_UART_REG->SCR_f.TBIE = 0;

//送受信禁止
XB24_UART_REG->SCR_f.RXE = 0;
XB24_UART_REG->SCR_f.TXE = 0;

//内部状態初期化(プログラマブルクリア)
XB24_UART_REG->SCR_f.UPCL = 1;

//------ SMR Setting ------//
// 動作モード設定(UART NORMAL)
// WAKE UP OFF
// STOP bit : 1 bit (ESBL = 0)
// LSBファースト
// 出力禁止
//--------------------------------//

XB24_UART_REG->SMR &= 0x00;

//------ SSR Setting ------//
// 受信エラーフラグ クリア
//--------------------------------//

XB24_UART_REG->SSR |= 0x80;

//------ ESCR Setting ------//
// ハードウェアフロー制御禁止(とりあえず)
// STOP bit : 1 bit (SBL = 0)
// NRZフォーマット
// パリティ禁止(とりあえず)
// データ長 = 8 bit
//--------------------------------//

XB24_UART_REG->ESCR &= 0x00;

//------ BGR1 BGR0 Setting ------//
// 内部クロック使用
// ボーレートは9600Hzに設定(とりあえず)@ Main = 144MHz, バスクロック = 36MHz
// リロード値:3750(0x0ea5)
//--------------------------------//

XB24_UART_REG->BGR1 = 0x0e;
XB24_UART_REG->BGR0 = 0xa5;

isOk = TRUE;

return isOk;

}

static BOOL WRITE_UART_DATA(UART_CTRL *pUC, UINT8 *data, UINT32 size){

BOOL isOk = FALSE;
UINT8 buf;
int i;


XB24_UART_REG->SMR_f.SOE = 1;
XB24_UART_REG->SCR_f.TXE = 1;

TimerWait(10); //相手側の準備待ち

for(i=0;i < size;i++){

buf = *data;

while(XB24_UART_REG->SSR_f.TDRE == 0);

XB24_UART_REG->TDR = buf;

while(XB24_UART_REG->SSR_f.TBI == 0);

data++;

}

XB24_UART_REG->SCR_f.TXE = 0;
XB24_UART_REG->SMR_f.SOE = 0;

isOk = TRUE;

return isOk;

}



ここでは特に言及しませんが、TimerWait()関数は、自作した単なるウエイト関数です。
引数×1msecだけウエイトします。

最後に、蛇足ですがmain関数を含んだmain.cを掲載します。



//------main.c-------//

#include "lcd.h"
#include "uart_ctrl.h"


int main()
{
UART_CTRL *pUC;

UINT8 message[14] = {0};
strcpy(message,"Hello World\r\n");

pUC = initUartCtrl();

pUC->initUartReg(pUC);

pUC->writeUartData(pUC,message,sizeof(message));

initDisp();
printUpLine("XBee Test");

while(1);

return 0;
}



なお、lcd.hは、FM3からLCD(SC1602)を動かすための関数を定義したヘッダです。
これも解説はしませんが、ご要望があればソースコードを掲載します。

PC側はTeraTermでXBeeモジュールからの信号を受け取るようにしておきます。
その上で、マイコン側の電源を入れれば、リセットボタンを押すたびにTeraTerm上にHello Worldが表示されます。

XBee通信結果


なんて簡単なんだろう!

こんな簡単に無線通信が出来てしまったら、僕のような組み込み系の人間は必要なくなっちゃうんじゃないかと、リアルに心配になってしまいます(汗)

とりあえず、かなり不完全ではありますが、FM3とPCの通信が確認できました。
次は、PCからFM3側に信号を送りたいと思います。

最後までお読みいただいて、ありがとうございました!(感謝)
こんばんは!
夜もずいぶんと寒くなってきましたね。

最近、化粧水をお求めになったゆってぃです。

というのもね、実は今月頭の連休を使って、バンドメンバーと旅行に行ったんですよ。
富士急ハイランドへ、一泊二日で。

旅行中はずっと、ビデオ回したり写真撮ったりしていました。

それで旅行から帰ってきて、自宅でビデオを編集していて気づいたのですが

僕だけやたら顔が老けてたんですよ(涙)

いやね、最年長(27歳)だから仕方ないにしても、なんというかもう軽く絶望感が漂うほどの老けっぷりだったんです。

これはいかんと。

しかもなんかよく見ると、以前にまして頭頂部まで不安げになってきている始末。

これは本気でアンチエイジングしないと、一生独身だぞと。。。

で、化粧水や乳液(ともに女性用)を買ってですね、毎日ぬりぬりしている訳です。

さすがにまだ効果は現れていませんが、なんとか少しでも健康的な肌になってほしいものです(切実)


さて、今日は久々にFM3ネタです。

先日、秋葉原でCQ出版さん主催のFM3マイコンセミナーへ行ってきました。
そのときに、参加者全員にインターフェース6月号がプレゼントされたので、付録でついていたFM3マイコン基板で何かやろうと思い、手元にあった部品で拡張ボードを作ってみました。
以前にも発売と同時に買ったものがあったのですが、(ブログにも書きましたが)仕事で使ってしまい、自由に使える基板がなかったもので…ちょっと嬉しいです(笑)

まぁ、拡張ボードと言えば聞こえはいいですが
僕の部屋には住民と同じくしょぼい部品しかなかったので、正直ほとんど拡張されておりませんが。。。


これです。

お手軽拡張ボード

とりあえず、青色LEDと液晶(皆大好きSC1602)、あと静電容量式のタッチパネルを付けました。
あと、マイコンの電源をUSBから貰うのではなく、電池から貰うよう改造しました。
と言っても、一箇所パターンカットしただけですけど。
LEDはデジトラをかませてマイコンのPWM出力端子につけたので、明るさを変調させることが出来ます。

この基板には初めからminiBコネクタが実装されているので、IARのサンプルコードを使って、CDCでPCと通信をさせてみました。
静止画ではかわらないですが、PCのキーボードで'A'を押すとLEDが徐々に明るく、'S'を押すと徐々に暗くなります。

まぁ

だからなんだ?

って話ですが・・・(汗)

LCDも、画面に文字を出すとこまでは作りました。
このLCDは本当に簡単に使うことが出来ます(笑)

タッチパネルは…つけたものの、まだ何に使うか決めていません(笑)
ただ、せっかくCDCでPCとつながっているのだから、この拡張ボードからPCを操作できるような何かを作ってみたいと思います。

次回は、具体的なPWMの動かし方についてお話しますね。

という訳で、次回もお楽しみに(笑)

最後まで読んでいただいて、ありがとうございました!(感謝)
こんばんは!

長かったGWも今日でおしまい。。。
ああ、明日からまた仕事が始まってしまう(;_;)

さて、今日はFM3マイコンに内蔵されているベースタイマを使ってLEDを点滅させるプログラムを作ってみましょう。
FM3マイコンのベースタイマには、以下の4つの機能があります。

・PWMタイマ
・PPGタイマ
・リロードタイマ
・PWCタイマ

今回はLEDを点滅させるプログラムですので、リロードタイマを用いてコードを書いてみましょう。

--ここから--

#include "mcu.h"

static void initPort(void);
static void initBaseTimer(void);

int32_t main(void){

 initPort();
 initBaseTimer();

 while(1);

 return 1;

}

static void initPort(void){

 FM3_GPIO->PFRF_f.P3 = 0;
 FM3_GPIO->PZRF_f.P3 = 1;
 FM3_GPIO->DDRF_f.P3 = 1;
 FM3_GPIO->PDORF_f.P3 = 1;

}

static void initBaseTimer(void){

 FM3_BT3_RT->TMCR = 0x3030;
 FM3_BT3_RT->TMCR2 = 0x00;
 FM3_BT3_RT->STC = 0x50;

 NVIC_EnableIRQ(BTIM0_7_IRQn);

 FM3_BT3_RT->PCSR = 0xffff;
 FM3_BT3_RT->TMCR |= 0x03;

}

void BT0_7_IRQHandler(void){

 FM3_BT3_RT->STC &= 0xfe;
 FM3_GPIO->PDORF_f.P3 ^= 1;

}

--ここまで--

今回使用しているマイコンはMB9BF618Tですので、mb9b610t.hというデバイスヘッダファイルをプロジェクトフォルダに入れ、mcu.hをインクルードすれば、このコードの様に各レジスタのアドレスがFM3_xxx->xxxのようにマクロ経由で行えるようになります。
これはPICでも同じでしたね。

なお、FM3_BT3_RT->TMCRと書けばTMCRレジスタそのものに、FM3_BT3_RT->TMCR_f.xxx(xxxはビット名)と書けば、TMCRレジスタの各ビットにアクセスできます。詳細はヘッダファイルをご確認ください。

では、ソースコードの説明に入ります。

main関数では、initPort()関数とinitBaseTimer()関数を順番に呼び出し、無限ループに入っています。
無限ループ中はタイマ割り込みハンドラにてLEDの点滅を制御します。
その割り込みハンドラがBT0_7_IRQHandler()です。

まず、initPort()関数ではポートFの3ビット目をIO設定・出力設定とし、最後にHIを出力しています。
なお、インターフェース付属ボードではHIを出力した場合、LEDは消灯します。
CQ出版社のHPから回路図が入手できますのでご確認ください。

initBaseTimer()関数内では、ベースタイマのチャンネル3をリロードタイマとして初期化し、動作を開始させています。

まず、ベースタイマをリロードタイマとして使用する場合、以下のレジスタを設定する必要があります。

・TMCRレジスタ
・TMCR2レジスタ
・STCレジスタ
・PCSRレジスタ
(・TMRレジスタ)※このレジスタは読み出しのみ

各レジスタの詳細は、富士通さんのHPから入手できるペリフェラルマニュアルをご参照ください。
ありがたいことに日本語で書かれていますので、すぐにご理解いただけると思います。

ただし、各レジスタを設定しただけでは割り込みは発生しません。
ペリフェラルタイマは、割り込みが発生するとCortex-M3コアへ
(富士通ペリフェラル君)「割り込みが発生しました!!割り込みハンドラを呼び出して下さい!!」
という信号を送ることしか出来ないからです。
ですので、Cortex-M3コアが
(Cortex-M3様)「いやじゃ」
と言ったら、割り込みハンドラは呼ばれないのです。

そのため、タイマー初期化時などにあらかじめ「タイマ割り込みが発生するから、そのときはよろしくね」と伝えておかなければなりません。
それが、赤文字で書いた
NVIC_EnableIRQ(BTIM0_7_IRQn);
という部分です。
NVIC_EnableIRQ()はNVIC用の関数で、要はCortex-M3のもつ割り込みコントローラへアクセスするための関数です。
Interface6月号の第7章にとてもわかりやすい説明がありますので、詳細はそちらをご参照ください。
(記事を書かれているのもARM社の方です)

最後に、割り込みハンドラのBT0_7_IRQHandler()です。
この関数内では、割り込みフラグのクリアと、ポート出力の反転を行っています。
なお、使用する割り込みハンドラの関数名は、あらかじめスタートアップ用のアセンブリファイル内で登録をしておかなければなりません。
この内容もInterface6月号の第5章に詳しく書かれているので、ご確認ください。

駆け足でしたが、以上がペリフェラルタイマを用いた場合のLED点滅プログラムです。
本来であれば、割り込みハンドラ内の
if(i>2000000)
部分はカウントクロックによって変化させなければなりませんが、今回は大目に見てください(笑)

最後までお読みいただいて、ありがとうございました!!(感謝)
こんにちは!
ゴールデンウィークでテンションが上がりまくりんぐのゆってぃです!
特に予定はありませんがやはり大型連休はうれしいですね^^

さて、毎年この時期になると、CQ出版社さんから付属マイコン基板つきのInterfaceが発売されます。
今年はなんとCortex-M3コアを内蔵した富士通のFM3マイコン、MB9BF618Tが付属されています!

このマイコン、超豪華です。
なんでも出来ます。
タイマーが本当に豊富でモーター制御に適しているので、エアコンだろうが洗濯機だろうがマッサージ器だろうが、たぶんこのチップのみで制御できます。

もっとも、実際の開発現場では、白物家電や車載、FAなどを除けばここまで高価なマイコンを使用することは無いでしょう。
同じFM3マイコンでも、もう少し下のグレードのものになると思います。

けれども、コアはもちろんペリフェラルレジスタ名も同じなので、この付属基板でFM3マイコン開発に慣れておけば、そのノウハウは実務でも大いに役立つことでしょう!
僕はいままでルネサス派(SH系や旧NECエレの78K0系)だったのですが、最近のARMの急速な普及状況を見ると、やはりARMマイコンにも慣れておかないといけませんね。

という訳で、さっそくLEDペコペコプログラムを作成してみましたよ!

因みに、開発環境にはIAR Embedded Workbenchのコードサイズ限定版(評価版)を使用しています。
また、インクルードファイルやスタートアップファイル・初期化ファイルは、富士通HPからダウンロードしたテンプレートファイルを使用しています。
詳細は、インターフェース6月号をご参照ください。

//-----ここから-----//

#include"mcu.h"

static void initPort(void);

int32_t main(void)
{

 int i;

 initPort();

 while(1){
  for(i=0;i<2000000;i++);
  bFM3_GPIO_PDORF_P3 = ~bFM3_GPIO_PDORF_P3;
 }

 return 1;

}

static void initPort(void){

 bFM3_GPIO_PFRF_P3 = 0;
 bFM3_GPIO_PZRF_P3 = 1;
 bFM3_GPIO_DDRF_P3 = 1;
 bFM3_GPIO_PDORF_P3 = 0;

}

//-----ここまで-----//

どうです?
我らがPIC16F84Aで学習したものと、大して変わらないでしょう?(そうか・・・?)
PIC先生で学んだことは、他のどのマイコンを開発することになっても、必ず生きてくるのです(本当か・・・?)


ちなみに、インターフェースの本誌にはSysTickタイマーを使用したサンプルコードが書かれていましたが、このタイマーはコアのタイマーを使用しているので、あまりアプリケーションプログラムからは使用しないほうがいい気がします。
ですので、あえてfor文でウエイトを入れたプログラムにしました。

タイマーはFM3のペリフェラルタイマーを使用しましょう。
次回は、FM3のもつタイマーを用いたLEDペコペコプログラムを掲載いたします!

最後までお読みいただいて、ありがとうございました!(感謝)
ご訪問者様
プロフィール

ゆってぃ

Author:ゆってぃ
経歴7年の組み込み系・制御系エンジニアです。
("ど素人"という文言は取りました…笑)
ソフトウェア開発経験ゼロの状態から、なんとか実務がこなせるようになってきた現在に至るまでの経験を、備忘録代わりに綴っていきたいと思います。
入門者の方、大歓迎!
(上級者の方、ごめんなさい…)

あと、ブログには全然関係ないですが、Bumpy Headというバンドのギターをやっています。
ライブ情報なんかも書いたりすることがあるので、その時に「行ってもいいよ~」といった感じのコメントを戴けると、泣いて喜びます(泣)
ブログ読んでくださってる方なら、チケット代サービスしちゃいます!

最後に…滅多に流用することは無いでしょうが、このブログに書かれているソースは、特に指定の無い限りMITライセンスとします。ただし、一部それ以外のものもございますのでご注意下さい。
※ブログのリンク先にあるコードに関しては、リンク先のポリシーに従ってください。

最新記事
最新コメント
カテゴリ
RSSリンクの表示
メールフォーム

名前:
メール:
件名:
本文:

twitter
リンク
ブロとも申請フォーム
スポンサードリンク