Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystemCpp I2SSlave TLV320 mbed
main.cpp
00001 //------------------------------------------------------------------------------------------------------------ 00002 // Demoprogramm 6 für die Audio-Ausgabe über das AudioCODEC Board (RS Product Code 754-1965) 00003 //------------------------------------------------------------------------------------------------------------ 00004 //(c) Roland Elmiger, ELcon Consulting & Engineering, Switzerland 00005 // 00006 // Version 1.0A 00007 // 00008 // Enwickelt am : 22.11.2015 00009 // Letzter Update : 06.12.2015 00010 //------------------------------------------------------------------------------------------------------------ 00011 // Jedes WAV-Files mit den Bedingungen 44100Hz, 16-bit, Stereo sollte funktionieren. 00012 // 00013 // Beschaltung: 00014 // 00015 // AudioCODEC Board mbed NXP LPC1768 00016 // --------------------- --------------------- 00017 // GND | 1 <-------> 1 | GND (0V) 00018 // LRCOUT | 2 | 00019 // DOUT | 3 | 00020 // BCLK | 4 <-------- 7 | P7 (SCLK) 00021 // DIN | 5 <-------- 5 | P5 (MOSI) 00022 // LCRIN | 6 <-------- 6 | P6 (MISO) 00023 // /CS | 7 <-------> 1 | GND (0V) 00024 // MODE | 8 <-------> 1 | GND (0V) 00025 // SDIN | 9 <-------- 9 | P9 (SDA) 00026 // SCLK |10 <--------10 | P10 (SCL) 00027 // +3.3V |11 <------->40 | Vout (3.3V) 00028 // --------------------- --------------------- 00029 00030 00031 //------------------------------------------------------------------------------------------------------------ 00032 00033 #include "mbed.h" 00034 #include "TLV320.h" 00035 #include "SDHCFileSystem.h" 00036 #include "LCD.h" 00037 00038 00039 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); 00040 Serial pc(USBTX, USBRX); 00041 00042 TextLCD lcd(p26, p25, p24, p23, p22, p20, p19, TextLCD::LCD20x4); // RS, RW, E, D0, D1, D2, D3, Typ 00043 TLV320 audio(p9, p10, 0x34, p5, p6, p7, p8, p29); //Objekt I2S Codec 00044 00045 SDFileSystem sd(p11, p12, p13, p14, "sd"); //Objekt SD-Karte (MOSI, MISO, SCLK, CS, "SD-Kartenname") 00046 00047 FILE *fp; //Zeiger auf die Audiodatei 00048 00049 AnalogIn aIn(p15); //Lautstärke 00050 00051 #define DEBOUNCING_INTERVAL 20 //Debouncing Interval (in Millisekunden) 00052 00053 // Variablen 00054 //--------------------------------------------------------------------------------------------------------------------------------------- 00055 int RingBuffer[4096]; //Ringspeicher 00056 volatile int ReadPointer = 0; 00057 volatile int Theta = 0; 00058 00059 /* Wav file header data, for setting up the transfer protocol */ 00060 short Channels; //Kanalzahl (2 = Stereo, 1 = Mono) 00061 long SampleRate; //Abtastrate 00062 short WordWidth; //Bit-Anzahl der Daten (z.B. 16 Bit) 00063 00064 bool AnsagePlay = false; // 00065 char AnsageNr = 0; //Nr. der Ansage 00066 00067 // Texte für die Anzeigen und die Audio-Dateiauswahl 00068 //--------------------------------------------------------------------------------------------------------------------------------------- 00069 const char AnsageAudio[5][40] = { 00070 {"/sd/Bahnhof1.wav"}, 00071 {"/sd/Bahnhof2.wav"}, 00072 {"/sd/Bahnhof3.wav"}, 00073 {"/sd/Bahnhof4.wav"}, 00074 {"/sd/Bahnhof5.wav"} }; 00075 00076 const char AnzeigeText[5][40] = { 00077 {"Bahnhof 1\n\nEndstation\nRestaurant"}, 00078 {"Bahnhof 2\n\nLoewengehege"}, 00079 {"Bahnhof 3\n\nRegenwald"}, 00080 {"Bahnhof 4\n\nSchweizer-Tiere"}, 00081 {"Bahnhof 5\n\nEndstation\nStreichel-Zoo"} }; 00082 00083 InterruptIn Reed1(p16); //Eingänge der Reed-Kontakte (LOW aktiv) 00084 InterruptIn Reed2(p17); 00085 InterruptIn Reed3(p18); 00086 InterruptIn Reed4(p28); 00087 InterruptIn Reed5(p30); 00088 00089 00090 // Funktion zum lesen des Potentiometerwerts und setzten der Ausgangslautstärke 00091 //------------------------------------------------------------------------------------------------------------ 00092 void SetVolume(void) 00093 { 00094 audio.outputVolume(1-aIn, 1-aIn); 00095 } 00096 00097 00098 // Funktion zum lesen des Zirkular-Speichers und zum senden der Daten zum TLV320 00099 //------------------------------------------------------------------------------------------------------------ 00100 void isr_audio(void) 00101 { 00102 audio.write(RingBuffer, ReadPointer, 8); 00103 ReadPointer += 8; 00104 ReadPointer &= 0xfff; 00105 Theta -= 8; 00106 } 00107 00108 00109 // Funktion um den Zirkular-Speicher von der SD Karte zu laden 00110 //------------------------------------------------------------------------------------------------------------ 00111 void FillBuffer(void) 00112 { 00113 while(!feof(fp)) 00114 { //füllt den Zirkularspeicher bis zum Ende des Files 00115 static volatile int WritePointer = 0; 00116 if(Theta < 4096) 00117 { 00118 fread(&RingBuffer[WritePointer], 4, 4, fp); //liest 4 integer Werte auf einmal in den Zirzularspeicher 00119 Theta += 4; 00120 WritePointer += 4; 00121 WritePointer &= 0xfff; 00122 } 00123 } 00124 } 00125 00126 00127 // Interruptroutine für die Abfrage der Reed Kontakte (LOW aktiv) 00128 //------------------------------------------------------------------------------------------------------------ 00129 void ReedClosed() 00130 { 00131 wait_ms(DEBOUNCING_INTERVAL); 00132 { 00133 if((Reed1 == 0 || Reed2 == 0 || Reed3 == 0 || Reed4 == 0 || Reed5 == 0) && (AnsagePlay == false)) 00134 { 00135 AnsagePlay = true; //eine Ansage ist zum abspielen bereit 00136 00137 if(Reed1 == 0) AnsageNr = 0; //Ansage Nr 1 Endstation Restaurant 00138 else if(Reed2 == 0) AnsageNr = 1; //Ansage Nr 2 Löwengehege 00139 else if(Reed3 == 0) AnsageNr = 2; //Ansage Nr 3 Regenwald 00140 else if(Reed4 == 0) AnsageNr = 3; //Ansage Nr 4 Schweizer Tiere 00141 else if(Reed5 == 0) AnsageNr = 4; //Ansage Nr 5 Endstation Streichelzoo 00142 00143 pc.printf("%s\n",AnzeigeText[AnsageNr]);//zur Kontrolle den Text auch auf der serielle Schnittstelle ausgeben 00144 lcd.cls(); //LC-Display löschen 00145 lcd.printf("%s",AnzeigeText[AnsageNr]); //Bahnhoftext auf LCD ausgeben 00146 } 00147 } 00148 } 00149 00150 00151 // Hauptprogramm (hier beginnt der Programmablauf, "main" muss immer existieren) 00152 //--------------------------------------------------------------------------------------------------------------------------------------- 00153 int main(int argc, char *argv[]) 00154 { 00155 pc.baud(115200); 00156 00157 audio.power(0x02); //Mikrofon aus 00158 audio.inputVolume(0.2, 0.2); //Eingangspegel 0.0 bis 1.0 (leftVolumeIn, rightVolumeIn) 00159 audio.outputVolume(0.5, 0.5); //Ausgangspegel 0.0 bis 1.0 (leftVolumeOut, rightVolumeOut) 00160 audio.frequency(44100); //8kHz, 8.021kHz, 32kHz, 44.1kHz, 48kHz, 88.2kHz, 96kHz -> Default ist 44.1kHz 00161 audio.attach(&isr_audio); //Interrupt für die I2SxxFIFOs 00162 00163 Reed1.mode(PullUp); Reed1.fall(ReedClosed); 00164 Reed2.mode(PullUp); Reed2.fall(ReedClosed); 00165 Reed3.mode(PullUp); Reed3.fall(ReedClosed); 00166 Reed4.mode(PullUp); Reed4.fall(ReedClosed); 00167 Reed5.mode(PullUp); Reed5.fall(ReedClosed); 00168 00169 pc.printf("--------------------\nSTART\n--------------------\n\n"); // "START" auf erste Zeile schreiben 00170 wait(2); // 2s warten 00171 00172 // t.start(); //Timer start 00173 00174 while(1) 00175 { 00176 if (AnsagePlay == true) 00177 { 00178 // audio.start(TRANSMIT); //Interrupt starten (NONE, nur TRANSMIT, nur RECEIVE, BOTH) 00179 pc.printf("%s\n\n",AnsageAudio[AnsageNr]); 00180 00181 fp = fopen(AnsageAudio[AnsageNr],"rb"); 00182 00183 if(!fp) return(printf("File Error\n")); 00184 00185 fseek(fp, 22, SEEK_SET); fread(&Channels, 2, 1, fp); //Parse WAV File Header 00186 fseek(fp, 24, SEEK_SET); fread(&SampleRate, 4, 1, fp); 00187 fseek(fp, 34, SEEK_SET); fread(&WordWidth, 2, 1, fp); 00188 audio.format(WordWidth, (2-Channels)); //setzen des Transferprotokoll 00189 00190 for(int j = 0; j < 4096; ++j) //RingSpeicher löschen 00191 { 00192 RingBuffer[j] = 0; //Zirkularspeicher löschen 00193 } 00194 00195 SetVolume(); //Ausgangspegel vom Potentiometer lesen (leftVolumeOut, rightVolumeOut) 00196 audio.start(TRANSMIT); //Interrupt kommt nur vom I2STXFIFO 00197 FillBuffer(); //kontinuierlich den Zirkularspeicher füllen 00198 audio.stop(); 00199 fclose(fp); 00200 AnsagePlay = false; 00201 } 00202 } 00203 } 00204
Generated on Mon Jul 18 2022 01:32:11 by
1.7.2