【遊戯王真DM】チートリモコンLiteを製作する~ソフトウェア編~【封印されし記憶】

1年前に、遊戯王真デュエルモンスターズ~封印されし記憶~のポケットステーションで強力なカードを入手するためのツール:チートリモコンを製作記事を作成した。
今回は、チートリモコンの設計を見直し、小型で操作性を向上したLite版を製作する。




<初代チートリモコン>
封印されし記憶を語る
概要編
ハードウェア編
ソフトウェア編①:動作確認
ソフトウェア編②:キー操作
ソフトウェア編③:チャタリング対策
ソフトウェア編④:NECフォーマット
ソースコード一覧
入手カード一覧


<チートリモコンLite>
回路図編
ソフトウェア編 ←いまここ
基板実装編
ソースコード一覧




以下の内容は、ある程度PICやC言語を知っている前提となります。
何をしているのか分からない部分があったら、参考書やwebのPIC入門などを参照してください。




初代で作ったIrREMlib.hとIrREMlib.cは、ピンや周波数、ディレイ時間などの修正が必要なものの流用することができる。
修正は別記事に載せるとして、マイコンが変更になっているためコンフィグファイルを修正し、pic16f1786_config.hという名称で作った。

// PIC16F1786 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF     // Voltage Regulator Capacitor Enable bit (Vcap functionality is disabled on RA6.)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low Power Brown-Out Reset Enable Bit (Low power brown-out is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

特に必要なのは以下の4つ。

  • FOSC:クロックソースの選択、内部発振を使用するためINTOSCにする、こうすることでRA6とRA7がデジタルIOピンとして使用可能になる
  • WDTE:ウォッチドッグタイマーのイネーブル、使用しないのでOFF
  • MCLRE:MCLRピンの役割設定、リセットとして使用しないのでOFF
  • PLLEN:4倍PLLのイネーブル、使用するのでON


次はmain.c。
まずは#includeや#define部分。

#include "xc.h"
#include "pic16f1786_config.h"
#include "IrREMlib.h"

#define _XTAL_FREQ 32000000

// I/O
#define CUSTOM  ~PORTA
#define DATA    PORTC
#define SEND_SW RB0
#define LED_ON  LATB5 = 1;
#define LED_OFF LATB5 = 0;

クロック周波数は内臓8MHz×4倍PLLのため、32MHzとなる。
ピンの定義は回路図に合わせて行い、今回はCUSTOMがPORTA、DATAがPORTCに接続されており、PORTAは正論理のロータリースイッチを使っているため反転にした。




次はint main内の変数定義やコンフィグ。

  unsigned char nec_custom = 0;
  unsigned char nec_data   = 0;

  // Clock Config
  OSCCONbits.IRCF = 0b1110; // 8MHz(x4 = 32MHz)

  // I/O Port Init
  ANSELA = 0x00; //全てデジタル
  ANSELB = 0x00; //全てデジタル
  TRISA  = 0xFF; //全て入力
  TRISB  = 0xDF; //RB5のみ出力
  TRISC  = 0xFF; //全て入力
  nWPUEN = 0;    //内部プルアップ有効化
  WPUA   = 0xFF; //全て内部プルアップ有り
  WPUB   = 0x01; //RB0のみ内部プルアップ有り
  WPUC   = 0xFF; //全て内部プルアップ有り
  LED_OFF;

コメントに書いてある通りで、今回は入力ピンに内部プルアップを使用するため、nWPUENやWPUA/B/Cを使用する。
未使用ポートって入力より出力にした方がいいんだっけ?




肝心のmainループは以下のようにした。

  while(1){
    if(SEND_SW == 0){
      nec_custom = CUSTOM;
      nec_data   = DATA;
      do{
        NecSend(nec_custom, nec_data);
        __delay_ms(40);
      } while(SEND_SW == 0);
    }
  }

たったこれだけで初代チートリモコンのmainループ、keys.hとkeys.cと同等の動作をする。
特にnec_customとnec_dataは、初代ではLCD表示やロータリーエンコーダーによる値の変更、チャタリング対策に桁の変更など複雑なことをしていたが、それがたったの2行まで圧縮された。




前回の記事でも載せたけど、実験中の写真はこんな感じ。

ICSPはブレッドボードに直接接続している。
今回は内部発振を使用しており、初代より誤差が大きいし0.125us単位での動作となるため、ロジアナでタイミング解析を行い、ディレイ時間を調整した。
うまく動作したため、次回の記事で基板実装を行う。