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.
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.
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.
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.
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.
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);
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);
Top Related