Перемещение порта Arduino (PORTD в PORTB)

Поэтому я пытаюсь соединить чип с 8-битной шиной данных. Все работает хорошо, но...

Arduino Uno использует D0 и D1 для последовательного TX/RX (USB-соединение с ПК). Когда я пытаюсь открыть последовательное соединение (на стадии serial.begin), порты D0 и D1 блокируются, и чип перестает работать. Это проблема.

Я думаю, что я должен переместить контакты D0 и D1 в другой порт. Но чип использует 8 контактов (8-битный чип). Поэтому мне нужно переместить первый вывод (D0) и второй вывод (D1) в порт b. Может быть, я могу использовать B4 и B3?

Но я не знаю, как использовать PORTD[PD2, PD3, PD4, PD5, PD6, PD7] и PORTB[PB4, PB3] одновременно, например:

var portX = PORTD[PD2, PD3, PD4, PD5, PD6, PD7] + PORTB[PB4, PB3];
portX = data;

Мой код:

#include <avr/io.h>     // For I/O and other AVR registers
#include <util/delay.h> // For timing


/* Pinmap (Arduino UNO compatible) */
#define YM_IC (5) // PC5 (= pin A5 for Arduino UNO)
#define YM_CS (4) // PC4 (= pin A4 for Arduino UNO)
#define YM_WR (3) // PC3 (= pin A3 for Arduino UNO)
#define YM_RD (2) // PC2 (= pin A2 for Arduino UNO)
#define YM_A0 (1) // PC1 (= pin A1 for Arduino UNO)
#define YM_A1 (0) // PC0 (= pin A0 for Arduino UNO)
#define YM_CTRL_DDR DDRC
#define YM_CTRL_PORT PORTC
#define YM_DATA_DDR DDRD

#define YD0 (0)(= pin D0 for Arduino UNO)
#define YD1 (1)(= pin D1 for Arduino UNO)
#define YD2 (2)(= pin D2 for Arduino UNO)
#define YD3 (3)(= pin D3 for Arduino UNO)
#define YD4 (4)(= pin D4 for Arduino UNO)
#define YD5 (5)(= pin D5 for Arduino UNO)
#define YD6 (6)(= pin D6 for Arduino UNO)
#define YD7 (7)(= pin D7 for Arduino UNO)

#define YM_DATA_PORT PORTD // Whole PORT D for data bus (= pins D0 to D7 for Arduino UNO)
#define YM_MCLOCK (1) // PB1 = OC1A (= pin D9 for Arduino UNO)
#define YM_MCLOCK_DDR DDRB

extern uint8_t chflash[6];
uint8_t dacflash;
#define NOTEONFLASH 4
#define VGMWAIT 15

static void write_ym(uint8_t data) {
  YM_CTRL_PORT &= ~_BV(YM_CS); // CS LOW
  YM_DATA_PORT = data;
  _delay_us(1);
  YM_CTRL_PORT &= ~_BV(YM_WR); // Write data
  _delay_us(5);
  YM_CTRL_PORT |= _BV(YM_WR);
  _delay_us(5);
  YM_CTRL_PORT |= _BV(YM_CS); // CS HIGH
}

/**
 * Write data into a specific register of the YM2612
 *
 * @author Furrtek
 * @param reg Destination register address
 * @param data Data to write
 */
static void setreg(uint8_t reg, uint8_t data) {
  YM_CTRL_PORT &= ~_BV(YM_A0); // A0 low (select register)
  write_ym(reg);
  YM_CTRL_PORT |= _BV(YM_A0);  // A0 high (write register)
  write_ym(data);
}

void call() {
  setreg(0x28, 0xF0); // Key on
  _delay_ms(1000);
  setreg(0x28, 0x00); // Key off
}

uint8_t getfilebyte() {
  return Serial.read();
}

