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

さて、今日は前回に引き続き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なので、これからも遊んでみたいと思います^ ^

最後までお読みいただいて、ありがとうございました!(感謝)
関連記事
スポンサーサイト
コメント
コメントの投稿
トラックバック URL
トラックバック
ご訪問者様
プロフィール

ゆってぃ

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

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

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

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

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

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