MP3 Player Standalone - up.edu.br · ANEXO I – CÓDIGO FONTE DO MICROCONTROLADOR ... primeiro o...

69
Centro Universitário Positivo - UnicenP Núcleo de Ciências Exatas e Tecnológicas NCET Engenharia da Computação Eduardo Theiss Przysiezny MP3 Player Standalone Curitiba 2004

Transcript of MP3 Player Standalone - up.edu.br · ANEXO I – CÓDIGO FONTE DO MICROCONTROLADOR ... primeiro o...

Centro Universitário Positivo - UnicenP Núcleo de Ciências Exatas e Tecnológicas – NCET

Engenharia da Computação Eduardo Theiss Przysiezny

MP3 Player Standalone

Curitiba

2004

Centro Universitário Positivo - UnicenP Núcleo de Ciências Exatas e Tecnológicas – NCET

Engenharia da Computação Eduardo Theiss Przysiezny

MP3 Player Standalone

Monografia apresentada à disciplina de Projeto Final, como requisito parcial à conclusão do Curso de Engenharia da Computação. Orientador: Prof. Valfredo Pilla Jr.

Curitiba 2004

TERMO DE APROVAÇÃO

Eduardo Theiss Przysiezny

MP3 Player Standalone

Monografia aprovada como requisito parcial à conclusão do curso de

Engenharia da Computação do Centro Universitário Positivo, pela seguinte banca

examinadora:

Prof. Valfredo Pilla Júnior

Prof. Mauricio Schafranski

Prof. Luiz Carlos Pessoa Albini

Curitiba, 13 de Dezembro de 2004

SUMÁRIO

1. Introdução ........................................................................................................ 11

2. Fundamentação Teórica .................................................................................. 12

2.1. Unidades de Armazenamento ................................................................................................. 12 Memória Flash ...................................................................................................................................... 12 Compact Flash (CF) .............................................................................................................................. 13 Sistema de Arquivos FAT ..................................................................................................................... 14

2.2. Display de Informações .......................................................................................................... 18 ID3 Tag ................................................................................................................................................. 18

2.3. MP3 ......................................................................................................................................... 19

3. Especificação Técnica ..................................................................................... 21

3.1. Descrição Geral do Sistema .................................................................................................... 21

3.2. Especificação de Hardware ..................................................................................................... 22

3.3. Especificação de Software ...................................................................................................... 22

3.4. Especificação de Módulo Adicional ....................................................................................... 23

3.5. Diagrama em blocos dos módulos .......................................................................................... 23

3.6. Módulo de Armazenamento .................................................................................................... 23

3.7. Módulo de Display de Informações ........................................................................................ 23

3.8. Módulo de Controle ................................................................................................................ 24

3.9. Módulo de Microprocessamento ............................................................................................. 24

3.10. Módulo de Decodificação ....................................................................................................... 24

3.11. Módulo de Conversão ............................................................................................................. 24

3.12. Cronograma ............................................................................................................................ 25

3.13. Recursos Necessários .............................................................................................................. 27

3.14. Estimativa de Custos ............................................................................................................... 27

4. Projeto ............................................................................................................. 29

4.1. Diagrama em blocos dos módulos .......................................................................................... 29

4.2. Módulo de Armazenamento .................................................................................................... 30 4.2.1. Componentes necessários para implementação deste módulo ...................................................... 32 4.2.2. Procedimentos para testes ............................................................................................................. 32

4.3. Módulo de Controle e Display de Informações ...................................................................... 32 4.3.1. Componentes necessários para implementação deste módulo ...................................................... 34 4.3.2. Procedimentos para testes ............................................................................................................. 34

4.4. Decodificação MP3 e Conversão D/A .................................................................................... 34 4.4.1. Componentes necessários para implementação deste módulo ...................................................... 36 4.4.2. Procedimentos para testes ............................................................................................................. 36

4.5. Integração entre os módulos ................................................................................................... 36 4.5.1. Lista de Componentes ................................................................................................................... 38

4.6. Projeto de Software ................................................................................................................. 38 4.6.1. Leitura de MP3 do cartão de memória, display de informações e envio para decodificação ........ 38

5. Resultados ....................................................................................................... 40

6. Conclusão ........................................................................................................ 41

7. Referências Bibliográficas ............................................................................... 42

ANEXO I – CÓDIGO FONTE DO MICROCONTROLADOR .................................... 43

LISTA DE FIGURAS Figura 1 - Se você tira a cobertura de um cartão de memória flash, você encontra circuitos de estado sólido. ... 12 Figura 2 - Formato do arquivo MP3 incluindo as Tags ID3 v1 e v1.1 ................................................................. 18 Figura 3 - Diagrama em blocos do sistema .......................................................................................................... 23 Figura 4 - Diagrama em blocos do projeto ........................................................................................................... 29 Figura 5 - Diagrama Esquemático do módulo de armazenamento e interface com o PC .................................... 31 Figura 6 - Diagrama Esquemático do módulo de controle e display de informações .......................................... 33 Figura 7 - Diagrama Esquemático do módulo decodificação MP3 e conversão D/A .......................................... 35 Figura 8 – Integração entre os módulos ................................................................................................................ 37 Figura 9 - Fluxograma geral do algoritmo do microprocessador ......................................................................... 39

LISTA DE TABELAS Tabela 1 - Região Reservada do volume FAT ..................................................................................................... 15 Tabela 2 - Entrada de Diretório de 32 bits ........................................................................................................... 17 Tabela 3 - Estrutura que compõe tags ID3 v1 e v1.1 ........................................................................................... 19 Tabela 4 - Performances típicas da codificação MP3 .......................................................................................... 20 Tabela 5 - Cronograma ........................................................................................................................................ 26 Tabela 6 - Estimativa de Custos .......................................................................................................................... 28

LISTA DE SIGLAS NCET – Núcleo de Ciências Exatas e Tecnológicas UNICENP – Centro Universitário Positivo CF – Compact Flash LCD – Liquid Crystal Interface (Display de Cristal Líquido) MPEG – Moving Pictures Experts Group ISO – International Standards Organization DA – Digital-Analógico

RESUMO

Com o intuito de estudar mídias alternativas de armazenamento e

decodificação MP3, neste trabalho foi projetado um MP3 Player Standalone, ou seja,

um aparelho capaz de reproduzir arquivos de áudio gravados no formato MP3.

Para decodificação MP3 foram estudados chips decodificadores MP3 e o

formato MP3 em geral, como mídia de armazenamento foi estudado o cartão de

armazenamento do tipo Compact Flash, que compõem um das grandes variedades

de mídia de armazenamento compacta dos dias de hoje, e também o sistema de

arquivos FAT16.

Apesar de basicamente o projeto englobar MP3 e mídia de armazenamento

Compact Flash, também serão necessários neste projeto estudos sobre displays

LCD, microprocessadores, sinais analógicos e digitais.

Palavras-Chave: MP3, Compact Flash, FAT16, decodificação, armazenamento.

ABSTRACT

With intention to study alternative storage medias and decoding MP3, this work had for objective the development of a MP3 Player Standalone, or either, a device capable to reproduce archives of audio recorded in MP3 format.

For decoding MP3 have been studied MP3 decoder chips and the MP3 format in general, as media of storage has been studied the storage card Compact Flash, that compose one of the great varieties of compact storage medias of the present, and the FAT16 File System .

Although basically the project is the MP3 format and the Compact Flash storage media, also have been necessary in this project studies on LCD, microprocessors, analogical and digital signals. Keywords: MP3, Compact Flash, FAT16, decoding, storage.

11

1. INTRODUÇÃO

Atualmente com o desenvolvimento de dispositivos de armazenamento cada

vez menores e de maior capacidade, existe um grande foco no desenvolvimento de

aparelhos digitais com tamanho reduzido e grande capacidade de armazenamento.

Dentre estes dispositivos podemos citas máquinas fotográficas digitais, palm tops,

telefones celulares, entre outros.

Uma das tecnologias de armazenamento que vêm sendo muito empregadas

nestes tipos de aparelhos eletrônicos é a memória flash.

Com o intuito de estudar esta tecnologia e também outra tecnologia que a

algum tempo esta em evidência, não só pela sua alta taxa de compressão, mas por

questões éticas, este projeto teve por objetivo o desenvolvimento de um dispositivo

reprodutor de arquivos de áudio no formato MP3 que funcione sem a necessidade

de um computador.

12

2. FUNDAMENTAÇÃO TEÓRICA

Aqui é apresentada a fundamentação teórica para o projeto, que envolve

pesquisas na área de circuitos digitais, unidades de armazenamento e compressão

de arquivos de áudio.

2.1. Unidades de Armazenamento

Mídias de armazenamento secundárias, e dispositivos de armazenamento

existem em quatro categorias principais: magnética, óptica, magneto-óptica, e de

estado sólido. Este projeto prevê o armazenamento em estado sólido.

Memória Flash

Como aumentou a popularidade de dispositivos portáteis como máquinas

fotográficas digitais, registradores de voz, telefones celulares e computadores, assim

também aumento a necessidade por dispositivos de memória pequenos e baratos. O

mais utilizado é o chamado memória flash, às vezes também chamado filme digital.

A memória flash usa chips de estado sólido para armazenar seus arquivos. De

algum modo, estes chips são como os chips de RAM usados dentro de um

computador, mas eles têm uma diferença importante. Eles não requerem nenhuma

bateria e não perdem seus dados quando a bateria acaba. Seus arquivos são retidos

indefinidamente sem qualquer força fornecida aos componentes do Flash. Estes

chips são empacotados dentro de um recipiente com conectores e a unidade inteira

é chamada de um cartão (www.image-digital.com).

Figura 1 - Se você tira a cobertura de um cartão de memória flash, você encontra circuitos de estado

sólido.

13

Até recentemente, a maioria dos cartões de flash estiveram enquadrados no

padrão PC Card (PCMCIA) que é extremamente usado em computadores laptop.

Porém, com o crescimento do mercado da máquina fotográfica digital e outros

dispositivos, foram introduzidos formatos menores. Como resultado da competição,

as máquinas fotográficas apóiam uma confusa variedade de cartões de memória

flash que são incompatíveis entre si, que incluem os seguintes tipos: Cartões de PC,

Compact Flash, Miniature Card, Smart Media, Cartões de Multimídia, Memory Sticks,

entre outros. Este projeto prevê a utilização do tipo Compact Flash.

Compact Flash (CF)

O Compact Flash (CF) é um dispositivo de armazenamento em massa muito

pequeno, ele foi introduzido em 1994, pela Sandisk Corporation. Os cartões têm

1.433-polegadas (36,4 mm) de largura por 1.685-polegadas (42,8 mm) de

comprimento, mais ou menos o tamanho de uma caixa de fósforos e utilizam a

popular arquitetura ATA que emula um disco rígido. Naquela época parecia que o

CF seria o vencedor no jogo da memória flash. Era o formato de armazenamento de

máquina fotográfica mais amplamente utilizado (www.imagem-digital.com). O

formato é apoiado por um número grande de companhias que forma a Compact

Flash Association (www.compactflash.org) para promover a adoção de um único

formato de armazenamento de dados para máquinas fotográficas digitais.

Recentemente o novo cartão CF Tipo II (5mm de espessura) foi introduzido.

