芯片KC89C72 可編程聲音發生器(PSG)

一片從遊戲器上拆下來的KC89C72。MCU使用的51。

/* \file main.c - Keil C v8.02
 *   Project id: 00595cf9-8de6-4a57-b940-eb0347ac9e13
 *
 * \details This file is part of the KC89C72 project.
 *
 * History:
 *   Date        Auther      Description
 *   -------------------------------------------------------------
 *   2013-01-06  Perry       Initial created.
 *
 * Note:
 * This source code can be used, modified, and redistributed under the
 * terms of the license agreement that is included in the lcd_h018in01 package
 * By continuing to use, modify, or redistributed this code you indicate
 * that you have read the license and understand and accept it fully.
 */


#include "main.h"

#define PSG_KC89C72_REG_R0              0x00  // 通道A頻率設置,低8位。
#define PSG_KC89C72_REG_R1              0x01  // 通道A頻率設置,高4位。
#define PSG_KC89C72_REG_R2              0x02  // 通道B頻率設置,低8位。
#define PSG_KC89C72_REG_R3              0x03  // 通道B頻率設置,高4位。
#define PSG_KC89C72_REG_R4              0x04  // 通道C頻率設置,低8位。
#define PSG_KC89C72_REG_R5              0x05  // 通道C頻率設置,高4位。
#define PSG_KC89C72_REG_R6              0x06  // 噪音頻率設置,5位。
#define PSG_KC89C72_REG_R7              0x07  // I/O端口與混音設置。
#define PSG_KC89C72_REG_R8              0x08  // 通道A電平設置。
#define PSG_KC89C72_REG_R9              0x09  // 通道B電平設置。
#define PSG_KC89C72_REG_RA              0x0A  // 通道B電平設置。
#define PSG_KC89C72_REG_RB              0x0B  // 包絡頻率。微調,8位。
#define PSG_KC89C72_REG_RC              0x0C  // 包絡頻率。粗調,8位。
#define PSG_KC89C72_REG_RD              0x0D  // 包絡形狀。低4位(CONT/ATT/ALT/HOLD)。
#define PSG_KC89C72_REG_RE              0x0E  // 擴展/外設端口A數據寄存器,8位。
#define PSG_KC89C72_REG_RF              0x0F  // 擴展/外設設口B數據寄存器,8位。

#define chip_addr  PSG_KC89C72_DA
#define chip_data  PSG_KC89C72_DA

sbit key = P1^0;

sbit bc1      = PSG_KC89C72_BC1;
sbit bc2      = PSG_KC89C72_BC2;
sbit bdir     = PSG_KC89C72_BDIR;
sbit sel      = PSG_KC89C72_SEL;
sbit a8       = PSG_KC89C72_A8;
sbit a9       = PSG_KC89C72_A9;
sbit reset    = PSG_KC89C72_RESET;
sbit clk      = PSG_KC89C72_CLK;

#define set_addr_mode() \
  bc1 = 1; \
  bc2 = 1; \
  bdir = 1; \
  a8 = 1; \
  a9 = 0

#define set_read_mode() \
  bc1 = 1; \
  bc2 = 1; \
  bdir = 0; \
  a8 = 0

#define set_write_mode() \
  bc1 = 0; \
  bc2 = 1; \
  bdir = 1; \
  a8 = 0

#define set_inactive_mode() \
  bc1 = 0; \
  bc2 = 1; \
  bdir = 0; \
  a8 = 0

void chip_write(uint8 reg, uint8 val)
{
  set_addr_mode();
  delay_xms(1);
  chip_addr = reg & 0xf;
  delay_xms(1);

  set_write_mode();
  delay_xms(1);
  chip_data = val;
  delay_xms(1);

  set_inactive_mode();
  delay_xms(1);
  
  chip_data = 0xff;
}

void chip_reset()
{
  reset = 0;
  delay_xms(1);
  reset = 1;
}

void chip_init()
{
  chip_reset();
  sel = 1;
  
  chip_write(PSG_KC89C72_REG_R0, 150);
  chip_write(PSG_KC89C72_REG_R1, 10);
  
  chip_write(PSG_KC89C72_REG_R2, 0xff);
  chip_write(PSG_KC89C72_REG_R3, 0xf);
  
  chip_write(PSG_KC89C72_REG_R4, 8);
  chip_write(PSG_KC89C72_REG_R5, 0);
  
  chip_write(PSG_KC89C72_REG_R6, 1);
  chip_write(PSG_KC89C72_REG_R7, 0xf8);
  
  chip_write(PSG_KC89C72_REG_R8, 0x2);
  chip_write(PSG_KC89C72_REG_R9, 0xf);
  chip_write(PSG_KC89C72_REG_RA, 0x1f);
  
  chip_write(PSG_KC89C72_REG_RB, 0x28);
  chip_write(PSG_KC89C72_REG_RC, 0x0);
  
  chip_write(PSG_KC89C72_REG_RD, 0xe);
}

void main()
{
  uint8 vol = 0xf;
  
  chip_init();
  
  while (1)
  {
    if (!key)
    {
      delay_xms(500);
      if (vol = 0)
        vol = 0xf;
      vol--;
  chip_write(PSG_KC89C72_REG_R1, vol & 0xf);
  chip_write(PSG_KC89C72_REG_R3, vol & 0xf);
  chip_write(PSG_KC89C72_REG_R5, vol & 0xf);
    }
  }
}

// 延時子程序毫秒單位。
void delay_xms(uint16 ms)
{
  while (ms--)
    delay_xus(109);
}

// 延時子程序微秒單位。
void delay_xus(uint16 us)
{
  while (us--);
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章