{"id":414,"date":"2017-02-08T02:39:06","date_gmt":"2017-02-08T05:39:06","guid":{"rendered":"http:\/\/omecatronico.com.br\/blog\/?p=414"},"modified":"2017-02-10T12:50:51","modified_gmt":"2017-02-10T15:50:51","slug":"teclado-midi-at89s51","status":"publish","type":"post","link":"https:\/\/omecatronico.com.br\/blog\/teclado-midi-at89s51\/","title":{"rendered":"Teclado MIDI AT89S51"},"content":{"rendered":"<p>Teclado constru\u00eddo por volta de 2009&#8230; com intuito de aprender a programa\u00e7\u00e3o de 8051 utilizando linguagem Assembly e tamb\u00e9m de reutilizar material que iria para o lixo.<\/p>\n<div id=\"attachment_415\" style=\"width: 973px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-415\" class=\"size-full wp-image-415\" src=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1.jpg\" alt=\"teclado MIDI\" width=\"963\" height=\"348\" srcset=\"https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1.jpg 963w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1-300x108.jpg 300w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1-768x278.jpg 768w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/teclado-MIDI-1-210x76.jpg 210w\" sizes=\"(max-width: 963px) 100vw, 963px\" \/><\/a><p id=\"caption-attachment-415\" class=\"wp-caption-text\">teclado Casio reaproveitado<\/p><\/div>\n<p>Um teclado Casio estava para ir pro lixo sem suas placas e bot\u00f5es. Ent\u00e3o veio a ideia de criar um teclado MIDI com o 8051 (<a href=\"http:\/\/www.atmel.com\/images\/doc2487.pdf\">AT89S51<\/a>). Fiz uma <a href=\"http:\/\/omecatronico.com.br\/blog\/placa-de-desenvolvimento-at89s51-8051\/\">placa principal j\u00e1 com o AT89S51<\/a> , uma fonte de 5v, cristal e \u00a0barras de pinos para facilitar projetos (seria uama esp\u00e9cie de Arduino pr\u00e9 hist\u00f3rico \ud83d\ude09 ).<!--more--> Inicialmente a d\u00favida seria como ler as 49 teclas&#8230; a solu\u00e7\u00e3o foi ler em formato de matriz, onde temos 8 linhas e 7 colunas o que d\u00e1 o m\u00e1ximo de 56 teclas. As teclas foram agrupadas e lidas de 8 em 8 sendo que cada uma das 7 colunas \u00e9 acionada de cada vez. Sendo assim, acionando a coluna 1 podemos ler as teclas de 1 a 8 e acionando a coluna 2 teremos leitura das teclas 9 a 16 e por a\u00ed segue. Para isso, foi selecionado o circuito integrado ULN2003 para servir de buffer e selecionar a coluna que estar\u00e1 ativa em cada ciclo.<\/p>\n<div id=\"attachment_426\" style=\"width: 1046px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-426\" class=\"size-full wp-image-426\" src=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi.jpg\" alt=\"Esquema teclado MIDI\" width=\"1036\" height=\"818\" srcset=\"https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi.jpg 1036w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi-300x237.jpg 300w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi-768x606.jpg 768w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi-1024x809.jpg 1024w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/Esquema-teclado-midi-210x166.jpg 210w\" sizes=\"(max-width: 1036px) 100vw, 1036px\" \/><\/a><p id=\"caption-attachment-426\" class=\"wp-caption-text\">Esquema teclado MIDI com AT89S51<\/p><\/div>\n<div id=\"attachment_427\" style=\"width: 1022px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-427\" class=\"size-full wp-image-427\" src=\"http:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI.jpg\" alt=\"Vista interna teclado MIDI\" width=\"1012\" height=\"569\" srcset=\"https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI.jpg 1012w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI-300x169.jpg 300w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI-768x432.jpg 768w, https:\/\/omecatronico.com.br\/blog\/wp-content\/uploads\/2017\/02\/vista-interna-teclado-MIDI-210x118.jpg 210w\" sizes=\"(max-width: 1012px) 100vw, 1012px\" \/><\/a><p id=\"caption-attachment-427\" class=\"wp-caption-text\">Vista interna teclado MIDI<\/p><\/div>\n<p>O programa abaixo fixa uma coluna por vez e l\u00ea linha por linha e depois seleciona a pr\u00f3xima coluna. O estado das teclas s\u00e3o armazenados e a cada loop s\u00e3o comparados.<\/p>\n<ol>\n<li>Se a tecla n\u00e3o estava pressionada e agora est\u00e1? envia comando ON<\/li>\n<li>Se a tecla n\u00e3o estava pressionada e agora tamb\u00e9m n\u00e3o? N\u00e3o faz nada<\/li>\n<li>Se a tecla estava pressionada e agora n\u00e3o est\u00e1? Envia comando OFF<\/li>\n<li>Se a tecla estava pressionada e agora continua pressioanda? N\u00e3o faz nada<\/li>\n<\/ol>\n<p><span style=\"color: #339966;\"> ;www.omecatronico.com.br<\/span><br \/>\n<span style=\"color: #339966;\"> ;Autor: Almir M Ventura<\/span><br \/>\n<span style=\"color: #339966;\"> ;Variaveis e constantes associadas&#8212;&#8212;&#8211;<\/span><br \/>\n<span style=\"color: #339966;\"> ;R0 ponteiro dos bits!<\/span><br \/>\nlinha \u00a0\u00a0<span style=\"color: #00ccff;\">EQU<\/span> R1 \u00a0 \u00a0<span style=\"color: #339966;\">;indica qual linha estamos trabalhando&#8230;<\/span><br \/>\nnota \u00a0 \u00a0<span style=\"color: #00ccff;\">EQU<\/span> R2 \u00a0 \u00a0<span style=\"color: #339966;\">;byte que guarda a nota a ser tocada ou interrompida.<\/span><br \/>\ncanal \u00a0\u00a0<span style=\"color: #00ccff;\">EQU<\/span> R3 \u00a0<span style=\"color: #339966;\">\u00a0;byte que guarda o canal MIDI ( vai de 1 a 16)<\/span><br \/>\ncoluna <span style=\"color: #00ccff;\">EQU<\/span> P1 \u00a0 \u00a0<span style=\"color: #339966;\">;PORT 1 varrer\u00e1 as colunas e PORT 0 ser\u00e3o as linhas<\/span><\/p>\n<p><span style=\"color: #339966;\">;************************* RESET ************************<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 0h \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">; Diretiva de origem no endereco 0h<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> INICIO \u00a0 \u00a0<span style=\"color: #339966;\">; Salto para o inicio do programa<\/span><br \/>\n<span style=\"color: #339966;\">;***INT EXTERNA_0***<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 03h \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">; Externa 0<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> EXTERNA_0 \u00a0\u00a0<span style=\"color: #339966;\">; Salta para Rotina Externa 0<\/span><\/p>\n<p><span style=\"color: #339966;\">;***INT TIMER_0***<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 0Bh \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; TIMER 0<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> TIMER_0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">; Salta para Rotina TIMER 0<\/span><\/p>\n<p><span style=\"color: #339966;\">;***INT EXTERNA_1***<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 13h \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; EXTERNA 1<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> EXTERNA_1 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; Salta para Rotina EXTERNA 1<\/span><\/p>\n<p><span style=\"color: #339966;\">;***INT TIMER_1***<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 1Bh \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">; TIMER 1<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> TIMER_1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; Salta para Rotina TIMER 1<\/span><\/p>\n<p><span style=\"color: #339966;\">;***INT SERIAL***<\/span><\/p>\n<p><span style=\"color: #00ccff;\">ORG<\/span> 23h \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; SERIAL<\/span><br \/>\n<span style=\"color: #0000ff;\">LJMP<\/span> SERIAL_COM \u00a0 \u00a0<span style=\"color: #339966;\">; Salta para Rotina SERIAL_COM<\/span><\/p>\n<p>INICIO:<br \/>\n<span style=\"color: #339966;\">;vamos gravar nas memorias das teclas que elas estavam pressionadas&#8230;<\/span><br \/>\n<span style=\"color: #339966;\"> ;com isso ao ligar vamos enviar off para todas as teclas no primeiro loop!<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 20h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; &#8220;zera&#8221; memoria das teclas 1-&gt;8<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 21h, #0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; 8-&gt;16<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 22h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; 17-&gt;24<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 23h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; 25-&gt;32<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 24h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; teclas 33-&gt;40<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 25h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; teclas 41-&gt;48<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> 26h, #0 \u00a0 \u00a0 <span style=\"color: #339966;\">; teclas 49-&gt;56<\/span><br \/>\n<span style=\"color: #339966;\">;configurando a porta serial&#8230;<\/span><br \/>\n<span style=\"color: #339966;\"> ;timer 1 para 19200 baud<\/span><br \/>\n<span style=\"color: #339966;\"> ;TH1 = 256 &#8211; ((Crystal \/ 192) \/ Baud)<\/span><br \/>\n<span style=\"color: #339966;\"> ;TH1 = 256 &#8211; ((11059000 \/ 192) \/ 57600)<\/span><br \/>\n<span style=\"color: #339966;\"> ;TH1 = 256 &#8211; ((57699) \/ 57600)<\/span><br \/>\n<span style=\"color: #339966;\"> ;TH1 = 256 &#8211; 1 = 255<\/span><\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> PCON,#128 \u00a0 \u00a0<span style=\"color: #339966;\"> ; seta o SMOD para dobrar o Baud Rate<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> TMOD,#00100000B <span style=\"color: #339966;\">;configurar Timer1 no modo 2 (8bits auto recarregavel)<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> TH1,#255 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;seta para 57600 baud o timer1<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> TL1,#255 \u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #339966;\">;<\/span><br \/>\n<span style=\"color: #0000ff;\">SETB<\/span> TR1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;liga timer 1<\/span><\/p>\n<p><span style=\"color: #339966;\">;configurando a serial com SM0=0 SM1=1(8-bit UART Set by Timer 1 (*)) e setando a flag ;TI (de transmissao concluida) &#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">mov<\/span> scon,#01000010B<\/p>\n<p>LOOP:<br \/>\n<span style=\"color: #339966;\">;vamos ler o canal MIDI selecionado<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A,P2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;salva P2 -&gt; Acc<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A,#15<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0;vamos cortar o nible &#8220;alto&#8221; fazedno uma AND 00001111<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> canal, A \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; A -&gt; canal (salvamos canal MIDI no formato 0000xxxx)<\/span><br \/>\n<span style=\"color: #339966;\"> ;lendo qual oitava ser\u00e1 a primeira<\/span><\/p>\n<p><span style=\"color: #339966;\">;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><br \/>\n<span style=\"color: #339966;\"> ; no loop abaixo sempre C \u00e9 o estado atual e A vai com a &#8220;memoria&#8221; anterior<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> R0,#20h \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;inicia o ponteiro R0 com o 1 byte orientado &#8220;bit a bit&#8221; 20h<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> nota,#46 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;inicia na 3 oitava? ser\u00e1?? =D<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> coluna,#1 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;ativa primeira coluna<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#1 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;inicicamos a primeira linha&#8230;<\/span><br \/>\nMINI_LOOP:<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;faz um and entre a e 00000001 entao A ficar\u00e1 com 0000000X<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.0<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE<span style=\"color: #339966;\">\u00a0 \u00a0;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#2 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;indicamos a segunda linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;faz um and entre a e 00000010 entao A ficar\u00e1 com 000000X0<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE \u00a0 \u00a0<span style=\"color: #339966;\">;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#4 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;indicamos a terceira linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;faz um and entre a e 00000100 entao A ficar\u00e1 com 00000X00<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#8 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;indicamos a quarta linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;faz um and entre a e 00001000 entao A ficar\u00e1 com 0000X000<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.3 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE<span style=\"color: #339966;\">\u00a0 \u00a0 ;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#16 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;indicamos a quinta linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;faz um and entre a e 00010000 entao A ficar\u00e1 com 000X0000<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.4 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE \u00a0 \u00a0<span style=\"color: #339966;\">;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#32 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;indicamos a sexta linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span style=\"color: #339966;\">;faz um and entre a e 00100000 entao A ficar\u00e1 com 00X00000<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.5 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#64 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;indicamos a setima linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0;faz um and entre a e 01000000 entao A ficar\u00e1 com 0X000000<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.6 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#128 \u00a0 \u00a0<span style=\"color: #339966;\">;indicamos a oitava linha&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A, @R0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;pega Byte da memoria das 8 teclas atuais e joga no A<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, linha \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;faz um and entre a e 10000000 entao A ficar\u00e1 com X0000000<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> C, P0.7 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;copia valor do pino em C &#8230;e chama sub rotina pra resolver a bronca!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> DECIDE<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0;decide e resolve tudo e depois volta&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">INC<\/span> nota \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;incrementa nota&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">INC<\/span> R0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;incrementa ponteiro dos bits para um novo byte&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A,coluna \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;joga em A a coluna atual<\/span><br \/>\n<span style=\"color: #0000ff;\">RL<\/span> A \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;rotaciona a esquerda<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> coluna,A<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 \u00a0;devolve pra porta a nova coluna<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> linha,#1 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;inicicamos a primeira linha novamente&#8230;<\/span><\/p>\n<p><span style=\"color: #0000ff;\">CJNE<\/span> R0,#27h, MINI_LOOP \u00a0 <span style=\"color: #339966;\">;\u00e9 o byte 27h ? entao continua no MINI_LOOP ate terminarem as 56 teclas&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">SJMP<\/span> LOOP \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;era memoria 27h&#8230;fim do teclado! reiniciar tudo!<\/span><br \/>\n<span style=\"color: #339966;\">;Continua &#8230;<\/span><\/p>\n<p><span style=\"color: #339966;\">;************************* SUB ROTINAS *****************************************<\/span><br \/>\nDECIDE:<br \/>\n<span style=\"color: #0000ff;\">JNC<\/span> PRESSIONADA \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;testa se a tecla esta pressionada (c=0)<\/span><br \/>\n<span style=\"color: #339966;\">;nao esta pressionada (C=1)&#8230;entao ou ja estava assim ou acabou de soltar a tecla!<\/span><br \/>\n<span style=\"color: #0000ff;\">JZ<\/span> SOLTOU \u00a0 \u00a0<span style=\"color: #339966;\">;Acc = 0? pula pra soltou!(significa que memoria constava tecla pressionada = 0)ou seja&#8230;soltou a tecla<\/span><br \/>\n<span style=\"color: #0000ff;\">RET<\/span><span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 ;Acc=1! apenas retorna&#8230; memoria era 1 (tecla estava em repouso&#8230;)<\/span><br \/>\nSOLTOU:<br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A,linha \u00a0 \u00a0<span style=\"color: #339966;\">;linha indica qual bit sera setado!<\/span><br \/>\n<span style=\"color: #0000ff;\">ORL<\/span> A, @R0 \u00a0 \u00a0<span style=\"color: #339966;\">;vamos atualizar o bit da memoria!!! ex se xxxxxxxx OR 00100000 teremos xx1xxxxx setando o bit que queriamos&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> @R0, A<span style=\"color: #339966;\">\u00a0 \u00a0;o resultado jogamos no byte o qual R0 aponta!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> NOTA_OFF \u00a0 \u00a0<span style=\"color: #339966;\">;agora mandamos o comando de desligar<\/span><br \/>\n<span style=\"color: #0000ff;\">RET<\/span><\/p>\n<p>PRESSIONADA:<br \/>\n<span style=\"color: #339966;\">;tecla pressionada&#8230; entao vamos ver se acabou de ser pressionada ou se ja estava pressionada anteriormente!<\/span><br \/>\n<span style=\"color: #0000ff;\">JNZ<\/span> APERTOU \u00a0\u00a0<span style=\"color: #339966;\">;Acc = 1? pula pra apertou!(significa que memoria constava tecla solta = 1)ou seja&#8230;apertou a tecla<\/span><br \/>\n<span style=\"color: #0000ff;\">RET<\/span> \u00a0 \u00a0<span style=\"color: #339966;\">;Acc=0! apenas retorna&#8230; memoria era 0 (tecla estava pressionada ja&#8230;)<\/span><br \/>\nAPERTOU:<br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> A,linha<br \/>\n<span style=\"color: #0000ff;\">CPL<\/span> A \u00a0 \u00a0<span style=\"color: #339966;\">;complementa A ex se 0001 vai para 1110<\/span><br \/>\n<span style=\"color: #0000ff;\">ANL<\/span> A, @R0 \u00a0 \u00a0<span style=\"color: #339966;\">;vamos atualizar o bit da memoria!!! ex se xxx1xxxx AND 11101111 teremos xxx0xxxx zerando o bit que queriamos&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> @R0, A<span style=\"color: #339966;\">\u00a0 \u00a0 ;o resultado jogamos no byte o qual R0 aponta!<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> NOTA_ON<br \/>\n<span style=\"color: #0000ff;\">RET<\/span><\/p>\n<p><span style=\"color: #339966;\">;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><br \/>\nNOTA_ON:<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A, canal \u00a0 \u00a0<span style=\"color: #339966;\">;faz canal -&gt; Acc ( o canal esta no fomato 0000xxxx) onde xxxx representa o numero do canal<\/span><br \/>\n<span style=\"color: #0000ff;\">ORL<\/span> A,#90h \u00a0 \u00a0<span style=\"color: #339966;\">;Nota ON combinada com o canal escolhido (onde ficar\u00e1 1001xxxx)<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A,nota \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;envia o numero da nota<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A,#70 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">;velocidade<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">RET<\/span><br \/>\n<span style=\"color: #339966;\">;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/span><br \/>\nNOTA_OFF:<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A, canal \u00a0 <span style=\"color: #339966;\">;faz canal -&gt; Acc ( o canal esta no fomato 0000xxxx)<\/span><br \/>\n<span style=\"color: #0000ff;\">ORL<\/span> A,#80h \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;Nota OFF combinada com o canal escolhido (onde ficar\u00e1 1000xxxx)<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A,nota<span style=\"color: #339966;\">\u00a0 \u00a0 \u00a0 ;envia o numero da nota<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">MOV<\/span> A,#0 \u00a0 \u00a0 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;velocidade zero significa nota off<\/span><br \/>\n<span style=\"color: #0000ff;\">ACALL<\/span> ENVIA_BYTE<\/p>\n<p><span style=\"color: #0000ff;\">RET<\/span><br \/>\n<span style=\"color: #339966;\">;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<\/span><br \/>\nENVIA_BYTE:<br \/>\n<span style=\"color: #0000ff;\">JNB<\/span> SCON.1,ENVIA_BYTE \u00a0 \u00a0<span style=\"color: #339966;\">;checa se ja nao existe alguma coisa sendo enviada pq a flag ta zerada&#8230;enquanto nao terminar o envio espera&#8230;<\/span><br \/>\n<span style=\"color: #0000ff;\">CLR<\/span> SCON.1 \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">;tx livre! limpa flag de enviado<\/span><br \/>\n<span style=\"color: #0000ff;\">MOV<\/span> SBUF,A \u00a0\u00a0<span style=\"color: #339966;\">;manda enviar o conteudo de Acc<\/span><br \/>\n<span style=\"color: #0000ff;\">RET<\/span><\/p>\n<p><span style=\"color: #339966;\">;************************* TRATAMENTO DAS INTERRUP\u00c7\u00d5ES *************************<\/span><\/p>\n<p>EXTERNA_0: <span style=\"color: #0000ff;\">NOP<\/span> \u00a0 \u00a0\u00a0<span style=\"color: #339966;\">; C\u00f3digo de tratamento de externa0<\/span><br \/>\n<span style=\"color: #0000ff;\">RETI<\/span><\/p>\n<p>TIMER_0: <span style=\"color: #0000ff;\">NOP<\/span> ;<br \/>\n<span style=\"color: #0000ff;\">RETI<\/span><br \/>\nEXTERNA_1: <span style=\"color: #0000ff;\">NOP<\/span> \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; C\u00f3digo de tratamento de externa1<\/span><br \/>\n<span style=\"color: #0000ff;\">RETI<\/span><\/p>\n<p>TIMER_1: <span style=\"color: #0000ff;\">NOP<\/span> \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<span style=\"color: #339966;\">; C\u00f3digo de tratamento de timer1<\/span><br \/>\n<span style=\"color: #0000ff;\">RETI<\/span><\/p>\n<p>SERIAL_COM: <span style=\"color: #0000ff;\">NOP<\/span> \u00a0 \u00a0<span style=\"color: #339966;\">; C\u00f3digo de tratamento de serial<\/span><br \/>\n<span style=\"color: #0000ff;\">RETI<\/span><br \/>\n<span style=\"color: #339966;\">;*******************************************************************************<\/span><\/p>\n<p><span style=\"color: #00ccff;\">END<\/span> <span style=\"color: #339966;\">; Fim de Arquivo p\/ compila\u00e7\u00e3o ufa ;D<\/span><\/p>\n<hr \/>\n<p>Bem espero que seja \u00fatil para algu\u00e9m&#8230; \u00e9 arcaico mas para quem est\u00e1 procurando sobre 8051 \u00e9 uma boa estudar o c\u00f3digo \ud83d\ude09 Quem quiser um c\u00f3digo MIDI em Arduino deixa um coment\u00e1rio explicando o que deseja que <del>quando tiver tempo<\/del> fa\u00e7o um post sobre o assunto.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Teclado constru\u00eddo por volta de 2009&#8230; com intuito de aprender a programa\u00e7\u00e3o de 8051 utilizando linguagem Assembly e tamb\u00e9m de reutilizar material que iria para o lixo. Um teclado Casio estava para ir pro lixo sem suas placas e bot\u00f5es. Ent\u00e3o veio a ideia de criar um teclado MIDI com o 8051 (AT89S51). Fiz uma [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":415,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[27,11,28],"_links":{"self":[{"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/posts\/414"}],"collection":[{"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/comments?post=414"}],"version-history":[{"count":10,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/posts\/414\/revisions"}],"predecessor-version":[{"id":435,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/posts\/414\/revisions\/435"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/media\/415"}],"wp:attachment":[{"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/media?parent=414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/categories?post=414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/omecatronico.com.br\/blog\/wp-json\/wp\/v2\/tags?post=414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}