1

我正在为两个 SNES 控制器构建发射器和接收器对,因为我不喜欢使用长延长线让控制器到达沙发。我将ATmega328Ps用于 AVR,带有 RF24l01 无线收发器(使用 ManiacBugs RF24 库)。我在发射器上使用修改后的 snesPad 库来轮询两个控制器的按钮状态并将它们作为 32 位无符号长返回,然后将其传输到接收器。所有标准库,没有问题(到目前为止)。

然而,在接收端,我必须正确响应来自 SNES 的锁存器和时钟信号,我还没有找到任何库存库。对于那些不熟悉 SNES 控制器的人来说,它们基本上是两个 8 位并行到串行移位寄存器串联。它们在锁存信号的上升沿(12 µs 脉冲高电平,通常为低电平)锁存所有按钮状态,在锁存器的下降沿驱动第一位,然后在时钟的上升沿驱动每个连续的位(6 µs 延迟从锁存器下降,通常为高,6 µs 低 - 6 µs 高周期)。

我决定使用外部中断来触发锁存脉冲和每个时钟脉冲的正确行为。不过,我是编程 Arduinos 的新手,也是 C/C++ 的新手。虽然我的代码可以编译,但我不确定它是否真的能按预期运行。如果对 AVR 有一定经验的人可以看看我的代码并告诉我它是否可以工作,如果不行,在哪里以及为什么,我将非常感激!

Arduino草图如下:

/*
   Copyright (C) 2012 John Byers <jbyers2@wgu.edu>
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   version 3 as published by the Free Software Foundation
*/

/**
 * Dual Wireless Retro Controller Adapter Transmitter
 *
 * This is the reciever side code for the adapter set.
 */

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>

//
// Hardware Configuration
//

RF24 radio(9,10);

//
// Variable Inits
//

volatile unsigned long state2 = 0xFFFFFFFF;
volatile byte i = 0;
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
int strobe = 2;
int clock = 3;
volatile int data1 = 5;
volatile int data2 = 6;
bool firstLoop = true;
volatile int status2 = 1;

void setup()
{
    radio.begin();
    radio.setRetries(0,15);
    radio.enableDynamicPayloads();
    Serial.begin(57600);
    pinMode(strobe, INPUT);
    pinMode(clock, INPUT);
    pinMode(data1, OUTPUT); digitalWrite(data1, LOW);
    pinMode(data2, OUTPUT); digitalWrite(data2, LOW);

    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1,pipes[0]);

    //
    //Dump the configuration of the RF unit for debugging
    //

    radio.printDetails();

    //
    //Setup Interupts
    //

    attachInterrupt(strobe,latch,RISING);
    attachInterrupt(clock,data,RISING);
}

void loop()
{
    if (firstLoop) {
        int status1 = 1;
        bool ok = radio.write( &status1, sizeof(int));
        firstLoop = false;
        radio.startListening();
        if (!ok) {
            Serial.println("sync packet transmission failed");
        }
        else {
            Serial.println("sync packet transmission successful");
        }
    }
    if ( radio.available() )
    {
        unsigned long state = 0;
        radio.read( &state, sizeof(unsigned long) );
        Serial.println(state, BIN);
        state2 = state;
    }
    else
    {
        Serial.println("No data recieved yet");
    }
}

//Latch interrupt routine

void latch()
{
    i = 0;
    digitalWrite(data1,HIGH);
    digitalWrite(data2,HIGH);
    digitalWrite(data1,bitRead(state2,i));
    digitalWrite(data2,bitRead(state2,(i+16)));
    Serial.println("Bit0 out");
}

//Data interrupt routine

void data()
{
    i++;
    digitalWrite(data1,bitRead(state2,i));
    digitalWrite(data2,bitRead(state2,(i+16)));
    Serial.print("Bit");
    Serial.print(i);
    Serial.println(" out");
    if(i=15)
    {
        digitalWrite(data1,LOW);
        digitalWrite(data2,LOW);
        radio.stopListening();
        int status1 = status2;
        bool ok = radio.write( &status1, sizeof(int));
        if (!ok) {
            Serial.println("sync packet transmission failed");
        }
        else {
            Serial.println("sync packet transmission successful");
        }
        radio.startListening();
    }
}
4

0 回答 0