Cartões CF Tipo I (3.3mm de espessura) são compatíveis com os CF Tipo II e

podem ser inseridos em qualquer slot para CF Tipo II.

O modo de operação suportado pelo CF é de 3.3V ou 5V, seu conector é

similar ao conector PCMCIA, mas com 50 pinos, suportam nível de vibração de

aproximadamente 2.000 Gs e seus dados são protegidos por tecnologias dinâmicas

internas de gerenciamento de defeito e tecnologias de correção de erros

(www.compactflash.org).

O armazenamento no Compact Flash pode ser de diversos formatos, para este

projeto está prevista a utilização do padrão FAT16 de armazenamento, compatível

com o sistema operacional windows.

14

Sistema de Arquivos FAT

Todos os sistemas de arquivos FAT foram desenvolvidos originalmente para a

arquitetura IBM PC. A importância disto é que o sistema de arquivos FAT

armazenado na estrutura de dados do disco é todo “little endian”. Se olharmos para

uma entrada FAT32 armazenada em um disco como uma série de 4 bytes, sendo

primeiro o byte 0 é o último o byte 3, teremos 32 bits númerados de 00 até 31 (onde

00 é o bit menos significativo e 31 é o bit mais significativo) armazenados da

seguinte maneira:

Byte[3] = 31,30,29,28,27,26,25,24

Byte[2] = 23,22,21,20,19,18,17,16

Byte[1] = 15,14,13,12,11,10,09,08

Byte[0] = 07,06,05,04,03,02,01,00

Isto é importante, pois se a máquina é “big endian machine” será necessário

traduzir os dados de “big” para “little endian” conforme são lidos ou armazenados

dados no disco (MICROSOFT, 2000).

O volume do sistema de arquivos FAT é dividido em quatro regiões básicas,

que estão armazenadas nesta ordem no volume:

0 – Região Reservada

1 – Região FAT

2 – Região do diretório root

3 – Região de arquivos e diretórios

A primeira estrutura de dados importante de um volume FAT é chamada de

“BIOS Parameter Block” (BPB), que está localizada no primeiro setor do volume na

Região Reservada. Este setor é algumas vezes chamado setor de boot, setor

reservado ou setor 0, mas o mais importante é que este é o primeiro setor do

volume.

Na tabela 1 pode ser visualizada a estrutura que compõe a região reservada do

volume FAT.

15

Tabela 1 - Região Reservada do volume FAT

Nome do Campo

Offset (byte)

Tamanho (bytes)

Descrição

BS_jmpBoot 0 3 Instrução Jump para código de boot. Este campo tem dois formatos permitidos: jmpBoot[0] = 0xEB, jmpBoot[1] = 0x??, jmpBoot[2] = 0x90 ou jmpBoot[0] = 0xE9, jmpBoot[1] = 0x??, jmpBoot[2] = 0x?? 0x?? Indica que qualquer valor de 8 bits é permitido neste byte. Este campo forma a instrução de 3 bytes Intel x86 branch incondicional (jump), que realiza o jump para o código de boot do sistema operacional. Este código normalmente ocupa o resto do setor 0. Qualquer uma das duas formas é permitida, sendo normalmente utilizada a forma jmpBoot[0] = 0xEB.

BS_OEMName 3 8 "MSWIN4.1" Existem várias confusões sobre este campo. Este campo é somente uma string. Os sistemas operacionais microsoft não são influenciados por este campo, enquanto que outros sistemas FAT são. Por esta razão a string "MSWIN4.1" é o valor recomendável para este campo. Caso se deseje colocar outro valor para o campo, é possível, mas pode resultar que diversos sistemas FAT não reconhecerão o volume. O valor deste campo normalmente indica que sistema operacional formatou o volume.

BPB_BytsPerSec 11 2 Quantidade de bytes por setor. Este campo pode conter somente os seguintes valores: 512, 1024, 2048 ou 4096. Se for desejavel uma maior compatibilidade com sistemas antigos, deve ser utilizado o valor 512. Sistemas operacionais microsoft suportam todos os valores.

BPB_SecPerClus 13 1 Número de setores por unidade de alocação(cluster). Este valor deve ser uma potência de 2 e maior que 0. Os valores legais são 1, 2, 4, 8, 16, 32, 64 e 128. Note que nunca deve ser utilizado um valor que resulte em "Bytes por Cluster" (BPB_BytsPerSec * BPB_SecPerClus) maior que 32Kbytes (32 * 1024).

BPB_RsvdSecCnt 14 2 Número de setores reservados na Região Reservada do volume. Este campo deve ser diferente de 0, em volumes FAT16 e FAT12 este campo deve ser sempre 1.

BPB_NumFATs 16 1 Quantidade de estrutura de dados FAT no volume. Este campo normalmente contém o valor 2 para volumes FAT de qualquer tipo, mas qualquer valor maior que 2 ou o valor 1 é permitido.

BPB_RootEntCnt 17 2 Para volumes FAT12 e FAT16 este campo contém a quantidade de entradas de diretório (32 bytes) armazenadas no diretório root. Para os volumes FAT12 e FAT16, este campo deve sempre conter uma quantidade que quando multiplicada por 32 resulte em um múltiplo de BPB_BytsPerSec. Para maior compatibilidade, volumes FAT16 devem usar o valor 512.

BPB_TotSec16 19 2 Este é um campo antigo de 16 bits que contém a quantidade de setores do volume. Este campo pode conter o valor 0. Caso contenha 0, então o campo BPB_TotSec32 deve ser diferente de 0. Para volumes FAT32, este campo deve sempre ser 0.

BPB_Media 21 1 0xF8 é o valor padrão para mídias não removíveis. Para mídias removíveis é normalmente utilizado o valor 0xF0. Este campo pode conter os valores 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE ou 0xFF. O mais importante sobre este campo é que o valor deste campo deve também estar no primeiro byte da FAT[0].

16

BPB_FATSz16 22 2 Este campo é a quantidade (16 bits) de setores ocupados por uma FAT12/16. Para volumes FAT32, este campo deve ser 0.

BPB_SecPerTrk 24 2 Setores por trilha para interrupção 0x13. Este campo é relevante apenas para mídias que possuem geometria (volumes são dívididos em trilhas por múltiplas cabeças e cilindros) e são visíveis pela interrupção 0x13.

BPB_NumHeads 26 2 Número de cabeças para interrupção 0x13. Este campo é relevante apenas para mídias que possuem geometria (volumes são dívididos em trilhas por múltiplas cabeças e cilindros) e são visíveis pela interrupção 0x13.

BPB_HiddSec 28 4 Quantidade de Setores escondidos precedendo a partição que contem este volume FAT. Este campo geralmente é relevante para mídias visíveis através da interrupção 0x13. E mídias não particionadas este campo deve ser sempre 0.

BPB_TotSec32 32 4 Este é o campo novo de 32 bits que contém a quantidade de setores do volume. Este campo pode conter o valor 0. Caso contenha 0, então o campo BPB_TotSec16 deve ser diferente de 0. Para volumes FAT32, este campo deve sempre ser diferente de 0.

BS_DrvNum 36 1 Este campo contém o número do driver para interrupção 0x13. Valor 0x00 para disquetes e 0x80 para discos rigído.

BS_Reserved1 37 1 Campo reservado, utilizado pelo Windows NT.

BS_BootSig 38 1 Contém o valor 0x29.

BS_VolID 39 4 Número de série do volume.

BS_VolLab 43 11 Label do Volume.

BS_FilSysType 54 8 Tipo do sistema de arquivos. ("FAT12", "FAT16" ou "FAT32"). Este campo não serve como base para definir o tipo de sistema de arquivos é apenas um campo informativo.

A próxima estrutura importante é a FAT proprieamente dita. Esta estrutura

define uma lista ligada simples de “extensões” (clusters) de um arquivo. Um

apontamento para um diretório FAT é nada mais do que um arquivo regular com um

atributo especial indicando que isto é um diretório. Outra informação importante

sobre diretórios é que o conteúdo do “arquivo” é uma série de entradas de diretório

(32 bytes). A FAT mapeia a região de dados do volume através do número do

cluster. O primeiro clustes de dados é o cluster 2.

Para calcular o ínicio da região de dados é necessário primeiramente calcular a

quantidade de setores que o diretório root ocupa:

RootDirSectors = (( BPB_RootEntCnt * 32 ) + ( BPB_BytsPerSec – 1 )) / BPB_BytsPerSec;

O ínicio da região de dados, o primeiro setor do cluster 2, é calculado da

seguinte maneira:

FirstDataSector = BPB_ResvdSecCnt + ( BPB_NumFATs * FATSz16 ) + RootDirSectors;

17

Um diretório FAT é nada mais do que um “arquivo” composto de uma lista

linear de estruturas de 32 bytes. O único diretórios especial que sempre deve estar

presente é o diretório root. Para volumes FAT12/16 o diretório root está localizado

em uma região fixa, logo após a última estrutura FAT e possui um tamanho fixo de

setores (RootDirSectors). Para FAT12/16 o primeiro setor do diretório root é relativo

ao primeiro setor do volume FAT e pode ser calculado conforme segue:

FirstRootDirSecNum = BPB_ResvdSecCnt + ( BPB_NumFATs * BPB_FATSz16 );

A tabela 2 mostra a estrutura que compõe uma entrada de diretório de 32

bytes.

Tabela 2 - Entrada de Diretório de 32 bits

Nome do Campo

Offset (byte)

Tamanho (bytes)

Descrição

DIR_Name 0 11 Nome curto.

DIR_Attr

11 1

Atributos do arquivo: 0x01 - Somente leitura 0x02 - Oculto 0x04 - Sistema 0x08 - Volume 0x10 - Diretório 0x20 - Arquivo 0x0F - Nome longo

DIR_NTRes 12 1 Reservado, para uso pelo Windows NT.

DIR_CrtTimeTenth 13 1 Milisegundos da criação do arquivo.

DIR_CrtTime 14 2 Hora em que o arquivo foi criado.

DIR_CrtDate 16 2 Date em que o arquivo foi criado.

DIR_LstAccDate 18 2 Data de último acesso ao arquivo.

DIR_FstClusHI

20 2

Word mais significativo que indica o primeiro cluster do arquivo. Deve conter 0 para entradas FAT12/16.

DIR_WrtTime 22 2 Hora da última escrita no arquivo.

DIR_WrtDate 24 2 Data da última escrita no arquivo.

DIR_FstClusLO

26 2 Word menos significativo que indica o primeiro cluster do arquivo.

DIR_FileSize

28 4 Campo de 32 bits que representa o tamanho do arquivo em bytes.

A partir do primeiro cluster de um arquivo pode ser calculado o setor onde este

arquivo está localizado.

ThisFATSecNum = BPB_ResevdSecCnt + (( DIR_FstClusLO * 2 ) / BPB_BytsPerSec );

18

2.2. Display de Informações

Para auxílio ao usuário, faz-se necessária a disponibilização de informações a

respeito da música, tais como gênero, álbum, nome da música, entre outras. Os

arquivos de áudio no formato MP3 possuem uma propriedade, chamada ID3 tag,

que armazena estas informações, esta propriedade será utilizada em conjunto com

