Ich habe große Probleme eine MircoSD-Karte per SPI anzusprechen, um fünf
wav-Dateien (22050Hz, 8-Bit unsigned, Mono) abzuspielen.
Für die Audioausgabe ist ein ATMega644A über Pin PB3 (OC0A) an einem
LM386 (Gain20) verbunden. Ein Test der Audioausgabe mit einer
synthetischen Tonleiter war erfolgreich.
Für das Auslesen der wav-Dateien, habe ich ein MicroSD Breakout Board+
von adafruit (http://www.adafruit.com/products/254) wie folgt
angeschlossen:
Pin PB4 (SS) an CS
Pin PB5 (MOSI) an DI
Pin PB6 (MISO) an DO
Pin PB7 (SCK) an CLK
GND an GND
5V an 5V
Vergleichbar mit:
http://circuitfun.files.wordpress.com/2009/02/spi-to-usd.jpg?w=497&h=345
Wenn ich den MyWavePlayer-Code von Holger Klabunde
(Beitrag "Re: Sprachausgabe mit AVR") verwende und an
den ATMeag644 anpasse, passiert nichts.
Alle Versuche den Timer0 (Fast-PWM) an PB3 zu aktivieren schlugen fehl.
Mit dem Code von Holger Klabunde kam ich nicht zurecht und bin auf die
SPI/FAT-Lib von Daniel R.
(http://www.mikrocontroller.net/articles/AVR_FAT32) gewechselt.
Leider bekomme ich immer noch keinen Ton aus dem µC.
Sowohl der Timer, als auch die korrekte Anbindung der MircoSD scheint
schwierig. Die SPI-Lib benutzt nicht den SPI_SS aber ich schon, dafür
MMC_Chip_Select, aber ich nicht. Kann man einfach beiden den gleich Port
zuweisen?
Statt einer UART-Ausgabe verwende ich LEDs zur Statusanzeige. Da alle
drei LEDs leuchten, gehe ich mal davon aus, dass ein Zugriff auf die
MicroSD besteht.
Wenn der Timer korrekt eingestellt ist, dürfte die Abspielfunktion
falsch sein.
1
#include<avr/io.h>
2
#include<avr/iom644.h>
3
#include<avr/interrupt.h>
4
5
#include"config.h"
6
#include"file.h"
7
#include"fat.h"
8
#include"mmc.h"
9
#include<string.h>
10
#include<stdlib.h>
11
12
voidPlayWave(char*name);
13
voidStartTimer(void);
14
voidStopTimer(void);
15
16
17
voidPlayWave(char*name)
18
{
19
20
// Datei existiert also lesen.
21
if(MMC_FILE_EXISTS==ffopen(name))
22
{
23
24
unsignedlongintseek=file.length;// setzen einer Variable und dann runterzaehlen geht am schnellsten !
25
26
StartTimer();// start playing
27
28
do{
29
OCR0A=ffread();
30
}while(--seek);
31
32
StopTimer();// stop playing
33
34
ffclose();
35
}
36
}
37
38
39
40
41
// Timer0 für die Audioausgabe
42
voidStartTimer(void)
43
{
44
TCCR0A=(1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(1<<WGM00);// Mode 3: Fast PWM top=0xFF
45
TCCR0B=(1<<CS00);// Fast PWM (mode 3), no prescaler
46
47
OCR0A=((F_CPU/8)/22050)-1;// Set interval timer (sampling period)
48
49
DDRB|=(1<<PB3);// OC0A
50
51
TIMSK0|=(1<<OCIE0A);//Start
52
TIFR0|=(1<<OCF0A);
53
}
54
55
56
// Stoppt Timer0 für die Audioausgabe
57
voidStopTimer(void)
58
{
59
TIMSK0&=~(1<<OCIE0A);
60
}
61
62
63
64
// Hauptprogramm */
65
intmain(void)
66
{
67
68
// Als Ausgänge für die LEDs sind definiert:
69
DDRA=0b11111111;
70
DDRC=0b11111111;
71
72
PORTA|=(1<<PA7);// ein -> System Ready!
73
74
75
// Versuch Karte zu Initialisieren, bis es klappt.
76
while(FALSE==mmc_init())
77
{
78
nop();
79
PORTA|=(1<<PA1);// ein -> Karte gefunden!!
80
}
81
82
// Fat initialisieren.
83
while(FALSE==fat_loadFatData())
84
{
85
//nop();
86
PORTA|=(1<<PA4);// ein -> Init OK. Jetzt kann man lesen
// OCR1A is a 16-bit register, so we have to do this with
26
// interrupts disabled to be safe.
27
OCR1A=TIMER1_OCR_VALUE;
28
29
// Enable interrupt when TCNT1 == OCR1A
30
TIMSK1|=(1<<OCIE1A);
31
32
//enable interrupts
33
sei();
34
35
}
Zum Test der Audioausgabe über OCR0A (ISR Timer1), wurde mit Hilfe von
wav2c eine sounddata.h generiert und erfolgreich getestet.
Zur Einbindung der MicroSD kämpfe ich immer noch mit der SPI/FAT-Lib von
Klabunde. Folgender Code sollte eigentlich gehen:
1
PORTA|=(1<<PA7);// LED A ein -> System Start!
2
3
MMC_IO_Init();
4
5
6
if(GetDriveInformation()!=F_OK)// get drive parameters
7
{
8
PORTA|=(1<<PA4);// LED D ein -> No Flash!!
9
while(1);
10
}
11
else
12
{
13
PORTA|=(1<<PA1);// LED G ein -> Karte gefunden!!
14
}
Beim Start des µC ohne MicroSD leuchten die LEDs A und D. Mit
MicroSD-Karte leuchtet nur die LED A und nichts geschieht weiter.
Ein Abspielen der Sounddateien findet auch nicht statt.
Was könnte die Ursache sein??
>Was könnte die Ursache sein??
Nur mal so nebenbei:
Der Originalcode benutzt Timer1 für die Samplerate
und Timer2 mit FastPwm für die Ausgabe an PD7.
Warum versuchst du es nicht erst einmal mit
dem Originalcode?
holger schrieb:>>Was könnte die Ursache sein??>> Nur mal so nebenbei:> Der Originalcode benutzt Timer1 für die Samplerate> und Timer2 mit FastPwm für die Ausgabe an PD7.>> Warum versuchst du es nicht erst einmal mit> dem Originalcode?
Der µC ist auf einer vom mir entworfenen Platine gelötet und Änderungen
sind nur sehr eingeschränkt möglich.
Der Audioausgang befindet sind am Pin PB3 (OC0A), so dass nur Timer 0
für den Fast PWM mode in Frage kommt. Timer 1 übernimmt den CTC Mode.
Timer 2 dient einem anderen Zweck, welcher bereits läuft und später mit
der Audioausgabe gekoppelt werden soll.
Mal abgesehen davon, zum Aufruf der Funktion "void StartTimer(void)"
kommt es erst gar nicht, weil die Bedingung
"if(GetDriveInformation()!=F_OK)" weder die LED D noch die LED G
leuchten lässt.
Scheinbar ein vorzeitiger Stopp.
>Mal abgesehen davon, zum Aufruf der Funktion "void StartTimer(void)">kommt es erst gar nicht, weil die Bedingung>"if(GetDriveInformation()!=F_OK)" weder die LED D noch die LED G>leuchten lässt.>>Scheinbar ein vorzeitiger Stopp.
Das würde ich auch so sehen;)
Dein Board benutzt Spannungsteiler als Levelkonverter.
Das ist schon mal ziemlicher Schrott.
Abgesehen davon dürfte das Programm nicht hängen bleiben. Benutzt
du den SS Pin als Ausgang? Oder hast du da auch
dran rumgefummelt?
holger schrieb:> Abgesehen davon dürfte das Programm nicht hängen bleiben. Benutzt> du den SS Pin als Ausgang? Oder hast du da auch> dran rumgefummelt?holger schrieb:> Und was machst du? Bullshit.
Bitte hier im Forum nicht ausfallend werden, sondern sachlich bleiben.
So ist keinem gedient.
Dieses Forum dient dazu bei Problemen mit µC zu helfen.
Wie bereits oben erwähnt, ist der µC wie folgt angeschlossen:
Pin PB4 (SS) an CS
Pin PB5 (MOSI) an DI
Pin PB6 (MISO) an DO
Pin PB7 (SCK) an CLK
GND an GND
5V an 5V
Zwischen µC und SD-Karte selber ist ein 4050D Pegelwandler, sowie eine
4,7k/10K-GND Spannungsteilung auf den Leitungen MOSI, SS und SCK.
Letzter kann entfernt werden, so dass der µC direkt an den 4050D
angeschlossen ist.
Nachtrag:
Nach Durchsicht des Datenblattes zum 4050D, habe ich die drei 4,7K
entfernt, aber die drei 10K belassen. Folge: Es kann auf die MicroSD
zugegriffen werden. Somit war die Spannungsteilung die Ursache, was ich
ein wenig komisch finde.
Danke für den Tipp.