|
There are no translations available.
Questo spazio è dedicato alla descrizione del lettore mp3 versione 1 scritto in MikroC. Un lettore MP3 è un'oggetto capace di riprodurre un suono memorizzato in formato digitale compresso, le tecniche di compressione adottate per generare i file MP3 sono tecniche che implicano perdita d'informazione, cioè non è possibile ricreare fedelmente l'informazione iniziale dopo il trattamento di compressione, viceversa accade quotidianamente con la creazione di un'archivio dati di tipo zip dove è sempre possibile risalire al file originale, l'MP3 sfrutta l'incapacità dell'apparato umano di percepire suoni con frequenze e timbri particolari eliminando tali sequenze che rispetto ad algoritmi opportunamente studiati non verrano percepite dall'orecchio medio, in realtà l'MP3 permette diversi livelli di compressione, la diminuzione lineare delle dimensioni tende a diminuire esponenzialmente la qualità audio, quindi per rimanere fedeli all'originale non si devono superare le soglie minime di comprssione. Un lettore MP3 come in questo caso è composto sostanzialmente da un processore che si occupa di prelevare i byte dal dispositivo di memorizzazioni e passarli ad un DSP, un Digital Signal Processing, ovvero un microcontrollore con delle funzioni matematiche aggiuntive capaci di elaborare segnali digitali in tempo reale, nel caso dell'MP3 il lavoro svolto è quello di catturare il tipo di compressione adottata e di riprodurre il suono seguendo degli algoritmi di decodifica predefiniti. Nel progetto presentato il DSP è il componente VS1011e, il chip comprende anche un DAC, Digital-Analogic-Conversion, ed uno stadio amplificativo al quale possono essere collegate delle cuffie o degli auricolari. Dall'esperienza maturata in programmazione assembler PIC, e dalle prime conoscere di linguaggio C, è nata l'idea di realizzare un lettore di file musicali MP3, basato su microcontrollore PIC18F452 programmato in MikroC, il MikroC è una sotto-classe del linguaggio di programmazione C, opportunamente modellato da permettere un semplice approccio anche allo sviluppatore meno esperto. Il MikroC integra delle comode librerie per gestire le periferiche interne, offrendo delle funzioni avanzate ai protocolli più diffusi. L'MP3 presentato è stato il primo progetto realizzato con un software scritto in linguaggio di alto livello, in realtà nel codice sono presenti anche delle righe di basso livello "assembler", necessarie per poter migliorare, in termini di velocità, l'accesso ai pin. Questo progetto è stato l'unico realizzato in MikroC, a causa di alcuni bug presenti nelle funzioni offerte da tale linguaggio, inoltre le problematiche riscontrate hanno spinto ad adottare come linguaggio di riferimento il C standard della Microchip, sfruttando allo stesso tempo un gradevole ambiente di programmazione del tutto gratuito ovvero l'MPLAB-IDE, inoltre la Microchip offre i compilatori gcc versione Student, per un periodo di prova limitato, in forma gratuita previa registrazione. Adottando questa strada è possibile anche ad un pubblico non professionale sfruttare le potenzialità del C, inoltre va ricordato che essendo i compilatori proprietari Microchip garantiscono una piena compatibilità con i nuovi modelli di microcontrollori introdotti periodicamente sul mercato, ed una veloce correzione in caso di errori. Funzionamento. Il software realizzato per gestire l'MP3 è composto da una funzione principale "main" nella quale viene inizializzata la MMC ed il decoder VS1011e, terminata la fase di configurazione iniziale, il controllo passa alla funzione "M_Open_File_Read" che si occupa di leggere progressivamente i byte della song in esecuzione, dalla MMC ed inviarli al decode. Nella fase di esecuzione del file MP3 viene gestita in maniera semplice anche la pressione degli switch che permettono le normali funzioni di play, stop, avanti, indietro, volume-up e volume-down. Di seguito viene presentato il codice sorgente del main commentato opportunamente per comprenderne il funzionamento: //--------------------------------------------------------------------------------------------------------
// * Project name: // MP3 player whit VS1011e // * Copyright: // Luca Pascarella www.lucasproject.it
// * Description:
// I file MP3 devono essere rinominati secondo questa regola: // PROVA00 MP3 (8+3 senza punto "." ma con " ") // * Test configuration: // MCU: P18F452 // Oscillator: HSPLL, 10.0000 MHz x 4 = 40Mhz // Ext. Modules: MMC/SD // SW: mikroC v6.2.1.0 //-------------------------------------------------------------------------------------------------------- #include "built_in.h" //Libreria da icludere per le funzioni
#define LED_GREEN PORTA.F2 #define LED_RED PORTA.F3 #define LOOK PORTD.F0 #define PRESENT PORTD.F1
#define RST PORTA.F0 #define CS PORTA.F5 #define DCS PORTA.F1 #define DREQ PORTA.F4 #define CLK 1 #define SO 0
char txt[3], txt2[6], filename[12] = "PROVA00 MP3"; unsigned long i, size; unsigned short loop, caracter, x, ctrl_vol=0; unsigned int volume=0x6464, loop2;
#include "Funzione.h"
void main() {
unsigned repeat=0;
INTCON = 0; // Disable all interrupts ADCON1 = 6; TRISA = 16; TRISE = 0; LED_GREEN = LED_RED = 1;
delay_ms(100); // Delay 100ms Lcd_Config(&PORTB,7,5,6,1,2,3,4); // Configura LCD sui rispettivi pin Lcd_Cmd(LCD_CLEAR); // Clear display Lcd_Cmd(LCD_CURSOR_OFF); // Turn cursor off Lcd_Cmd(LCD_RETURN_HOME); // Cursor home Lcd_Out(1, 1, "Hello Luca"); Delay_ms(1000); Lcd_Cmd(LCD_CLEAR); // Clear display LED_GREEN = LED_RED = 0;
Spi_Init_Advanced(MASTER_OSC_DIV4, DATA_SAMPLE_MIDDLE, CLK_IDLE_LOW, LOW_2_HIGH); Soft_Spi_Config (&PORTE, 2, 0, 1); RST = 1; //Hardware Reset logical level to 0-->1 CS = 1; DCS = 1; Delay_ms(100); if (DREQ == 1){ //controllo che l'hardware reset è avvenuto bene LED_GREEN = 1; CS = 0; //Enable Circuit Select for SCI Soft_Spi_Write(0x02); //Command for write 0x(02) Soft_Spi_Write(0x00); //ar register 0x00 Soft_Spi_Write(0x08); //Set mode register Soft_Spi_Write(0x02); //is 16bit long CS = 1; //disable Circuit Select for SCI Delay_us(30); //attesa per l'esecuzione basta controllare lo stato di DREQ CS = 0; Soft_Spi_Write(0x02); Soft_Spi_Write(0x03); //Set the register for the clock Soft_Spi_Write(0x98); //I use a doubler PLL whit 12.288Mhz Soft_Spi_Write(0x00); CS = 1; Delay_us(30); CS = 0; Soft_Spi_Write(0x02); Soft_Spi_Write(0x0B); //Set the volume at medium value Soft_Spi_Write(0x64); Soft_Spi_Write(0x64); CS = 1; } do{ if(PRESENT == 0){ //Controlla se la card è presente if(LOOK == 0){ //Controlla se la card è bloccata if(!Mmc_Fat_Init(&PORTC,2)){ //Inizializza MMC/SD Lcd_Out(1, 1, "Card OK"); Delay_ms(300); Lcd_Cmd(LCD_CLEAR); loop=1; while (loop<50){ //Ciclo per leggere gli mp3 in sequenza filename[5] = loop / 10 + 48; //Calcolo del nome del file filename[6] = loop % 10 + 48; M_Open_File_Read(); //Chiamata a funzione for (loop2=0; loop2<2048; loop2++){ //Invio di 2048 "0" per accertarsi la fine dell'mp3 DCS = 0; Soft_Spi_Write(0x00); DCS = 1; } while (DREQ==0){} //attesa su DREQ CS = 0; Soft_Spi_Write(0x02); //Software reset Soft_Spi_Write(0x00); Soft_Spi_Write(0x08); Soft_Spi_Write(0x06); CS = 1; Delay_us(100); while (DREQ==0){} CS = 0; Soft_Spi_Write(0x02); //Imposto il clock Soft_Spi_Write(0x03); Soft_Spi_Write(0x98); Soft_Spi_Write(0x00); CS = 1; loop++; } }else{ //Inizializzazione fallita Lcd_Out(1, 1, "CARD fallita"); Delay_ms(1000); }
Lcd_Cmd(LCD_CLEAR); Lcd_Out(1, 6, "FINE"); repeat=1; Delay_ms(1000); } else{ Lcd_Out(2, 1, "Card Looked"); repeat=1; Delay_ms(1000); } } else{ Lcd_Out(2, 1, "Card assente"); Delay_ms(1000); repeat=1; } do{ Lcd_Out(1, 1, "Play to repeat"); if(Button(&PORTD, 5, 1, 0)){ repeat=0; Lcd_Cmd(LCD_CLEAR); } if(Button(&PORTD, 4, 1, 0)){ Lcd_Cmd(LCD_CLEAR); // Clear display Lcd_Out(1, 1, "See you"); Delay_ms(3000); Lcd_Cmd(LCD_TURN_OFF); while(1); } } while(repeat==1); } while(1);
}//~!
|
Descritto il funzionamento iniziale del main si può passare allo studio della parte più complessa, ovvero della gestione avanzata della della memoria e dell'invio ciclico dei dati al decoder: void M_Open_File_Read() {
unsigned short sec_lo, sec_hi, min=0, scd=0, ctrl_sec=0; unsigned long sec, ctrl_sec2=0; if ((Mmc_Fat_Assign(&filename, 0))==1) //se il file viene trovato lo decodifica altrimenti { //passa al file successivo per un limite di 50 Lcd_Out(1, 1, filename); Lcd_Out(2, 10, "Vol."); x=volume/257; //Calcolo valore volume ByteToStr((254-x), txt); Lcd_Out(2, 14, txt); Mmc_Fat_Reset(&size); // To read file, procedure returns size of file while (DREQ==0){} for (i = 1; i <= size; i++) { //ciclo lettura Byte dal file PROVAXX mp3 Mmc_Fat_Read(&caracter); while (DREQ==0) { //cicli da eseguire solo quando il decoder ctrl_sec2++; //è impegnato a decodificare l'audio if (ctrl_sec2==4000) //***cycle to be corrected but it work { sec=(sec_hi*256)+sec_lo; min=sec/60; scd=sec-(min*60); ByteToStr(min, txt); Lcd_Out(2, 1, txt); Lcd_Out(2, 1, "M"); ByteToStr(scd, txt); Lcd_Out(2, 4, txt); Lcd_Out(2, 4, "s"); ctrl_sec=1; ctrl_sec2=0; } if (Button(&PORTD, 7, 1, 0)) //indietro { Delay_ms(50); i=size; loop=loop-2; } if (Button(&PORTD, 6, 1, 0)) //avanti { i=size; } if (Button(&PORTD, 5, 1, 0)) //Pause { Delay_ms(100); } if (Button(&PORTD, 4, 1, 0)) //Stop { i=size; loop=250; } if (Button(&PORTD, 2, 1, 0) && (ctrl_vol==0)) //Volume up { if(volume!=0) { x=volume/257; x--; volume=(x*256)+x; ByteToStr((254-x), txt); Lcd_Out(2, 14, txt); ctrl_vol=1; } } if (Button(&PORTD, 3, 1, 0) && (ctrl_vol==0)) //Volume Down { if(volume!=65278) { x=volume/257; x++; volume=(x*256)+x; ByteToStr((254-x), txt); Lcd_Out(2, 14, txt); ctrl_vol=1; } } LED_RED=1; } //Fine while if (ctrl_vol==1) { CS = 0; Soft_Spi_Write(0x02); Soft_Spi_Write(0x0B); Soft_Spi_Write(Hi(volume)); Soft_Spi_Write(Lo(volume)); CS = 1; ctrl_vol=0; } if (ctrl_sec==1) { CS=0; Soft_Spi_Write(0x03); Soft_Spi_Write(0x04); sec_hi = Soft_Spi_Read(0); sec_lo = Soft_Spi_Read(0); CS=1; ctrl_sec=0; } LED_RED=0; DCS=0; //Enable Circuit select for SDI asm{ //Codice in assembler perchè in C troppo lento bcf PORTE,SO,0 btfsc _caracter,7,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,6,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,5,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,4,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,3,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,2,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,1,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0 bcf PORTE,SO,0 btfsc _caracter,0,0 bsf PORTE,SO,0 bsf PORTE,CLK,0 bcf PORTE,CLK,0} DCS=1; //Fine disable DCS } } else { Lcd_Out(1, 1, "File non trovato"); Delay_ms(500); } Lcd_Cmd(LCD_CLEAR); }//~ |
Le immagini inserite mostrano il circuito realizzato con un bromografo domestico ed il player in funzione, precisamente nella fase di inizializzazione dove viene anche visualizzato un messaggio di benvenuto all'utente. Il disegno del PCB e dello schema elettrico è stata fatta con un software CAD per PCB, FidoCAD, fruibile dalla rete gratuitamente, questo programma non supporta lo sbroglio automatico delle piste ne la trasformazione da SHC a PCB, tutto il lavoro di disegno delle tracce su basetta presensibilizzata è stato fatto manualmente sfruttando le capacità umane di trovare il percorso più breve. Il progetto proposto può essere sfruttato come un'ottima guida, per iniziare a programmare i microcontrollori PIC in un linguaggio di programmazione di alto livello come il C, inoltre tali conoscenze si rilevano estremanenti utili anche in ambienti più complessimo come i progetti realizzati sull'hardware della Fox Board, sistema Linux embedded per eccellenza. Letture e links consigliati. Di segui riporto alcuni documenti ed alcunii collegamenti che possono essere utili per approfondire le conoscenze sul funzionamento dei componenti impiegati. Conclusioni e note. In caso vengano riscontrate dubbi o chiarimenti è possibile contattarmi usando l'apposito modulo contact, provvederò in una tempestiva risposta. Luca Pascarella
|