int main() { 
  init();

  //Serial.begin(9600);
  /* Pins setup */
  YM_CTRL_DDR |= _BV(YM_IC) | _BV(YM_CS) | _BV(YM_WR) | _BV(YM_RD) | _BV(YM_A0) | _BV(YM_A1);
  YM_DATA_DDR |= _BV(YD0) | _BV(YD1) | _BV(YD2) | _BV(YD3) | _BV(YD4) | _BV(YD5) | _BV(YD6) | _BV(YD7); 
  YM_MCLOCK_DDR |= _BV(YM_MCLOCK);
  YM_CTRL_PORT |= _BV(YM_IC) | _BV(YM_CS) | _BV(YM_WR) | _BV(YM_RD); /* IC, CS, WR and RD HIGH by default */
  YM_CTRL_PORT &= ~(_BV(YM_A0) | _BV(YM_A1)); /* A0 and A1 LOW by default */

  /* F_CPU / 2 clock generation */
  TCCR1A = _BV(COM1A0);            /* Toggle OCA1 on compare match */
  TCCR1B = _BV(WGM12) | _BV(CS10); /* CTC mode with prescaler /1 */
  TCCR1C = 0;                      /* Flag reset */
  TCNT1 = 0;                       /* Counter reset */
  OCR1A = 0;                       /* Divide base clock by two */

  /* Reset YM2612 */
  YM_CTRL_PORT &= ~_BV(YM_IC);
  _delay_ms(10);
  YM_CTRL_PORT |= _BV(YM_IC);
  _delay_ms(10);

  /* YM2612 Test code */ 
  setreg(0x22, 0x00); // LFO off
  setreg(0x27, 0x00); // Note off (channel 0)
  setreg(0x28, 0x01); // Note off (channel 1)
  setreg(0x28, 0x02); // Note off (channel 2)
  setreg(0x28, 0x04); // Note off (channel 3)
  setreg(0x28, 0x05); // Note off (channel 4)
  setreg(0x28, 0x06); // Note off (channel 5)
  setreg(0x2B, 0x00); // DAC off
  setreg(0x30, 0x71); //
  setreg(0x34, 0x0D); //
  setreg(0x38, 0x33); //
  setreg(0x3C, 0x01); // DT1/MUL
  setreg(0x40, 0x23); //
  setreg(0x44, 0x2D); //
  setreg(0x48, 0x26); //
  setreg(0x4C, 0x00); // Total level
  setreg(0x50, 0x5F); //
  setreg(0x54, 0x99); //
  setreg(0x58, 0x5F); //
  setreg(0x5C, 0x94); // RS/AR 
  setreg(0x60, 0x05); //
  setreg(0x64, 0x05); //
  setreg(0x68, 0x05); //
  setreg(0x6C, 0x07); // AM/D1R
  setreg(0x70, 0x02); //
  setreg(0x74, 0x02); //
  setreg(0x78, 0x02); //
  setreg(0x7C, 0x02); // D2R
  setreg(0x80, 0x11); //
  setreg(0x84, 0x11); //
  setreg(0x88, 0x11); //
  setreg(0x8C, 0xA6); // D1L/RR
  setreg(0x90, 0x00); //
  setreg(0x94, 0x00); //
  setreg(0x98, 0x00); //
  setreg(0x9C, 0x00); // Proprietary
  setreg(0xB0, 0x32); // Feedback/algorithm
  setreg(0xB4, 0xC0); // Both speakers on
  setreg(0x28, 0x00); // Key off
  setreg(0xA4, 0x22); // 
  setreg(0xA0, 0x69); // Set frequency

  call();

  while(1000) {
    if (Serial.available() > 0) {
      _delay_ms(1000);
      call();
      _delay_ms(1000);
      char var = getfilebyte();
      Serial.print("Yeah: ");
      Serial.println(var);
    } else {
      Serial.print("Nooo: ");
      Serial.println(Serial.available());
      call();
    }
  }
  while(1);
}

3 ответа

Второй ответ, потому что я думаю, что теперь вы действительно идете другим путем, когда я перечитал ваш вопрос. Я думаю, что вы хотите вывести на эти контакты. Вам понадобится bitmath, чтобы сделать это.

Что-то вроде:

PORTB |= (data & 0x03) << 3;
PORTD |= data & 0xFC;

Тебе нужен битмат, чтобы соединить их. Сдвиг по битам или по битам или по битве и. Посмотрите это в ссылке. То, что вы хотите, будет выглядеть примерно так:

byte portX = (PORTD & 0xFC) | ((PORTB >> 3) & 0x03);

То, что вы на самом деле получите, может немного отличаться, хотя, поскольку я делаю предположения о том, в каком порядке вы хотите биты. Первая часть маскирует старшие 6 бит PORTD, вторая часть сдвигает два бита, которые вы хотите из PORTB, в младшие два бита и маскируют их. | в середине соединяет два.

"Невозможно записать в два разных регистра одну и ту же инструкцию, поэтому, если вам нужно, чтобы все восемь битов изменялись точно одновременно, вам не повезло". Ответ от электроники. Может быть, я могу проверить свою удачу в нескольких серийных начала и конца..

Другие вопросы по тегам