um display de cristal líquido (LCD) para disponibilizar informações e auxiliar ao

usuário.

ID3 Tag

Ao produzirem o formato MP3 para compressão de áudio, o formato teve uma

compressão tão proeminente e ainda uma qualidade muito boa, foi adaptado logo

como o padrão para música digital, mas faltava a possibilidade de se incluir

informação textual nos arquivos que utilizavam este formato (ID3 ORG). De repente,

alguém (Erik Kemp) teve a idéia de um bloco de 128 bits que residiria no fim do

arquivo, este bloco iria incluir título, artista, álbum, ano, gênero e comentário. A idéia

foi implementada e logo Michael Mutschler estendeu o bloco, previamente chamado

de ID3 tag, incluindo também a trilha do CD que originou o arquivo MP3 em questão.

Ele usou os dois últimos bytes do comentário para isso, e nomeou esta variante de

ID3 tag v1.1. A figura 2 mostra o formato do arquivo MP3 incluindo a Tag ID3 v1 e

sua variante 1.1.

Figura 2 - Formato do arquivo MP3 incluindo as Tags ID3 v1 e v1.1

19

A tabela 3 mostra a estrutura que compõe as Tags ID3 v1 e v1.1.

Tabela 3 - Estrutura que compõe tags ID3 v1 e v1.1

Dados Tag ID3 v1 Tag ID3 v1.1

Título 30 caracteres 30 caracteres

Artista 30 caracteres 30 caracteres

Álbum 30 caracteres 30 caracteres

Ano 4 caracteres 4 caracteres

Comentário 30 caracteres 28 caracteres

Gênero 1 byte 1 byte

No da Faixa - 1 byte

Possuindo ainda muitas limitações surgiu recentemente a versão 2 do bloco

ID3, que visa melhorar muitas limitações do padrão antigo.

2.3. MP3

Por volta de 1980, no Instituto Fraunhofer na Alemanha um grupo de

pesquisadores desenvolveu um algoritmo para compressão de áudio chamado

Eureka-EU 147, um ano mais tarde foi criado o Moving Pictures Expert Group

(MPEG), que possibilitou ao instituto trabalhar em conjunto com a International

Standards Organization (ISO). Assim, diversas tecnologias para codificação de áudio

e vídeo foram criadas com base no MPEG. Entre estas estava o MPEG Layer 3, o

popular MP3 (JONES, 2000).

Em 1997, Tomislav Uzelac um desenvolvedor da Advanced Multimedia

Products, criou o AMP MP3 Playback Engine, que é considerado o primeiro

reprodutor MP3. Logo uma dupla de universitários, Justin Frankel e Dmirty Boldyrev,

utilizou a engine para criar o WinAMP.

Mas quem popularizou o MP3 foi Shawn Fanning, ao desenvolver um software

que facilitava a troca deste tipo de arquivo através da internet, o Napster (JONES,

2003).

O MP3 é um formato de compressão que diminui arquivos de áudio sem perda

significativa na qualidade do áudio. Este algoritmo permite uma compressão do

20

áudio com uma razão de 11 para 1 (11:1), que rende um arquivo de

aproximadamente 4 Mbytes para uma música de 3 minutos.

As deficiências do ouvido humano são a base técnica para compressão MP3.

O princípio de funcionamento básico do mp3 é buscar num sinal de áudio normal,

como um arquivo wave, todos os sinais redundantes e irrelevantes que não

sensibilizam nosso ouvido. O algoritmo de compactação do mp3 corta freqüências

muito altas, acima dos 20kHz, que não são audíveis pelo ouvido humano. Só aí já

são muitos bits economizados. Em qualquer música, se duas freqüências muito

próximas foram “tocada” ao mesmo tempo, nosso ouvido somente ouvirá a mais

forte, ou seja, o mp3 simplesmente diminui o número de bits desse sinal mais fraco e

mantém os bits do sinal mais forte, diminuindo assim o tamanho final do arquivo na

proporção 11:1 (qualidade semelhante ao CD).

A tabela 4 mostra algumas performances típicas da codificação MP3.

Tabela 4 - Performances típicas da codificação MP3

Qualidade de Som Largura de

Banda

Modo Taxa de Bits

(bitrate)

Razão de

Compacatação

Som de Telefone 2,5 kHz Mono 8 kbps 96:1

Melhor que ondas curtas 4,5 kHz Mono 16 kbps 48:1

Melhor que rádio AM 7,5 kHz Mono 32 kbps 24:1

Similar ao rádio FM 11 kHz Stereo 56..64 kbps 26..24:1

Próximo de CD 15 kHz Stereo 96 kbps 16:1

CD >15 kHz Stereo 112..128 kbps 14..12:1

21

3. ESPECIFICAÇÃO TÉCNICA

A descrição a seguir apresenta os módulos de hardware e software

identificando quais as tecnologias, técnicas e procedimentos utilizados.

O projeto é dividido em módulos:

- Hardware

o Módulo de Armazenamento

o Módulo de Display de Informações

o Módulo de Controle

o Módulo de Microprocessamento

o Módulo de Decodificação

o Módulo de Conversão

- Software

o Módulo de Microprocessamento

3.1. Descrição Geral do Sistema

O projeto consiste em um dispositivo capaz de reproduzir arquivos de áudio

codificados no formato MP3. Este dispositivo não depende do microcomputador para

a reprodução destes arquivos, trata-se de um dispositivo standalone. Um dispositivo

portátil que poderá ser utilizado dentro de um automóvel ou até mesmo durante uma

caminhada pelo usuário do mesmo.

Para armazenamento dos arquivos de áudio no formato MP3 este dispositivo

utilizará um cartão de memória do tipo compact flash, este tipo de cartão vem sendo

muito utilizado nos dias de hoje em diversos dispositivos digitais portáteis, como

máquinas fotográficas digitais, palm tops, entre outros.

Para a leitura dos arquivos do cartão de memória será utilizado em

microprocessador do tipo PIC, que também irá ler informações sobre as músicas

para posteriormente disponibilizar estas informações em um display de cristal

líquido. Além destas funções o microprocessador também executará funções de

comandos sobre as músicas do cartão, tais como ir para a próxima música, voltar

para música anterior, pausar, parar, reproduzir, entre outras. Estas funções serão

chamadas através de botões do tipo push-button.

22

Depois de realizada a leitura da música armazenada no cartão, esta deverá ser

decodificada. Este trabalho será feito por um chip decodificador de MP3, o qual

transformará o arquivo em áudio digital, que posteriormente será transformado em

áudio analógico através de um conversor DA (Digital-Analógico), com uma saída de

áudio para um fone de ouvido ou uma caixa de som.

3.2. Especificação de Hardware

Os seguintes módulos de hardware compõem o sistema:

Módulo de Armazenamento

Cartão de memória Compact Flash, conector para memória Compact

Flash.

Módulo de Display de Informações

Display de Cristal Líquido.

Módulo de Controle

Push-Buttons.

Módulo de Microprocessamento

Microprocessador PIC.

Módulo de Decodificação

Chip decodificador de MP3.

Módulo de Conversão

Chip de conversão Digital para Analógico.

3.3. Especificação de Software

O sistema é composto por software de leitura do cartão de memória Compact

Flash, identificação do padrão FAT16, busca dos arquivos armazenados no cartão,

reprodução dos arquivos armazenados no cartão, controle de reprodução de áudio,

leitura de informações da música e display de informações em LCD, através de

linguagem C para microprocessadores PIC.

23

3.4. Especificação de Módulo Adicional

O módulo adicional consiste em hardware e software para transferência de

arquivos de áudio no formato MP3 entre o PC e o dispositivo.

3.5. Diagrama em blocos dos módulos

A figura 3 apresenta o diagrama em blocos do sistema, conforme os módulos

que serão implementados.

Figura 3 - Diagrama em blocos do sistema

3.6. Módulo de Armazenamento

O módulo de armazenamento é composto por um cartão de memória do tipo

Compact Flash, onde estarão armazenados os arquivos de áudio no formato MP3, e

um conector para a memória Compact Flash, que possui interface com o módulo de

microprocessamento.

3.7. Módulo de Display de Informações

O módulo de display de informações é composto por um LCD de 84x48 pixels

de resolução com controlador PCD8544, que possui interface com o módulo de

24

microprocessamento, de modo a disponibilizar informações referentes à música que

estará sendo reproduzida.

3.8. Módulo de Controle

O módulo de controle é composto por botões do tipo push-button, que serão

responsáveis pelo controle de reprodução do arquivo de áudio, tais como reproduzir,

pausar, parar, próxima música, música anterior, entre outros, este módulo possui

interface direta com o módulo de microprocessamento.

3.9. Módulo de Microprocessamento

O módulo de microprocessamento é composto por um microprocessador PIC

da microchip e possui interface com os principais módulos do sistema, este módulo

é o responsável pelas principais atividades de gerenciamento do sistema, através de

interface com o módulo de armazenamento este módulo realizará a obtenção dos

arquivos de áudio em formato MP3, realizará a leitura deste arquivo enviando suas

informações para o módulo de display de informações e enviando o áudio para o

módulo de decodificação, também realizará interface com o módulo de controle

esperando sinais de controle e dependendo dos sinais recebidos realizará as

funções de início da reprodução do arquivo de áudio, pausa, busca da próxima

música, busca da música anterior, entre outras.

Os algoritmos deste módulo serão implementados através de linguagem C e

assembly para microprocessadores PIC.

3.10. Módulo de Decodificação

O módulo de decodificação é composto por um decodificador MP3 VS1001K,

que realiza a decodificação do arquivo de áudio em formato MP3 para o formato

digital de áudio e o envia para o Módulo de Conversão, este módulo também possui

interface com o Módulo de Microprocessamento.

3.11. Módulo de Conversão

25

O módulo de conversão é composto por um chip de conversão Digital-

Analógico (DA) que através da interface com o módulo de decodificação recebe o

arquivo de áudio em formato digital e realiza a sua saída em formato analógico, esta

saída pode ser conectada a um fone de ouvido ou caixa de som.

3.12. Cronograma

A tabela 5 apresenta o cronograma do projeto em relação aos meses e

semanas de desenvolvimento.

26

Tabela 5 - Cronograma

27

3.13. Recursos Necessários

A plataforma de desenvolvimento está relacionada às ferramentas e

equipamentos utilizados durante o período de graduação juntamente com as

necessidades do projeto bem como a familiaridade da linguagem de

desenvolvimento e dos tipos de equipamentos e dispositivos que se encontra no

mercado. Incorporando todo o hardware e software necessário para o

desenvolvimento e implementação do projeto.

O ambiente de desenvolvimento é constituído basicamente por:

o Computador Pentium III 1GHz, 128 Mb RAM;

o Sistema Operacional Microsoft Windows 2000 BR;

o Acesso à internet;

o Borland C++ Builder 5;

o Compilador CSS para PIC;

o OrCAD Release 10;

o Microsoft Office 2000;

o MPLab 6.22;

o Osciloscópio;

o Multímetro;

o Fonte de alimentação;

3.14. Estimativa de Custos

A estimativa de custo/investimento do projeto toma como base de cálculo os

valores dos produtos, dispositivos e horas de desenvolvimento associadas ao

projeto. Esses valores refletem os gastos que serão necessários para o

