20150206_171016

●マイコン側
オペアンプで増幅して矩形波としたものをmbedに入力し、インプットキャプチャで復調していきます。得られた8bitのデータをシリアルでパソコンに送ってターミナル画面で確認します。

#include "mbed.h"

#define SAMPLE_RATE 44100
#define FREQ_LOW 3150
#define FREQ_HIGH 6300
#define BAUD 630
#define HIGH 1
#define LOW 0
#define MID 2
#define IDLE 0
#define RCVCODE 1
#define CHECKCODE 2

Serial pc(USBTX, USBRX);
Timer timer;
InterruptIn sig(p21);

int begin,end,interval;
int LowWidth, HighWidth;
unsigned char lowFreqCnt, highFreqCnt;
unsigned char lowSigCnt, highSigCnt;
unsigned char fskSignal;
unsigned char bitCnt;
unsigned char fskData;
unsigned char rcvState;

void getData(unsigned char data) {
    pc.putc(data);    
}

void sigFall() {
    interval = 0;
    begin = timer.read_us();
}

void sigRise() {
    end = timer.read_us();
    interval = end - begin;
    timer.reset();
    fskSignal = MID;
    //check wave width
    if(LowWidth-54 < interval && interval < LowWidth+54) {    //lowFreq
        lowFreqCnt++;
        highFreqCnt = 0;
        if(lowFreqCnt == FREQ_LOW/BAUD) {   //signal is LOW
            fskSignal = LOW;
            lowFreqCnt = 0;
        }
    }else if(HighWidth-26 < interval && interval < HighWidth+26) {    //highFreq
        highFreqCnt++;
        lowFreqCnt = 0;
        if(highFreqCnt == FREQ_HIGH/BAUD) { //signal is HIGH
            fskSignal = HIGH;
            highFreqCnt = 0;
        }
    }else { //should ignore
        rcvState = IDLE;
        lowFreqCnt = highFreqCnt = lowSigCnt = highSigCnt = 0;
        fskSignal = MID;
    }
    //check data
    switch(rcvState) {
    case IDLE:
        if(fskSignal == LOW) {
            lowSigCnt++;
        }else if(fskSignal ==HIGH) {
            if(lowSigCnt == 8) {    //detect header and start bit
                rcvState = RCVCODE;
                fskData = 0;
                bitCnt = 0;
            }
        }
        break;
    case RCVCODE:
        if(fskSignal == LOW) {
            fskData <<= 1;
            bitCnt++;
        }else if(fskSignal == HIGH) {
            bitCnt++;
            if(bitCnt == 9) {   //stop bit
                bitCnt = 0;
                rcvState = IDLE;
                lowFreqCnt = highFreqCnt = lowSigCnt = highSigCnt = 0;
                getData(fskData);
                fskData = 0;
            }else {
                fskData <<= 1;
                fskData += 1;
            }
        }
        break;
    default:
        break;    
    }
}

int main() {
    LowWidth = 1000000/FREQ_LOW/2;
    HighWidth = 1000000/FREQ_HIGH/2;
    lowFreqCnt = highFreqCnt = 0;
    timer.start();
    sig.rise(&sigRise);
    sig.fall(&sigFall);
    while(1) {
    }
}