MSP430红外遥控器控制小车实验[日文、附源码]

楼主
MSP430红外遥控器控制小车实验[日文、附源码]
原文转载于:[URL=http://bird.dip.jp/mt/archives/2007/03/17/2121.html]http://bird.dip.jp/mt/archives/2007/03/17/2121.html[/URL]
有懂日文的网友或有朋友懂日文的,麻烦翻译一下供国内网友参考吧。先谢谢!

[IMGA=0,absMiddle]http://bird.dip.jp/mt/archives/2007/03/17/MSP430-QSTEER.jpg[/IMGA]

「Q-STEER 赤外線信号解析」の説明から、キャリア周波数38KHz、0.425msを on/off の時間隔単位として on-off でビット0を、on-onでビット1を表現すると解釈したのだが、PIECEソフトのコードによるとビット1はon-on-offとなるようだ。またon-on-on-onのヘッダの後にもoffが入る。自前で信号の解析をすれば良いのだろうが、そこは「適当も甚だしい電子工作研究所」と言うことでひとつよろしく。赤外線LEDは不要のリモコンを分解して取り出したもの。赤外線は肉眼では見えないからオシロスコープでモニタ。デジカメのモニタを通すと確認できたりもする。

プログラムはTimerA3により38KHzのキャリア周波数でLED点燈をおこない、0.425ms毎のWDT割込みでコマンドに応じて信号のオンオフをする。とりあえず最小限の動作確認ができただけで、スイッチなどによるコマンドインターフェース等はまだ無い。続く、かも。

[2007.03.18]

サンプルプログラム。このままだとひたすら前進のみ。動作を変更する場合は next_cmd に設定する。UI は適当によろしく。赤外線LEDはP1.2に付けたが、これは学習用マザーボードに実装されているLED(緑1)との差し替え。電流制限抵抗も適当に付けておく。

//******************************************************************************
//  MSP430-CQ
//  P1.2 に赤外線LED をつないで Q-STEER を動かすサンプル
//  2007.03 masato@bird.email.ne.jp
//******************************************************************************

#include "msp430x42x0.h"

// QSCMD: Q-STEER の信号パターンを bit で表現する
typedef struct _QSCMD {
  unsigned int cmd; // MSB から 1/0 パターンを埋める
  unsigned int len; // 有効ビット数
} QSCMD;

const QSCMD cmds[] = {
  { 0x0000,  0 }, // dummy
  // ヘッダとバンド指定
  { 0xf500,  9 }, // Header - Band A
  { 0xf580, 10 }, // Header - Band B
  { 0xf680, 10 }, // Header - Band C
  { 0xf6c0, 11 }, // Header - Band D
  // 操作コマンド
  { 0xaa00,  8 }, // 0000 reserved
  { 0xab00,  9 }, // 0001 forward
  { 0xad00,  9 }, // 0010 backward
  { 0xad80, 10 }, // 0011 left
  { 0xb500,  9 }, // 0100 right
  { 0xb580, 10 }, // 0101 dash forward
  { 0xb680, 10 }, // 0110 forward / left
  { 0xb6c0, 11 }, // 0111 forward / right
  { 0xd500,  9 }, // 1000 dash / left
  { 0xd580, 10 }, // 1001 dash / right
  { 0xd680, 10 }, // 1010 back / left
  { 0xd6c0, 11 }, // 1011 back / right
  { 0xda80, 10 }, // 1100 dash back
  { 0xdac0, 11 }, // 1101 dash back / left
  { 0xdb60, 12 }, // 1111 stop
};

enum Command {
  CMD_NONE = 0,
  CMD_HDA, CMD_HDB, CMD_HDC,CMD_HDD, // ヘッダとバンド指定
  CMD_RSV, CMD_FW,  CMD_BK, CMD_LT,  // コマンド
  CMD_RT,  CMD_FF,  CMD_FL, CMD_FR,
  CMD_FFL, CMD_FFR, CMD_BL, CMD_BR,
  CMD_FB,  CMD_FBL, CMD_FBR,CMT_STP
};

#define BITON(X) ((X) & 0x8000)    // bit on / off 判定
#define LEDON    P1DIR |= 0x04     // LED on
#define LEDOFF   P1DIR &= ~0x04    // LED off

unsigned int tick = 0;             // 0.425ms 単位ステップカウント
unsigned int tick2 = 0;            // 127ms 単位ステップカウント(テスト用)
enum Command band = CMD_HDA;       // バンド指定
enum Command cmd = CMD_FW;         // コマンド
enum Command next_cmd = CMD_BK;    // 次コマンド
int gap = 19;                      // 信号セット間隔 Band-A:19 tick, B:47, C:75, D:104

//

void main(void)
{
  /* WDT により 0.425ms 毎に LED の on/off 制御をする。*/
  SCFQCTL = 38 - 1; // 38 * ACLK = 1.246MHz - 38KHz キャリアと 0.425ms 割込周期を作りやすそうに
  WDTCTL = WDT_MDLY_0_5;  // 0.5ms@1MHz → 0.421ms@1.246MHz 細かいずれには目をつむる。

  // P1.2 に赤外線 LED をつなぐよ
  P1DIR |= 0x04;            // P1.2 as output
  P1SEL |= 0x04;            // P1.2 as TA1 output
 
  /* Timer_A3 を用いてキャリア周波数(38KHz)で赤外線 LED を点燈 */
  CCTL1 = OUTMOD_7;         // Reset on EQU2(TAR = CCR2), Set on EQU0(TAR = CCR0)
  CCR1 = 16;                // on time
  CCR0 = 33;                // interval time : 38KHz
  TACTL = TASSEL_2 + MC_1;  // source:SMCLK, up to CCR0
 
  IE1 |= WDTIE;             // WDT 割込み許可
  _BIS_SR(LPM0_bits + GIE); // LPM0
}

#pragma vector=WDT_VECTOR
__interrupt void WDT(void)
{
  const QSCMD *hp = &(cmds[band]);
  const QSCMD *cp = &(cmds[cmd]);
  int t;
 
  if (cmd == CMD_NONE)
    return; // no-op

  if (tick < hp->len) {
    // Header - Band
    if (BITON(hp->cmd << tick)) LEDON;
    else LEDOFF;
  } else if (tick < hp->len + cp->len) {
    // Command
    t = tick - hp->len;
    if (BITON(cp->cmd << t)) LEDON;
    else LEDOFF;
  } else if (tick < hp->len + cp->len + gap) {
    // Gap
    LEDOFF;
  } else if (tick < hp->len * 2 + cp->len + gap) {
    // Header - Band (2)
    t = tick - (hp->len + cp->len + gap);
    if (BITON(hp->cmd << t)) LEDON;
    else LEDOFF;
  } else if (tick < hp->len * 2 + cp->len + gap) {
    // Command (2)
    t = tick - (hp->len * 2 + cp->len + gap);
    if (BITON(cp->cmd << t)) LEDON;
    else LEDOFF;
  } else {
    LEDOFF; // nop
  }
  tick++;
  if (tick > 300) {
    // 127ms 周期で連続させる。
    tick = 0;
    tick2++;
#if TEST // テスト用に 1.27s 周期で前進(CMD_FW)と前進+左(CMD_FL)を切り替え
    t = tick2 / 10;
    next_cmd = (t % 2)? CMD_FL: CMD_FW;;
#endif
    if (next_cmd != cmd)
      cmd = next_cmd;
  }  
}

/* EOF */実際の Q-STEER リモコンではコマンドボタンを離した時に停止コマンドが出されるそうだ。このプログラムでは WDT 割込みでコマンド処理をおこなっているが、メインルーチンあるいは別の割込み処理でコマンドを送るときには cmd == next_cmd を待って next_cmd に次のコマンドを設定すること。

信号の on/off 制御をもっと汎用的にして UI を工夫することで他の赤外線リモコンにも使える、かも知れない。なお、デジQは信号の仕様が異なり、このプログラムでは動かない。
1楼
红外信号分析[日文]
[IMG=0,absmiddle]http://homepage2.nifty.com/stear/doc/file/QTir1.gif[/IMG]
详情请参考:http://homepage2.nifty.com/stear/doc/QSir.htm
2楼
干脆把注释去掉,放着像鬼画符一样
3楼
DC大大怎么突然想起弄这些日本的文章了,以后是不是还有其他国家的专题啊,嘿嘿
不过他们的技术确实~~ 可惜看不懂日文,不能看注释 呵呵

电脑版 Page created in 0.1250 seconds width 3 queries.