desenvolvimento do projeto como um todo.

Existem ainda alguns valores que não são considerados, por tanto não

agregam valo real ao projeto, esses valores estão relacionados a alguns softwares e

equipamentos que são cedidos pela universidade.

A tabela 6 descreve os custos tanto de software como de hardware

desconsiderando os dispositivos, equipamentos entre outros, necessários para o

desenvolvimento do projeto.

28

Tabela 6 - Estimativa de Custos

Recurso Quantidade Custo

Microcomputador Pentium III 1GHz, 128

Mb RAM

1 1600, 00 R$

Sistema Operacional Windows 1 500,00 R$

Borland C++ Builder 1 350,00 R$

Microprocessador PIC 1 40,00 R$

Conversor DA 1 7, 00 U$

Connector Compact Flash 1 6,00 U$

Cartão Compact Flash 256 Mb 1 160,00 R$

Display de Cristal Líquido 1 9,00 U$

Horas de Desenvolvimento 350 8.750,00 R$

Compilador C CSS para PIC 1 500,00 R$

Taxas de Importação/Correio 1 150,00 R$

Outros Equipamentos de Laboratório 10000,00 R$

Total 22.640,00 R$ e 24,00 U$

29

4. PROJETO

A descrição a seguir apresenta os módulos de hardware e software

projetados conforme a descrição mencionada na seção 3.1, identificando quais as

tecnologias, técnicas e procedimentos utilizados a fim de atingir os objetivos

descritos na proposta e na especificação do projeto.

O desenvolvimento do projeto é classificado da seguinte forma:

Projeto de Hardware

o Armazenamento

o Controle e display de informações

o Decodificação MP3 e Conversão DA

Projeto de Software

o Leitura de MP3 do cartão de memória, display de informações e

envio para decodificação.

4.1. Diagrama em blocos dos módulos

A figura 4 apresenta o diagrama em blocos do sistema conforme os módulos

que serão implementados. Dividido em:

1. Projeto de hardware: “Armazenamento”, “Controle e display de informações”

e “Decodificação MP3 e Conversão DA”.

2. Projeto de software: “Leitura de MP3 do cartão de memória, display de

informações e envio para decodificação”.

Figura 4 - Diagrama em blocos do projeto

30

4.2. Módulo de Armazenamento

O módulo de armazenamento é composto por um cartão de memória do tipo

Compact Flash, um microcontrolador para leitura das informações do cartão e um

display para disponibilização de informações do cartão.

31

Figura 5 - Diagrama Esquemático do módulo de armazenamento

32

4.2.1. Componentes necessários para implementação deste módulo

1 Microprocessador microchip PIC16F877

2 Resistores de 10 k ohms

2 Capacitores de 22 pF.

1 Capacitor de 10 uF.

1 Capacitor de 47 uF.

1 Cristal de 4 MHz.

1 Conector de Compact Flash tipo 1.

1 Push-Button.

4.2.2. Procedimentos para testes

Para testes deste módulo deve-se realizar alimentação 5V, conforme

especificado no diagrama esquemático.

Depois de realizada a alimentação, serão disponibilizadas no LCD as

informações contidas no cartão de memória.

4.3. Módulo de Controle e Display de Informações

O módulo de controle e display de informações é composto por um display LCD

e botões do tipo push-buttons.

Através deste módulo será realizado o controle de reprodução das músicas e

display de informações para o usuário, sobre a música e sobre os comandos

executados.

33

Figura 6 - Diagrama Esquemático do módulo de controle e display de informações

34

4.3.1. Componentes necessários para implementação deste módulo

1 Microprocessador microchip 16LF877A.

1 Display de LCD PCD8544.

5 botões push-button

1 Cristal de 4 MHz.

6 Resistores de 10 k ohms.

1 Capacitor de 10 uF.

1 Capacitor de 47 uF.

2 Capacitores de 22 pF.

4.3.2. Procedimentos para testes

Para testes deste módulo deve-se realizar alimentação 5V, conforme

especificado no diagrama esquemático.

Depois de realizada esta alimentação, deverá aparecer uma imagem no

display solicitando que seja pressionado um dos 5 push-buttons, deve se então

pressionar os push-buttons em ordens aleatórias, conforme cada push-button for

pressionado, deverá ser disponibilizada a informação de que função foi ativada no

display de informações.

4.4. Decodificação MP3 e Conversão D/A

O módulo de decodificação MP3 é composto por um chip que decodifica o

arquivo MP3 recebido do microprocessador, decodifica e realiza a conversão DA.

Através deste módulo será realizada a leitura da música e esta será

transformada em áudio.

35

Figura 7 - Diagrama Esquemático do módulo decodificação MP3 e conversão D/A

36

4.4.1. Componentes necessários para implementação deste módulo

1 Microprocessador microchip PIC16LF877A

1 Chip decodificador de MP3 e conversor DA VS1001K

2 Resistores de 10 k ohms

1 Indutor de 10 uH

2 Capacitores de 22 pF.

3 Capacitores de 100 nF.

2 Capacitores de 100 uF.

2 Capacitores de 10 uF.

2 Capacitores de 22 pF.

1 Cristal de 12 MHz.

1 Cristal de 4 MHz.

1 Conector de áudio.

4.4.2. Procedimentos para testes

Para testes deste módulo deve-se realizar alimentação 5V, conforme

especificado no diagrama esquemático.

Depois de realizada esta alimentação, serão executadas funções de teste,

presentes no próprio chip decodificador, que irão gerar uma onda senoidal para teste

de áudio.

4.5. Integração entre os módulos

A integração entre os módulos é apresentada na figura 8, e representa o

projeto finalizado.

37

Figura 8 – Integração entre os módulos

38

4.5.1. Lista de Componentes

1 Microcontrolador Microchip PIC16LF877A

1 Display LCD PCD8544

1 Memória Compact Flash

1 Decodificador MP3 VS1001k

1 Conector para fone

1 Cristal 12 MHz

1 Cristal 12.288 MHz

1 Regulador de Tensão LM317

1 Resistor 330 ohms

1 Resistor 3.3 k ohms

6 Resistores 10k ohms

1 Resistor de 1 M ohm

4 Capacitores 10uF

1 Capacitor 47 uF

2 Capacitores 100 uF

2 Capacitores 22 pF

2 Capacitores 33 pF

3 Capacitores 100 nF

2 Indutores de 10 uH

4.6. Projeto de Software

O projeto de software consiste em um programa, que está relacionado ao

microprocessador PIC16LF877A, que tem por função realizar a leitura e gravação de

arquivos no cartão de memória Compact Flash, disponibilizar estes arquivos para o

decodificador MP3 e disponibilizar informações destes arquivos no display LCD.

4.6.1. Leitura de MP3 do cartão de memória, display de informações e envio para decodificação

Este software tem por função realizar a administração básica das operações

realizadas pelo dispositivo, como leitura de arquivos do cartão de memória, display

de informações e envio de dados para decodificação.

39

O fluxograma apresentado na figura 9 representa a visão geral do algoritmo

implementado. Este algoritmo se refere ao microprocessador PIC16LF877A.

Figura 9 - Fluxograma geral do algoritmo do microprocessador

40

5. RESULTADOS

O projeto foi totalmente desenvolvido utilizando linguagem de programação C

para microcontroladores PIC, para compilação do código fonte foi utilizado o

compilador CCS. Isto facilitou o desenvolvimento do software de forma a possibilitar

um melhor entendimento do código e o desenvolvimento facilitado de funções mais

complexas.

Foi implementado no software executado pelo microprocessador o algoritmo de

reconhecimento do padrão de formatação FAT16, de leitura da lista de arquivos

armazenados e de leitura do conteúdo dos arquivos, tornando o dispositivo

compatível com o padrão FAT16, permitindo então que este padrão fosse utilizado

para o armazenamento das músicas no cartão de memória Compact Flash. Isto

possibilitou a utilização do cartão de memória também para o armazenamento de

arquivos que não estivessem no formato MP3, maximizando a utilização do cartão,

podendo este ser utilizado não só para o armazenamento de músicas, mas também

para a troca de arquivos de diferentes formatos.

O padrão de formatação FAT16 também viabilizou a leitura dos arquivos de

forma seqüencial e numerada, podendo ser feita a referencia a um arquivo apenas

informando seu índice, e ainda cópia dos arquivos do computador para o cartão de

memória de forma facilitada, sendo que qualquer computador que possui um

dispositivo de leitura de cartões compact flash consegue reconhecer o cartão como

uma unidade de disco.

Por motivos de atraso no projeto a unidade de controle não foi implementada,

portanto o projeto ficou incompleto quanto a navegação entre as músicas e controle

de volume. Desta maneira a leitura dos arquivos MP3 foi implementada de forma

seqüencial e o volume foi iniciado com seu valor máximo.

Inicialmente houve problemas com a decodificação dos arquivos MP3, pois a

velocidade com que o microprocessador enviava os bytes de áudio dos arquivos

MP3 para o decodificador MP3 estava muito lenta. Apenas com a melhora nas

rotinas de envio de bytes de áudio para o decodificador MP3 foi possível aumentar

esta velocidade, o que tornou a decodificação do áudio possível.

41

6. CONCLUSÃO

A utilização do cartão de memória Compact Flash mostrou-se eficiente e de

baixo custo para o desenvolvimento de aparelhos digitais portáteis e o padrão de

formatação FAT16, utilizado no cartão de memória, mostrou-se muito útil na troca

de arquivos entre o dispositivo e um computador com sistema operacional

Windows, viabilizando a utilização do cartão de memória para armazenamento

de outros tipos de arquivos que não sejam apenas os arquivos utilizados pelo

dispositivo.

O controle de navegação entre as músicas, apesar de não implementado

por motivos de atraso no projeto, mostra-se teoricamente viável e de fácil

implementação devido à utilização do padrão de formatação FAT16 que cria uma

lista seqüencial e numerada dos arquivos armazenados na Compact Flash.

O mesmo ocorre para o controle de volume que pode ser feito apenas

enviando informações de controle para o chip decodificador MP3.

A decodificação MP3 em um dispositivo portátil mostrou-se viável e foi

realizada de forma simples, com baixo custo e alta qualidade, podendo ainda o

decodificador ser utilizado como um processador digital de sinais.

42

7. REFERÊNCIAS BIBLIOGRÁFICAS

PEREIRA, Fábio. Microcontroladores PIC: Programação em C – São Paulo,

Editora Érica, 2003.

http://www.compactflash.org

http://www.imagem-digital.com

MICROSOFT. FAT: General Overview of On-Disk Format

