Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Работает !
- // === ПОДКЛЮЧЕНИЯ ===
- // D0 YM -> D2 Arduino (PD2)
- // D1 YM -> D3 Arduino (PD3)
- // D2 YM -> D4 Arduino (PD4)
- // D3 YM -> D5 Arduino (PD5)
- // D4 YM -> D6 Arduino (PD6)
- // D5 YM -> D7 Arduino (PD7)
- // D6 YM -> D8 Arduino (PB0)
- // D7 YM -> D9 Arduino (PB1)
- // BC1 -> D11 Arduino (PB3)
- // BDIR -> D12 Arduino (PB4)
- // CLOCK -> D10 Arduino (PB2)
- // RESET -> D13 Arduino (PB5)
- // Определяем маски для порта B
- #define BDIR_BIT (1 << 4) // PB4 (D12)
- #define BC1_BIT (1 << 3) // PB3 (D11)
- ///////////////////////////////////////////////////////////
- #define SET_DATA(value) { \
- uint8_t low_byte = (value) & 0x3F; \
- uint8_t high_bits = ((value) >> 6) & 0x03; \
- PORTD = (PORTD & 0x03) | ((low_byte & 0x3F) << 2); \
- PORTB = (PORTB & 0xFC) | ((high_bits & 0x03) << 0); \
- }
- /////////////////////////////////////////////////////////////
- // ИСПРАВЛЕННЫЙ макрос SET_CTRL - без if, только битовые операции
- #define SET_CTRL(bdir, bc1) { \
- PORTB = (PORTB & ~(BDIR_BIT | BC1_BIT)) | ((bdir) ? BDIR_BIT : 0) | ((bc1) ? BC1_BIT : 0); \
- }
- const uint8_t ay_data_01[] = { 15, 0, 0x01, 0x50, 196, 16, 16, 16, 184, 0, 0, 0x50, 0, 1, 0, 48 };
- //////////////////////////////////////////////////////////////
- void write_ym(uint8_t reg, uint8_t value) {
- // --- Шаг 1: Выбор регистра (Address Latch) ---
- SET_DATA(reg); // Выставляем номер регистра
- SET_CTRL(1, 1); // BDIR=1, BC1=0
- //asm volatile("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- //delayMicroseconds(10);
- SET_CTRL(0, 0); // Возврат в нейтральное состояние
- // --- Шаг 2: Запись данных (Data Write) ---
- SET_DATA(value); // Выставляем данные
- SET_CTRL(1, 0); // BDIR=1, BC1=1
- //asm volatile("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop");
- //delayMicroseconds(10);
- SET_CTRL(0, 0); // Возврат в нейтральное состояние
- }
- /////////////////////////////////////////////////////////////////////////
- void setup() {
- // --- 1. Настройка пинов как выходы ---
- DDRD |= 0xFC; // D2-D7 (PD2-PD7) как выходы
- DDRB |= 0x3F; // D8-D13 (PB0-PB5) как выходы
- // --- 2. Настройка тактового генератора 2 МГц на D10 ---
- TCCR1A = _BV(COM1B0); // Переключать OC1B (D10) при совпадении
- TCCR1B = _BV(WGM12) | _BV(CS10); // CTC, предделитель 1
- OCR1A = 3; // Верхнее значение счетчика
- //OCR1B = 3; // Обязательно для OC1B!
- // --- 3. Сброс YM2149F ---
- pinMode(13, OUTPUT);
- digitalWrite(13, LOW); delay(10);
- digitalWrite(13, HIGH); delay(10);
- // Небольшая задержка после сброса
- delay(100);
- // --- 4. Инициализация регистров ---
- for (int reg = 15; reg >= 0; reg--) {
- write_ym(reg, ay_data_01[15 - reg]);
- delayMicroseconds(100);
- }
- delay(1500);
- }
- ////////////////////////////////////////////////////////////////////////
- void loop() {
- write_ym(15, 170); delay(700); // 0xAA
- write_ym(15, 85); delay(700); // 0x55
- write_ym(15, 240); delay(700); // 0xF0
- write_ym(15, 1); delay(700); // Port_B_AA: бит 0
- write_ym(15, 128); delay(700); // Port_B_55: бит 7
- write_ym(15, 1); delay(700);
- write_ym(15, 128); delay(4177);
- }
- /// 2026 mart 29
- // Макросы для быстрого переключения пинов YM
- #define YM_PORT_DATA (PORTD)
- #define YM_PIN_DATA_MASK 0xFC // PD2–PD7: биты 2–7
- #define YM_PIN_DATA_SHIFT 2 // сдвиг на 2 бита
- #define YM_PORT_CTRL (PORTB)
- #define YM_PIN_BC1 (1<<3) // PB3
- #define YM_PIN_BDIR (1<<4) // PB4
- // Установка байта на D0–D7 (младший байт данных/адреса)
- static inline void ym_set_data(uint8_t data) {
- // младшие 6 бит → PD2–PD7
- uint8_t d_lower = (data & 0x3F) << YM_PIN_DATA_SHIFT;
- // оставшиеся 2 бит → PB0,PB1
- uint8_t d_high = (data & 0xC0) >> 6; // 0x00, 0x01, 0x02, 0x03
- PORTD = (PORTD & 0x03) | d_lower;
- PORTB = (PORTB & 0xFC) | d_high;
- }
- // Перейти в режим Address
- static inline void ym_mode_address() {
- YM_PORT_CTRL |= YM_PIN_BDIR; // BDIR = HIGH
- YM_PORT_CTRL |= YM_PIN_BC1; // BC1 = HIGH
- delayMicroseconds(1); // запас времени, чтобы YM увидел Address
- }
- // Перейти в режим Write
- static inline void ym_mode_write() {
- YM_PORT_CTRL |= YM_PIN_BDIR; // BDIR = HIGH
- YM_PORT_CTRL &= ~YM_PIN_BC1; // BC1 = LOW
- delayMicroseconds(1); // запас времени, чтобы YM увидел Write
- }
- // Запись байта в регистр YM2149F (регистр 0–15, data 0–255)
- void ym_write_register(uint8_t reg, uint8_t data) {
- reg &= 0x0F; // YM имеет 16 регистров
- // 1) MODE ADDRESS
- ym_mode_address();
- ym_set_data(reg); // на шину D0–D7 выставляем адрес
- // 2) MODE WRITE
- ym_mode_write();
- ym_set_data(data); // теперь выставляем реальные данные
- // YM требует минимального времени удержания данных (tow ~300 нс),
- // delayMicroseconds(1) после set_data уже достаточно.
- asm volatile("nop" : : : "memory"); // антиматериал
- }
Advertisement
Add Comment
Please, Sign In to add comment