A ligação elétrica é muito simples: o Arduino fornece a alimentação da placa através dos pinos +5V e GND e os sinais de controle da placa são ligados às portas digitais 3 a 7 do Arduino.
Como primeiro teste, vamos programar o KC89C72 para soar um tom de 523Hz (um dó). As informações de programação estão no datasheet, basicamente precisamos escrever valores apropriados nos registradores do KC89C72. A escrita em um registrador é feita através dos seguintes passos, lembrando que temos um shift register 595 ligado à via de dados do KC:
- Os sinais BC1 e BCDIR são colocados em zero para colocar a via de dados no modo inativo (alta impedância).
- O endereço do registrador é colocado na via. Para isto é preciso colocar o sinal Latch do 595 em nível baixo, colocar os bits um a um no sinal Data, pulsando o sinal Clock a cada bit (para colocar o endereço dentro do 595) e depois colocar o sinal Latch no nível alto para o 595 atualizar os seus pinos de dados com o valor que foi enviado serialmente.
- Os sinais BC1 e BCDIR sãi colocados em um, para o KC registrar o dado na via como um endereço de registrador.
- Os sinais BC1 e BCDIR são retornados a zero para voltar a via de dados ao modo inativo.
- O sinal BC1é mantido em zero e BCDIR colocado em um para inciar a escrita no registrador.
- O valor a ser escrito é colocado na via, de volta igual à feita com o endereço.
- Os sinais BC1 e BCDIR são retornados a zero para concluir a escrita.
Os registradores 0 e 1 definem a frequência (ou o período se preferirem) do tom que será emitido no canal A. O KC89C72 pega o sinal de clock (2MHz), divide por 16 e depois divide pelo valor de 12 bits que está nestes registradores. Portanto, para gerar uma frequência f, precisamos programar o valor 2MHz/16/f. O valor zero é usado para gerar silêncio (na realidade o KC89C72 gera uma frequência muito alta).
O registrador 7 determina quais canais de tom e ruído estão inibido, no nosso caso queremos inibir tudo menos o tom do canal A. Este registrador determina também o uso das portas de I/O adicionais (não usadas na placa), vamos deixá-las como entradas.
O registrador 10 determina o volume do canal A e o uso ou não do envelope. Vamos programar a amplitude máxima, sem envelope.
Para não perturbar muito, vamos usar a serial do Arduino para ligar e desligar o tom. O programa está abaixo e pode ser baixado dos arquivos do blog (KC89C72_A.zip).
// Teste com KC89C72 / AY-3-8910
// Conexões da placa de teste ao Arduino
const int pinData = 5;
const int pinLatch = 6;
const int pinClock = 7;
const int pinBC1 = 10;
const int pinBCDIR = 12;
// Frequencia do clock do KC89C72
const long freqKC = 2000000L;
// Registradores do KC89C72
const unsigned char regToneA_Lo = 0;
const unsigned char regToneA_Hi = 1;
const unsigned char regToneB_Lo = 2;
const unsigned char regToneB_Hi = 3;
const unsigned char regToneC_Lo = 4;
const unsigned char regToneC_Hi = 5;
const unsigned char regNoisePeriod = 6;
const unsigned char regEnable = 7;
const unsigned char regAmpA = 8;
const unsigned char regAmpB = 9;
const unsigned char regAmpC = 10;
const unsigned char regEnv_Lo = 11;
const unsigned char regEnv_Hi = 12;
const unsigned char regEnvShape = 13;
// iniciação
void setup ()
{
// configura direção dos pinos
pinMode(pinLatch, OUTPUT);
pinMode(pinData, OUTPUT);
pinMode(pinClock, OUTPUT);
pinMode(pinBC1, OUTPUT);
pinMode(pinBCDIR, OUTPUT);
// inicia o KC89C72
writeReg (regNoisePeriod, 0); // desliga noise generator
writeReg (regEnable, 0x3E); // somente Tom no A
writeReg (regToneA_Lo, 0); // desliga o tom
writeReg (regToneA_Hi, 0);
writeReg (regAmpA, 0x0F); // amplitude máxima, sem envelope
// incia a serial
Serial.begin (9600);
Serial.println ("KC89C72");
}
// programa principal
void loop ()
{
if (Serial.available() > 0)
{
Serial.read();
// Gerar um dó - 523Hz
long val = ((freqKC/16L) / 523L);
Serial.println (val);
writeReg (regToneA_Lo, (unsigned char) (val & 0xFF));
writeReg (regToneA_Hi, (unsigned char) ((val >> 8) & 0xFF));
while (Serial.available() == 0)
;
Serial.read();
// Encerra o tom
writeReg (regToneA_Lo, 0);
writeReg (regToneA_Hi, 0);
}
}
// rotina para escrever um valor em um registrador do KC89C72
void writeReg (unsigned char reg, unsigned char valor)
{
// coloca no modo inativo
digitalWrite(pinBC1, LOW);
digitalWrite(pinBCDIR, LOW);
// Coloca na via o endereço do registrador
digitalWrite(pinLatch, LOW);
shiftOut(pinData, pinClock, MSBFIRST, reg);
digitalWrite(pinLatch, HIGH);
// indica escrita de endereço
digitalWrite(pinBC1, HIGH);
digitalWrite(pinBCDIR, HIGH);
// volta ao modo inativo
digitalWrite(pinBC1, LOW);
digitalWrite(pinBCDIR, LOW);
// indica escrita de dado
digitalWrite(pinBC1, LOW);
digitalWrite(pinBCDIR, HIGH);
// Coloca na via o valor do registrador
digitalWrite(pinLatch, LOW);
shiftOut(pinData, pinClock, MSBFIRST, valor);
digitalWrite(pinLatch, HIGH);
// volta ao modo inativo
digitalWrite(pinBC1, LOW);
digitalWrite(pinBCDIR, LOW);
}
Sofisticando um pouco, vamos gerar vários tons e tocar uma musiquinha conforme o caractere recebido pela serial ((KC89C72_B.zip nos arquivos do blog). As alterações no programa são:unsigned freq[7] = {523, 587, 659, 698, 784, 880, 988 };
unsigned nota[7];
int musica[] = {
0, 1, 2, 3, 3, 3, 0, 1, 0, 1, 1, 1, 0, 4, 3, 2, 2, 2,
0, 1, 2, 3, 3, 3, -1
};
// iniciação
void setup ()
{
// ...
// calcula programação das notas
for (int i = 0; i < 7; i++)
{
nota[i] = (unsigned) ((freqKC/16L) / (long) freq[i]);
}
}
// programa principal
void loop ()
{
int c;
if (Serial.available() > 0)
{
c = Serial.read();
if ((c >= '1') && (c <= '7'))
{
writeReg (regToneA_Lo, (unsigned char) (nota[c-'1'] & 0xFF));
writeReg (regToneA_Hi, (unsigned char) ((nota[c-'1'] >> 8) & 0xFF));
delay (500);
writeReg (regToneA_Lo, 0);
writeReg (regToneA_Hi, 0);
}
else if (c == ' ')
{
for (int i = 0; musica[i] != -1; i++)
{
int n = musica[i];
writeReg (regToneA_Lo, (unsigned char) (nota[n] & 0xFF));
writeReg (regToneA_Hi, (unsigned char) ((nota[n] >> 8) & 0xFF));
delay (500);
writeReg (regToneA_Lo, 0);
writeReg (regToneA_Hi, 0);
delay (200);
}
}
}
}
No próximo post vamos brincar um pouco com o gerador de ruídos.


Um comentário:
Uma experiência bacana seria fazer um tocador portátil de arquivos .AY - populares em micros como Sinclair ZX Spectrum e Atari ST. Bastaria incluir um leitor de cartões SD e um display LCD de duas linhas e pronto!
Postar um comentário