(http://www.microsoft.com/hwdev/download/hardware/fatgen103.pdf) - 2000.

ID3 ORG. The short history of tagging (http://www.id3.org/history.html).

JONES, Cristopher. Behind the Music: The History of MP3

(http://hotwired.lycos.com/webmonkey/00/31/index3a.html) - 2000.

What is MP3, how does it work, what is MPEG ? (http://www.mp3-

mac.com/Pages/What_is_MP3.html)

FRAUNHOFER – Institut Integrierte Schaltungen. Audio & Multimedia MPEG

Audio Layer-3 (http://www.iis.fraunhofer.de/amm/techinf/layer3/index.html).

www.vlsi.fi

43

ANEXO I – CÓDIGO FONTE DO MICROCONTROLADOR

<principal.c>

#include <16f877a.h>

#use delay(clock=12000000)

#use fast_io(A)

#use fast_io(B)

#use fast_io(C)

#use fast_io(D)

#use fast_io(E)

#fuses HS, NOWDT, NOPROTECT, PUT

#include "lcd.h"

#include "vs1001k.h"

#include "compactflash.h"

#include "fat.h"

#include <string.h>

/**************************************************/

/* */

/* Função Principal */

/* */

/**************************************************/

void main()

{

// Inicialização do LCD

lcd_init();

set_tris_C(0x12);

lcd_clrscr();

lcd_gotoXY(0,0);

printf(lcd_printChar, "Inicializando");

lcd_gotoXY(1,1);

printf(lcd_printChar, "Compact Flash");

delay_ms(5000);

// Inicialização da Compact Flash

compactFlashInit();

compactFlashCheckCard();

compactFlashDiagnostic();

// Inicialização do Decodificador

vs__init();

// Testes do Decodificador de Áudio

lcd_clrscr();

printf(lcd_printChar, "Testando audio");

// Teste de Seno

vs__send_sinewave_beeps();

vs__sine_sweep();

// Realiza leitura dos arquivos e reprodução das músicas

lcd_gotoXY(0,0);

find_bpb();

printout_rootdir();

lcd_clrscr();

printf(lcd_printChar, "Nao ha mais arquivos!!!");

}

44

<lcd.h>

/**************************************************/

/* */

/* Biblioteca de funções para funcionamento do LCD */

/* */

/**************************************************/

/**************************************************/

/* */

/* Defines de Pinos */

/* */

/**************************************************/

#define sclk pin_b6 //16F877

#define sdta pin_b5 //16F877

#define dorc pin_b4 //16F877

#define rset pin_b2 //16F877

#define enab pin_b3 //16F877

/**************************************************/

/* */

/* Constante para escrita de caracteres */

/* */

/**************************************************/

BYTE CONST TABLE4 [6]= {125,250,001,125,250,001};

BYTE CONST TABLE5 [240]={0x00,0x00,0x00,0x00,0x00, // 20 espaço Tabela ASCII para o LCD

NOKIA: 96 linhas * 5 bytes= 480 bytes

0x00,0x00,0x5f,0x00,0x00, // 21 !

0x00,0x07,0x00,0x07,0x00, // 22 "

0x14,0x7f,0x14,0x7f,0x14, // 23 #

0x24,0x2a,0x7f,0x2a,0x12, // 24 $

0x23,0x13,0x08,0x64,0x62, // 25 %

0x36,0x49,0x55,0x22,0x50, // 26 &

0x00,0x05,0x03,0x00,0x00, // 27 '

0x00,0x1c,0x22,0x41,0x00, // 28 (

0x00,0x41,0x22,0x1c,0x00, // 29 )

0x14,0x08,0x3e,0x08,0x14, // 2a *

0x08,0x08,0x3e,0x08,0x08, // 2b +

0x00,0x50,0x30,0x00,0x00, // 2c ,

0x08,0x08,0x08,0x08,0x08, // 2d -

0x00,0x60,0x60,0x00,0x00, // 2e .

0x20,0x10,0x08,0x04,0x02, // 2f /

0x3e,0x51,0x49,0x45,0x3e, // 30 0

0x00,0x42,0x7f,0x40,0x00, // 31 1

0x42,0x61,0x51,0x49,0x46, // 32 2

0x21,0x41,0x45,0x4b,0x31, // 33 3

0x18,0x14,0x12,0x7f,0x10, // 34 4

0x27,0x45,0x45,0x45,0x39, // 35 5

0x3c,0x4a,0x49,0x49,0x30, // 36 6

0x01,0x71,0x09,0x05,0x03, // 37 7

0x36,0x49,0x49,0x49,0x36, // 38 8

0x06,0x49,0x49,0x29,0x1e, // 39 9

0x00,0x36,0x36,0x00,0x00, // 3a :

0x00,0x56,0x36,0x00,0x00, // 3b ;

0x08,0x14,0x22,0x41,0x00, // 3c <

0x14,0x14,0x14,0x14,0x14, // 3d =

0x00,0x41,0x22,0x14,0x08, // 3e >

0x02,0x01,0x51,0x09,0x06, // 3f ?

0x32,0x49,0x79,0x41,0x3e, // 40 @

0x7e,0x11,0x11,0x11,0x7e, // 41 A

0x7f,0x49,0x49,0x49,0x36, // 42 B

0x3e,0x41,0x41,0x41,0x22, // 43 C

0x7f,0x41,0x41,0x22,0x1c, // 44 D

0x7f,0x49,0x49,0x49,0x41, // 45 E

45

0x7f,0x09,0x09,0x09,0x01, // 46 F

0x3e,0x41,0x49,0x49,0x7a, // 47 G

0x7f,0x08,0x08,0x08,0x7f, // 48 H

0x00,0x41,0x7f,0x41,0x00, // 49 I

0x20,0x40,0x41,0x3f,0x01, // 4a J

0x7f,0x08,0x14,0x22,0x41, // 4b K

0x7f,0x40,0x40,0x40,0x40, // 4c L

0x7f,0x02,0x0c,0x02,0x7f, // 4d M

0x7f,0x04,0x08,0x10,0x7f, // 4e N

0x3e,0x41,0x41,0x41,0x3e // 4f O

};

BYTE CONST TABLE6 [240]={

0x7f,0x09,0x09,0x09,0x06, // 50 P

0x3e,0x41,0x51,0x21,0x5e, // 51 Q

0x7f,0x09,0x19,0x29,0x46, // 52 R

0x46,0x49,0x49,0x49,0x31, // 53 S

0x01,0x01,0x7f,0x01,0x01, // 54 T

0x3f,0x40,0x40,0x40,0x3f, // 55 U

0x1f,0x20,0x40,0x20,0x1f, // 56 V

0x3f,0x40,0x38,0x40,0x3f, // 57 W

0x63,0x14,0x08,0x14,0x63, // 58 X

0x07,0x08,0x70,0x08,0x07, // 59 Y

0x61,0x51,0x49,0x45,0x43, // 5a Z

0x00,0x7f,0x41,0x41,0x00, // 5b [

0x02,0x04,0x08,0x10,0x20, // 5c

0x00,0x41,0x41,0x7f,0x00, // 5d

0x04,0x02,0x01,0x02,0x04, // 5e

0x40,0x40,0x40,0x40,0x40, // 5f

0x00,0x01,0x02,0x04,0x00, // 60

0x20,0x54,0x54,0x54,0x78, // 61 a

0x7f,0x48,0x44,0x44,0x38, // 62 b

0x38,0x44,0x44,0x44,0x20, // 63 c

0x38,0x44,0x44,0x48,0x7f, // 64 d

0x38,0x54,0x54,0x54,0x18, // 65 e

0x08,0x7e,0x09,0x01,0x02, // 66 f

0x0c,0x52,0x52,0x52,0x3e, // 67 g

0x7f,0x08,0x04,0x04,0x78, // 68 h

0x00,0x44,0x7d,0x40,0x00, // 69 i

0x20,0x40,0x44,0x3d,0x00, // 6a j

0x7f,0x10,0x28,0x44,0x00, // 6b k

0x00,0x41,0x7f,0x40,0x00, // 6c l

0x7c,0x04,0x18,0x04,0x78, // 6d m

0x7c,0x08,0x04,0x04,0x78, // 6e n

0x38,0x44,0x44,0x44,0x38, // 6f o

0x7c,0x14,0x14,0x14,0x08, // 70 p

0x08,0x14,0x14,0x18,0x7c, // 71 q

0x7c,0x08,0x04,0x04,0x08, // 72 r

0x48,0x54,0x54,0x54,0x20, // 73 s

0x04,0x3f,0x44,0x40,0x20, // 74 t

0x3c,0x40,0x40,0x20,0x7c, // 75 u

0x1c,0x20,0x40,0x20,0x1c, // 76 v

0x3c,0x40,0x30,0x40,0x3c, // 77 w

0x44,0x28,0x10,0x28,0x44, // 78 x

0x0c,0x50,0x50,0x50,0x3c, // 79 y

0x44,0x64,0x54,0x4c,0x44, // 7a z

0x00,0x08,0x36,0x41,0x00, // 7b

0x00,0x00,0x7f,0x00,0x00, // 7c

0x00,0x41,0x36,0x08,0x00, // 7d

0x10,0x08,0x08,0x10,0x08, // 7e

0x78,0x46,0x41,0x46,0x78 // 7f

};

46

/**************************************************/

/* */

/* Protótipo de Funções */

/* */

/**************************************************/

void lcd_init();

void lcd_reset();

void lcd_sendCmd(unsigned int cmd);

void lcd_sendData(unsigned int data);

void lcd_sendSerialByte(unsigned int byte);

void lcd_clrscr();

void lcd_sendClock();

void lcd_gotoXY(unsigned int xNokia, unsigned int yNokia);

void lcd_printchar(unsigned int cvar);

/**************************************************/

/* */

/* Função de inicialização do LCD */

/* */

/**************************************************/

void lcd_init()

{

set_tris_B(0x00);

output_high(dorc);

output_high(enab);

lcd_reset();

lcd_sendCmd(0x21); //000100001 - PD=0 (chip ative), V=0 (Horizontal mode), H=1 (Extended

Instruction set)

lcd_sendCmd(0xC5); //011000101 - Vop

lcd_sendCmd(0x13); //000010011 - Bias system: (Mux = 1:48)

lcd_sendCmd(0x20); //000100000 - PD=0 (chip ative), V=0 (Horizontal mode), H=0 (Basic Instruction

Set)

lcd_clrscr();

lcd_sendCmd(0x09); //000001001 - Display Configuration (D=0, E=1) -> all segments on

lcd_sendCmd(0x08); //000001000 - Display configuration (D=0, E=0) -> display blank

lcd_sendCmd(0x0C); //000001100 - Display configuration (D=1, E=0) -> Normal Mode

lcd_sendCmd(0x40); //001000000 - Y address=0

lcd_sendCmd(0x80); //010000000 - X address=0

}

/**************************************************/

/* */

/* Função de Reset do LCD */

/* */

/**************************************************/

void lcd_reset()

{

output_low(rset);

delay_ms(250);

output_high(rset);

}

/**************************************************/

/* */

/* Função de envio de comando para o LCD */

/* */

/**************************************************/

void lcd_sendCmd(unsigned int cmd)

47

{

output_low(dorc);

output_low(enab);

lcd_sendSerialByte(cmd);

output_high(enab);

}

/**************************************************/

/* */

/* Função de envio de dados para o LCD */

/* */

/**************************************************/

void lcd_sendData(unsigned int data)

{

output_high(dorc);

output_low(enab);

lcd_sendSerialByte(data);

output_high(enab);

}

/**************************************************/

/* */

/* Função de envio de um byte serial para o LCD */

/* */

/**************************************************/

void lcd_sendSerialByte(unsigned int serialByte)

{

/*

// Comparador utilizado para enviar um byte completo serialmente para o LCD.

7F - 01111111

BF - 10111111

DF - 11011111

EF - 11101111

F7 - 11110111

FB - 11111011

FD - 11111101

FE - 11111110

*/

unsigned int comparator[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFd, 0xFE };

unsigned int counter;

for(counter = 0; counter < 8; counter++)

{

output_low(sclk);

if( (serialByte|comparator[counter]) == 0xFF)

{

output_high(sdta);

}

else

{

output_low(sdta);

}

//delay_us(3);

output_high(sclk);

//delay_us(3);

}

output_low(sclk);

}

/**************************************************/

/* */

/* Função de limpeza do LCD */

/* */

/**************************************************/

48

void lcd_clrscr()

{

unsigned long int counter;

output_high(dorc);

output_low(enab);

output_low(sdta);

for(counter = 0; counter < 4032; counter++)

{

output_low(sclk);

output_high(sclk);

}

output_low(sclk);

output_high(enab);

lcd_gotoXY(0,0);

}

/**************************************************/

/* */

/* Função de envio de clock para o LCD */

/* */

/**************************************************/

void lcd_sendClock()

{

output_low(sclk);

output_high(sclk);

}

/**************************************************/

/* */

/* Função de posicionamento de cursor no LCD */

/* */

/**************************************************/

void lcd_gotoXY(unsigned int xNokia, unsigned int yNokia)

{

lcd_sendCmd(0x40|(yNokia&0x07)); // inicialização de Y (linha) : 0100 0yyy

lcd_sendCmd(0x80|(xNokia&0x7f)); // inicialização de X (coluna): 1xxx xxxx

}

/**************************************************/

/* */

/* Função de escrita de texto no LCD */

/* */

/**************************************************/

void lcd_printChar(unsigned int charsel)

{

unsigned int char_row;

unsigned int charpos;

unsigned int chardata;

if(charsel=='á' || charsel=='à' || charsel=='â' || charsel=='ã')

charsel='a';

if(charsel=='é' || charsel=='è' || charsel=='ê')

charsel='e';

if(charsel=='í' || charsel=='ì' || charsel=='î')

charsel='i';

if(charsel=='ó' || charsel=='ò' || charsel=='ô' || charsel=='õ')

charsel='o';

if(charsel=='ú' || charsel=='ù' || charsel=='û')

charsel='u';

if(charsel=='ç')

charsel='c';

if(charsel=='ñ')

49

charsel='n';

if(charsel=='Á' || charsel=='À' || charsel=='Â' || charsel=='Ã')

charsel='A';

if(charsel=='É' || charsel=='È' || charsel=='Ê')

charsel='E';

if(charsel=='Í' || charsel=='Ì' || charsel=='Î')

charsel='I';

if(charsel=='Ó' || charsel=='Ò' || charsel=='Ô' || charsel=='Õ')

charsel='O';

if(charsel=='Ú' || charsel=='Ù' || charsel=='Û')

charsel='U';

if(charsel=='Ç')

charsel='C';

if(charsel=='Ñ')

charsel='N';

if (charsel<0x20)return;

if (charsel>0x7f)return;

for(char_row=0;char_row<5;char_row++) { // 5 bytes

if (charsel<0x50){charpos=(((charsel&0xff)-0x20)*5);chardata=TABLE5[(charpos+char_row)];}

// utiliza TABLE5

if (charsel>0x4f){charpos=(((charsel&0xff)-0x50)*5);chardata=TABLE6[(charpos+char_row)];}

// utiliza TABLE6

lcd_sendData(chardata); // envia dados para lcd nokia

}

lcd_sendData(0x00); // 1 byte (sempre em branco)

}

50

<vs1001k.h>

/**************************************************/

/* */

/* Biblioteca de funções para decodificador MP3 */

/* */

/**************************************************/

/**************************************************/

/* */

/* Defines de Pinos */

/* */

/**************************************************/

#define vs__bsync pin_c0

#define vs__dreq pin_c1

#define vs__xcs pin_c2

#define vs__sclk pin_c3

#define vs__so pin_c4

#define vs__si pin_c5

#define vs__dclk pin_c6

#define vs__sdata pin_c7

#define vs__xreset pin_b1

#byte VS1001K=0x07 //PORTC

#bit VS_SDATA=VS1001K.7

#bit VS_DCLK=VS1001K.6

#bit VS_DREQ=VS1001K.1

#bit VS_BSYNC=VS1001K.0

/**************************************************/

/* */

/* Prototipos de Função */

/* */

/**************************************************/

void vs__writeRegister(int8 addr, int8 data_hi, int8 data_lo);

void vs__sendSerialByte(unsigned int serialByte);

int16 vs__readRegister(int8 addr);

int8 vs__getSerialByte();

void vs__sine_on(int8 freq);

void vs__sine_off();

int8 vs__send_sinewave_beeps();

int8 vs__sine_sweep();

/**************************************************/

/* */

/* Escreve em um registrador */

/* */

/**************************************************/

void vs__writeRegister(int8 addr, int8 data_hi, int8 data_lo)

{

output_low(vs__xcs);

vs__sendSerialByte(0x02);

vs__sendSerialByte(addr);

vs__sendSerialByte(data_hi);

vs__sendSerialByte(data_lo);

output_high(vs__xcs);

}

/**************************************************/

/* */

/* Envia Byte Serialmente */

/* */

/**************************************************/

void vs__sendSerialByte(unsigned int serialByte)

{

51

/*

// Comparador utilizado para enviar um byte completo serialmente para o LCD.

7F - 01111111

BF - 10111111

DF - 11011111

EF - 11101111

F7 - 11110111

FB - 11111011

FD - 11111101

FE - 11111110

*/

unsigned int comparator[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFd, 0xFE };

unsigned int counter;

for(counter = 0; counter < 8; counter++)

{

output_low(vs__sclk);

if( (serialByte|comparator[counter]) == 0xFF)

{

output_high(vs__si);

}

else

{

output_low(vs__si);

}

output_high(vs__sclk);

}

output_low(vs__sclk);

}

/**************************************************/

/* */

/* Le um registrador */

/* */

/**************************************************/

int16 vs__readRegister(int8 addr)

{

int16 data=0;

output_low(vs__xcs);

vs__sendSerialByte(0x03);

vs__sendSerialByte(addr);

data = ((int16) vs__getSerialByte()<<8);

data += vs__getSerialByte();

output_high(vs__xcs);

return data;

}

/**************************************************/

/* */

/* Recebe um byte serialmente */

/* */

/**************************************************/

int8 vs__getSerialByte()

{

/*

// Comparador utilizado para enviar um byte completo serialmente para o LCD.

80 - 10000000

40 - 01000000

20 - 00100000

10 - 00010000

08 - 00001000

04 - 00000100

02 - 00000010

01 - 00000001

52

*/

unsigned int comparator[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

unsigned int counter;

int8 data=0;

for(counter = 0; counter < 8; counter++)

{

output_low(vs__sclk);

if(input(vs__so)!=0)

{

data=data|comparator[counter];

}

output_high(vs__sclk);

}

output_low(vs__sclk);

return data;

}

/**************************************************/

/* */

/* Envia byte de áudio */

/* */

/**************************************************/

void vs__sendAudioByte(unsigned int audioByte)

{

/*

// Comparador utilizado para enviar um byte completo serialmente para o LCD.

7F - 01111111

BF - 10111111

DF - 11011111

EF - 11101111

F7 - 11110111

FB - 11111011

FD - 11111101

FE - 11111110

*/

unsigned int comparator[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFd, 0xFE };

unsigned int counter;

output_high(vs__bsync);

for(counter = 0; counter < 8; counter++)

{

output_low(vs__dclk);

if(counter > 0)output_low(vs__bsync);

if( (audioByte|comparator[counter]) == 0xFF)

{

output_high(vs__sdata);

}

else

{

output_low(vs__sdata);

}

output_high(vs__dclk);

}

output_low(vs__dclk);

}

/**************************************************/

/* */

/* Realiza reset de hardware */

/* */

/**************************************************/

void vs__hardReset()

{

53

output_low(vs__xreset);

delay_ms(1);

output_high(vs__xreset);

delay_ms(5);

}

/**************************************************/

/* */

/* Realiza reset de software */

/* */

/**************************************************/

void vs__softReset()

{

vs__writeRegister(0x00, 0x00, 0x04); // RESET = 0000000000000100

delay_us(5);

delay_ms(1);

}

/**************************************************/

/* */

/* Envia 2048 zeros para pino de áudio */

/* */

/**************************************************/

void vs__sendZeros()

{

int16 counter;

for(counter=0; counter<2048; counter++)

{

vs__sendAudioByte(0x00);

}

}

/**************************************************/

/* */

/* Inicializa decodificador */

/* */

/**************************************************/

void vs__init()

{

// Initializing bits

output_low(vs__bsync); //BSYNC=0

output_high(vs__xcs); //XCS=1

output_high(vs__xreset); //XRESET=1

output_low(vs__sclk); //SCLK=0

output_low(vs__dclk); //DCLK=0

// HardReset

vs__hardReset();

// SoftReset

vs__softReset();

while(!vs__dreq);

// Configure

vs__writeRegister(0x00, 0x00, 0x00);

vs__writeRegister(0x03, 0x98, 0x00); // Clock 12.288 MHz + doubler

vs__writeRegister(0x0b, 0x00, 0x00); // Volume MAX - MAX

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

}

/**************************************************/

/* */

/* Liga teste do seno */

/* */

54

/**************************************************/

void vs__sine_on(int8 freq)

{

vs__sendAudioByte(0x53);

vs__sendAudioByte(0xEF);

vs__sendAudioByte(0x6E);

vs__sendAudioByte(freq);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

}

/**************************************************/

/* */

/* Desliga teste do seno */

/* */

/**************************************************/

void vs__sine_off()

{

vs__sendAudioByte(0x45);

vs__sendAudioByte(0x78);

vs__sendAudioByte(0x69);

vs__sendAudioByte(0x74);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

vs__sendAudioByte(0x00);

}

/**************************************************/

/* */

/* Envia ondas seno 3 vezes */

/* */

/**************************************************/

int8 vs__send_sinewave_beeps()

{

unsigned char i;

for (i=0;i<3;i++)

{

vs__sine_on(62); // 1 kHz ( 16 samples @ 16.000 Hz sample rate)

delay_ms(100);

vs__sine_off();

delay_ms(100);

}

return 0;

}

/**************************************************/

/* */

/* Envia ondas seno */

/* */

/**************************************************/

int8 vs__sine_sweep()

{

unsigned char i;

for (i=48;i<119;i++)

{

vs__sine_off();

vs__sine_on(i);

delay_ms(25);

55

}

vs__sine_off();

return 0;

}

56

<compactflash.h>

/**************************************************/

/* */

/* Biblioteca de funções para Compact Flash */

/* */

/**************************************************/

/**************************************************/

/* */

/* Defines de Pinos */

/* */

/**************************************************/

//PORTAS

#byte CF_ADDR=0x09 //PORTE

#byte CF_DATA=0x08 //PORTD

#byte CF_CONTROL=0x05 //PORTA

#bit CF_D0=CF_DATA.0

#bit CF_D1=CF_DATA.1

#bit CF_D2=CF_DATA.2

#bit CF_D3=CF_DATA.3

#bit CF_D4=CF_DATA.4

#bit CF_D5=CF_DATA.5

#bit CF_D6=CF_DATA.6

#bit CF_D7=CF_DATA.7

//TRIS DAS PORTAS

#byte TRIS_CF_ADDR =0x89 //TRIS DA PORTE

#byte TRIS_CF_DATA =0x88 //TRIS DA PORTD

#byte TRIS_CF_CONTROL =0x85 //TRIS DA PORTA

//DEFINES PARA SETAR/LER OS PINOS DE CONTROLE

#bit CE1=CF_CONTROL.0

#bit CD1=CF_CONTROL.1

#bit RESET=CF_CONTROL.2

#bit OE=CF_CONTROL.3

#bit WE=CF_CONTROL.4

#bit RDY=CF_CONTROL.5

// CF ENDEREÇO DE REGISTRADORES

// (X,X,X,X,X,A2,A1,A0)

#define DATA_REG 0x00 // DATA REGISTER

#define ERROR_REG 0x01 // ERROR REGISTER

#define FEATURES_REG 0x01 // FEATURES REGISTER

#define SEC_CNT_REG 0x02 // SECTOR COUNT REGISTER

#define SEC_NUM_REG 0x03 // SECTOR NUMBER REGISTER

#define CYL_LO_REG 0x04 // LOW CYLINDER REGISTER

#define CYL_HI_REG 0x05 // HIGH CYLINDER REGISTER

#define HEAD_REG 0x06 // HEAD/DRIVE REGISTER

#define STATUS_REG 0x07 // STATUS REGISTER

#define COMMAND_REG 0x07 // COMMAND REGISTER

// COMANDOS

#define DIAGNOSTIC 0x90

#define IDENTIFY 0xEC

#define WRITE_SEC 0x30

#define READ_SEC 0x20

/**************************************************/

/* */

/* Protótipos de Função */

/* */

/**************************************************/

void compactFlashInit();

void compactFlashCheckCard();

void compactFlashWait();

void compactFlashReset();

char compactFlashRead(char addr);

void compactFlashWrite(char addr,char data);

57

void compactFlashReadBlock(char blockHigh, char blockMiddle, char blockLow);

void compactFlashSkip(char count);

void getdatafromcf(int32 lba);

/**************************************************/

/* */

/* Inicializa Compact Flash */

/* */

/**************************************************/

void compactFlashInit()

{

//SETAR ENTRADAS E SAIDAS DA PORTA A USADA PARA ENDEREÇOS E ENTRADA

ANALÓGICA DO ADC

TRIS_CF_ADDR=0x08; //OU SET_TRIS_A(0x08);

//SETA INICIALMENTE O BARRAMENTO DE DADOS COMO SAIDA

TRIS_CF_DATA=0x00; //OU SET_TRIS_B(0X00);

//SETA ENTRADAS E SAIDAS DA PORTA UTILIZADA PARA OS PINOS DE CONTROLE

TRIS_CF_CONTROL=0xA2; //OU SET_TRIS_C(0xA2);

CF_CONTROL=0x18; //CONTROLE=00011000 OE E WE = 1;

CF_ADDR=0x00;

}

/**************************************************/

/* */

/* Verifica se Compact Flash está conectada */

/* */

/**************************************************/

void compactFlashCheckCard()

{

while(CD1)

{

printf(lcd_printChar, "Cartao Nao Conectado!");

delay_ms(1000);

}

compactFlashReset();

compactFlashWrite(COMMAND_REG,IDENTIFY);

}

/**************************************************/

/* */

/* Diagnostica Compact Flash */

/* */

/**************************************************/

void compactFlashDiagnostic()

{

compactFlashWrite(COMMAND_REG,DIAGNOSTIC);

}

/**************************************************/

/* */

/* Verifica se Compact Flash está pronta */

/* */

/**************************************************/

void compactFlashWait()

{

while(RDY==0);

}

/**************************************************/

/* */

/* Reseta Compact Flash */

/* */

58

/**************************************************/

void compactFlashReset()

{

RESET=1;

delay_us(10);

RESET=0;

delay_ms(200);

}

/**************************************************/

/* */

/* Escreve na Compact Flash */

/* */

/**************************************************/

void compactFlashWrite(char addr,char data)

{

CF_ADDR=addr;

CF_DATA=data;

compactFlashWait();

WE=0;

delay_us(1);

WE=1;

}

/**************************************************/

/* */

/* Le Compact Flash */

/* */

/**************************************************/

char compactFlashRead(char addr)

{

char data;

CF_ADDR=addr;

//Seta o barramento de dados como entrada

TRIS_CF_DATA=0xFF; //OU SET_TRIS_B(0XFF);

CF_DATA=0x00; //OU OUTPUT_B(0x00);

compactFlashWait();

OE=0;

delay_us(1);

data=CF_DATA;

OE=1;

TRIS_CF_DATA=0x00;

return data;

}

/**************************************************/

/* */

/* Lê um bloco Compact Flash */

/* */

/**************************************************/

void compactFlashReadBlock(char blockHigh, char blockMiddle, char blockLow)

{

compactFlashWrite(HEAD_REG, 0xE0);

compactFlashWrite(CYL_HI_REG, blockHigh);

compactFlashWrite(CYL_LO_REG, blockMiddle);

compactFlashWrite(SEC_NUM_REG, blockLow);

compactFlashWrite(SEC_CNT_REG, 1);

compactFlashWrite(COMMAND_REG, READ_SEC);

}

/**************************************************/

59

/* */

/* Seleção do setor */

/* */

/**************************************************/

void getdatafromcf(int32 lba){

lba = lba & 0x0FFFFFFF;

lba = lba | 0xE0000000;

CF_DATA=*(((char*)&lba)+3);

CF_ADDR=HEAD_REG;

WE=0;WE=1;

CF_DATA=*(((char*)&lba)+2);

CF_ADDR=CYL_HI_REG;

WE=0;WE=1;

CF_DATA=*(((char*)&lba)+1);

CF_ADDR=CYL_LO_REG;

WE=0;WE=1;

CF_DATA=*(((char*)&lba)+0);

CF_ADDR=SEC_NUM_REG;

WE=0;WE=1;

CF_DATA=0x01;

CF_ADDR=SEC_CNT_REG;

WE=0;WE=1;

CF_DATA=READ_SEC;

CF_ADDR=COMMAND_REG;

WE=0;WE=1;

}

60

<fat.h>

/**************************************************/

/* */

/* Biblioteca de funções para FAT e Envio de Áudio */

*/ para o decodificador */

/* */

/**************************************************/

/**************************************************/

/* */

/* Protótipos de Função */

/* */

/**************************************************/

// Funções FAT e de Gerenciamento de Arquivos

void find_bpb();

boolean prepareFileEntry(int16 index);

void selectByteofFile(int32 byteRead);

void printout_rootdir(void);

void showFileContent();

// Funções MP3

showMP3Tags();

void playMP3();

/**************************************************/

/* */

/* Variáveis globais */

/* */

/**************************************************/

// Variáveis FAT

char BPB_SecPerClus;

int16 bpbstart,RootDirSectors, BPB_FATSz16, BPB_RsvdSecCnt, BPB_BytsPerSec;

int32 FirstRootDirSecNum, FirstDataSector;

// Variáveis de gerenciamento de arquivos

char entry_f_filename[9], entry_f_extension[4];

int16 entry_f_cluster;

int32 entry_f_size;

/**************************************************/

/* */

/* Carrega informações do setor 0 e inicializa FAT */

/* */

/**************************************************/

void find_bpb(){

int i;

char read;

char BPB_NumFATs;

int16 BPB_RootEntCnt;

int16 n16; // Unused Vars

int32 n32; //Unused Vars

compactFlashReadBlock(0, 0, 0);

// BS_jmpBoot

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS jmpBoot");

lcd_gotoXY(0,1);

for(i=0; i<3;i++)

{

printf(lcd_printChar, "%X", compactFlashRead(DATA_REG));

}

lcd_clrscr();

// BS_OEMName

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS OEMName");

61

lcd_gotoXY(0,1);

for(i=0; i<8;i++)

{

printf(lcd_printChar, "%c", compactFlashRead(DATA_REG));

}

lcd_clrscr();

// BPB_BytsPerSec

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB BytsPerSec");

lcd_gotoXY(0,1);

BPB_BytsPerSec = compactFlashRead(DATA_REG);

BPB_BytsPerSec += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4lX", BPB_BytsPerSec);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", BPB_BytsPerSec);

lcd_clrscr();

// BPB_SecPerClus

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB SecPerClusCnt");

BPB_SecPerClus = compactFlashRead(DATA_REG);

lcd_gotoXY(0,1);

printf(lcd_printChar, "%X", BPB_SecPerClus);

lcd_clrscr();

// BPB_RsvdSecCnt

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB RsvdSecCnt");

lcd_gotoXY(0,1);

BPB_RsvdSecCnt = compactFlashRead(DATA_REG);

BPB_RsvdSecCnt += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", BPB_RsvdSecCnt);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", BPB_RsvdSecCnt);

lcd_clrscr();

// BPB_NumFATs

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB NumFATs");

lcd_gotoXY(0,1);

BPB_NumFATs = compactFlashRead(DATA_REG);

printf(lcd_printChar, "%X", BPB_NumFATs);

lcd_clrscr();

//BPB_RootEntCnt

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB RootEntCnt");

lcd_gotoXY(0,1);

BPB_RootEntCnt = compactFlashRead(DATA_REG);

BPB_RootEntCnt += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", BPB_RootEntCnt);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", BPB_RootEntCnt);

lcd_clrscr();

//BPB_TotSec16

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB TotSec16");

lcd_gotoXY(0,1);

n16 = compactFlashRead(DATA_REG);

n16 += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", n16);

62

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n16);

