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);
- }
- 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);
- }
- }
- }
- }
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