lcd_clrscr();

//BPB_Media

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB Media");

lcd_gotoXY(0,1);

printf(lcd_printChar, "%X", compactFlashRead(DATA_REG));

lcd_clrscr();

//BPB_FATSz16

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB FATSz16");

lcd_gotoXY(0,1);

BPB_FATSz16 = compactFlashRead(DATA_REG);

BPB_FATSz16 += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", BPB_FATSz16);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", BPB_FATSz16);

lcd_clrscr();

//BPB_SecPerTrk

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB SecPerTrk");

lcd_gotoXY(0,1);

n16 = compactFlashRead(DATA_REG);

n16 += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", n16);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n16);

lcd_clrscr();

//BPB_NumHeads

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB NumHeads");

lcd_gotoXY(0,1);

n16 = compactFlashRead(DATA_REG);

n16 += ((int16) compactFlashRead(DATA_REG)<<8);

printf(lcd_printChar, "%4LX", n16);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n16);

lcd_clrscr();

//BPB_HiddSec

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB HiddSec");

lcd_gotoXY(0,1);

n32 = compactFlashRead(DATA_REG);

n32 += ((int32) compactFlashRead(DATA_REG)<<8);

n32 += ((int32) compactFlashRead(DATA_REG)<<16);

n32 += ((int32) compactFlashRead(DATA_REG)<<24);

printf(lcd_printChar, "%8LX", n32);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n32);

lcd_clrscr();

//BPB_TotSec32

lcd_gotoXY(0,0);

printf(lcd_printChar, "BPB TotSec32");

lcd_gotoXY(0,1);

n32 = compactFlashRead(DATA_REG);

n32 += ((int32) compactFlashRead(DATA_REG)<<8);

63

n32 += ((int32) compactFlashRead(DATA_REG)<<16);

n32 += ((int32) compactFlashRead(DATA_REG)<<24);

printf(lcd_printChar, "%8LX", n32);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n32);

lcd_clrscr();

// BS_DrvNum

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS DrvNum");

lcd_gotoXY(0,1);

printf(lcd_printChar, "%X", compactFlashRead(DATA_REG));

lcd_clrscr();

// BS_Reserved1

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS Reserved1");

lcd_gotoXY(0,1);

printf(lcd_printChar, "%X", compactFlashRead(DATA_REG));

lcd_clrscr();

// BS_BootSig

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS BootSig");

lcd_gotoXY(0,1);

printf(lcd_printChar, "%X", compactFlashRead(DATA_REG));

lcd_clrscr();

//BS_VolID

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS VolID");

lcd_gotoXY(0,1);

n32 = compactFlashRead(DATA_REG);

n32 += ((int32) compactFlashRead(DATA_REG)<<8);

n32 += ((int32) compactFlashRead(DATA_REG)<<16);

n32 += ((int32) compactFlashRead(DATA_REG)<<24);

printf(lcd_printChar, "%8LX", n32);

lcd_gotoXY(0,2);

printf(lcd_printChar, "%ld", n32);

lcd_clrscr();

// BS_VolLab

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS VolLab");

lcd_gotoXY(0,1);

for(i=0; i<11;i++)

{

printf(lcd_printChar, "%c", compactFlashRead(DATA_REG));

}

lcd_clrscr();

// BS_FilSysType

lcd_gotoXY(0,0);

printf(lcd_printChar, "BS FilSysType");

lcd_gotoXY(0,1);

for(i=0; i<8;i++)

{

printf(lcd_printChar, "%c", compactFlashRead(DATA_REG));

}

lcd_clrscr();

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;

FirstDataSector = BPB_RsvdSecCnt + (BPB_NumFATs * BPB_FATSz16) + RootDirSectors;

64

FirstRootDirSecNum = BPB_RsvdSecCnt + ((int32) (BPB_NumFATs * BPB_FATSz16));

}

/**************************************************/

/* */

/* Le informações do arquivo na entrada de diretório */

/* */

/**************************************************/

int prepareFileEntry(int16 index)

{

int16 sec, _entry, count, entriesPerSec;

char aux;

int attr;

entriesPerSec=BPB_BytsPerSec/32;

sec=index/entriesPerSec;

_entry=index%entriesPerSec;

_entry=_entry*32;

getdatafromcf(FirstRootDirSecNum+sec);

//Posiciona leitura no inicio da entrada

for(count=0; count < _entry; count++)

{

compactFlashRead(DATA_REG);

}

//Inicia Leitura das informações da entrada

// DIR_Name

//Primeiro Caracter

aux=compactFlashRead(DATA_REG);

lcd_clrscr();

if(aux == 0xE5) // Entrada está vazia, as próximas não estão, leia próxima

{

//recursividade não permitida

return 2;

}

if(aux == 0x00) // Não existem mais entradas depois desta entrada, entrada vazia

{

return 1;

}

if(aux == 0x05)

{

aux = 0xE5;

}

// Inicia leitura do nome do arquivo

entry_f_filename[8]='\0';

entry_f_filename[0]=aux;

for(count=1;count<8;count++)

{

entry_f_filename[count]=compactFlashRead(DATA_REG);

}

// Leitura da extensão do arquivo

entry_f_extension[3]='\0';

for(count=0;count<3;count++)

{

entry_f_extension[count]=compactFlashRead(DATA_REG);

}

// DIR_Attr - Leitura de Atributos

attr=compactFlashRead(DATA_REG);

65

if((((attr&0x0F)==0x0F)||((attr&0x08)==0x08)||((attr&0x10)==0x10)||((attr&0x20)!=0x20))) // Entrada

de Nomes Longos|Volume|Diretorio|Não for entrada de arquivo, preapre proxima entrada (software não faz

leitura de nomes longos)

{

return 2;

}

// Continua preparação de entrada de arquivo

// se attr&0x01==0x01 -> Arquivo somente leitura

// se attr&0x02==0x02 -> Arquivo escondido

// se attr&0x04==0x04 -> Arquivo de sistema

// Leitura de informações desnecessárias

//DIR_NTRes - (1)

//DIR_CrtTimeTenth - (1)

//DIR_CrtTime - (2)

//DIR_CrtDate - (2)

//DIR_LstAccDate - (2)

//DIR_FstClusHI - (2)

//DIR_WrtTime - (2)

//DIR_WrtDate - (2)

//Total = 14

for(count=0;count<14;count++)

{

compactFlashRead(DATA_REG);

}

// DIR_FstClus

entry_f_cluster = compactFlashRead(DATA_REG);

entry_f_cluster += ((int16) compactFlashRead(DATA_REG)<<8);

// DIR_FileSize

entry_f_size = compactFlashRead(DATA_REG);

entry_f_size += ((int32) compactFlashRead(DATA_REG)<<8);

entry_f_size += ((int32) compactFlashRead(DATA_REG)<<16);

entry_f_size += ((int32) compactFlashRead(DATA_REG)<<24);

return 0;

}

/**************************************************/

/* */

/* Verifica caracteres válidos para nome de arquivo */

/* */

/**************************************************/

boolean checkValidFilenameChars(char aux)

{

return (aux>0x20 && aux!=0x22 && aux!=0x2A && aux!=0x2B && aux!=0x2C && aux!=0x2E &&

aux!=0x2F && aux!=0x3A && aux!=0x3B && aux!=0x3C && aux!=0x3D && aux!=0x3E && aux!=0x3F

&& aux!=0x5B && aux!=0x5C && aux!=0x5D && aux!=0x7C);

}

/**************************************************/

/* */

/* Lê os arquivos do diretório root e inicia */

/* reprodução dos arquivos MP3 */

/* */

/**************************************************/

void printout_rootdir(void){

int16 count=0;

int prepare, i;

prepare=prepareFileEntry(count);

while(prepare!=1)

{

lcd_clrscr();

66

count++;

if(prepare==2)

{

// Entrada Inválida, mas existem mais entradas.

prepare=prepareFileEntry(count);

continue;

}

// Mostra Nome do Arquivo

lcd_clrscr();

lcd_gotoXY(0,0);

printf(lcd_printChar, "Filename: ");

lcd_gotoXY(0,1);

for(i=0; i<8; i++)

{

if(checkValidFilenameChars(entry_f_filename[i]))

{

printf(lcd_printChar, "%c", entry_f_filename[i]);

}

}

printf(lcd_printChar, ".");

for(i=0; i<3; i++)

{

if(checkValidFilenameChars(entry_f_extension[i]))

{

printf(lcd_printChar, "%c", entry_f_extension[i]);

}

}

// Mostra Tamanho do Arquivo

lcd_gotoXY(0,2);

printf(lcd_printChar, "Tamanho: ");

lcd_gotoXY(0,3);

printf(lcd_printChar, "%ld bytes", entry_f_size);

// Mostra Fst Cluster of File

lcd_gotoXY(0,4);

printf(lcd_printChar, "1st Cluster: ");

lcd_gotoXY(0,5);

printf(lcd_printChar, "%ld", entry_f_cluster);

delay_ms(3000);

if((entry_f_extension[0]=='M'||entry_f_extension[0]=='m')&&(entry_f_extension[1]=='P'||entry_f_exten

sion[1]=='p')&&(entry_f_extension[2]=='3'))

{

showMP3Tags();

playMP3();

}

prepare=prepareFileEntry(count);

}

}

/**************************************************/

/* */

/* Mostra tags MP3 no LCD */

/* */

/**************************************************/

void showMP3Tags()

{

char read;

int counter;

int32 startByteOfTag;

lcd_clrscr();

67

//show MP3 Artist

startByteOfTag = entry_f_size - 125 + 30;

selectByteofFile(startByteOfTag);

for(counter = 0; counter < 30; counter++)

{

read = compactFlashRead(DATA_REG);

if(read == 0x00)

break;

printf(lcd_printChar, "%c", read);

}

//show MP3 Song Title

lcd_gotoXY(0,2);

startByteOfTag = (entry_f_size - 125);

selectByteofFile(startByteofTag);

for(counter = 0; counter < 30; counter++)

{

read = compactFlashRead(DATA_REG);

if(read == 0x00)

break;

printf(lcd_printChar, "%c", read);

}

//show MP3 Album

lcd_gotoXY(0, 4);

startByteOfTag = (entry_f_size - 125 + 60);

selectByteofFile(startByteofTag);

for(counter = 0; counter < 30; counter++)

{

read = compactFlashRead(DATA_REG);

if(read == 0x00)

break;

printf(lcd_printChar, "%c", read);

}

}

/**************************************************/

/* */

/* Posiciona o cursor de Leitura da Compact Flash */

/* no byte do arquivo atual. */

/* */

/**************************************************/

void selectByteofFile(int32 byteRead)

{

int32 OffsetSector, FirstSectorofCluster;

int16 counter, OffsetBuffer;

FirstSectorofCluster=(int32)(((int32)entry_f_cluster - (int32)2) * (int32)BPB_SecPerClus) + FirstDataSector;

OffsetSector = byteRead / (int32)BPB_BytsPerSec;

OffsetBuffer = byteRead % (int32)BPB_BytsPerSec;

getdatafromcf(OffsetSector + FirstSectorofCluster);

for(counter=0; counter < OffsetBuffer; counter++)

compactFlashRead(DATA_REG);

}

/**************************************************/

/* */

/* Reproduz arquivo MP3 */

/* */

68

/**************************************************/

void playMP3()

{

int32 FirstSectorofCluster, counter;

int16 counter_aux;

unsigned int comparator[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFd, 0xFE };

signed int counter2;

char audioByte;

FirstSectorofCluster=(int32)(((int32)entry_f_cluster - (int32)2) * (int32)BPB_SecPerClus) + FirstDataSector;

counter_aux = 0;

getdatafromcf(FirstSectorofCluster);

vs__init();

vs__sendZeros();

CF_ADDR=DATA_REG;

for(counter = 0; counter < entry_f_size; counter++)

{

if(counter_aux == BPB_BytsPerSec)

{

counter_aux = 0;

TRIS_CF_DATA=0x00;

getdatafromcf(++FirstSectorofCluster);

TRIS_CF_DATA=0xFF;

CF_ADDR=DATA_REG;

}

while(!VS_DREQ);

while(!RDY);

OE=0;

delay_us(1);

VS_BSYNC=1;

//for(counter2 = 7; counter2 >= 0; counter2--)

VS_DCLK=0;

VS_SDATA=CF_D7;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D6;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D5;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D4;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D3;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D2;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D1;

VS_DCLK=1;

VS_DCLK=0;

VS_SDATA=CF_D0;

VS_DCLK=1;

VS_DCLK=0;

OE=1;

counter_aux++;

}

TRIS_CF_DATA=0x00;

vs__sendZeros();

delay_ms(50);

69

}