Elektronik & mp3 h- mpeg der erste standalone mp3 Player im Eigenbau
|
| Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
| Autor |
Nachricht |
Speedy
Anmeldungsdatum: 04.01.2003 Beiträge: 54
|
Verfasst am: 09.01.2003, 09:05 Titel: Wie funktionieren die Timer beim H-Mpeg |
|
|
Hallo zusammen,
kann mir mal einer erklären, wie man die Timer für den Atmel 8515 und ATMega103 programmieren kann.
Leider kann ich kein Assembler und verstehe daher die Befehle in den bestehenden Code-Sourcen nicht wirklich.
Wäre supi, wenn mir das mal einer erklären könnte. Am besten für für 'blöde' und mit Code-Beispielen.
Speedy
|
|
| Nach oben |
|
 |
Joerg_B
Anmeldungsdatum: 02.01.2003 Beiträge: 55 Wohnort: Hannover +- garnix (^_^)
|
Verfasst am: 09.01.2003, 10:05 Titel: |
|
|
Hallo
dann wollen wir mal (hoffentlich verbocke ich jetzt keinen zu großen Müll *ggg*)
[code:1]
//Ein Beispiel für Timer0 als Delay und Timer1 als Int Quelle
//Timer1 clk in 125ns (8000 = 1ms)
#define T1_CLK 8000 //Quarzfreq. in kHz
#define TI1_H (((0xFFFF - T1_CLK)>>8) & 0xFF) //(Re)Loadwert high für Timer1
#define TI1_L ((0xFFFF - T1_CLK) & 0xFF) //(Re)Loadwert low für Timer1
//Bei 8MHz dauert ein interner Takt 125ns
//Der Timer1 läd aufwärts bis 0xFFFF und lößt dann einen Interrupt aus
//Bei einem Reload von (0xFFFF - 8000) ergibt das 8000 x 125ns = 1ms
SIGNAL(SIG_OVERFLOW1) //Timer1 overflow Interrupt
{
//restart timer
outp(TI1_H,TCNT1H); //reload Timer1 high
outp(TI1_L,TCNT1L); //reload Timer1 low
//Code nach belieben
}
void delay (unsigned short count) //Delay in ms (ca.)
{
for(; count !=0; count--)
{
timer0_stop(); //Timer0 Stop (aus <timer.h>)
timer0_source(CK1024); //Timer0 auf µC-Clk/1024 einstellen
timer0_start(); //Timer0 starten
while(inp(TCNT0) < 9 ) //TCNT0 enthält den Zählerstand
{ //8 "Ticks" --> ca. 1ms
}
}
timer0_stop();
}
int main (void)
{
//init Timer1 -> SERVICE routine
outp((1<<CS10),TCCR1B); //Timer1 Takt = µC-Takt
outp(TI1_H,TCNT1H ); //Timer1 high Wert laden
outp(TI1_L,TCNT1L); //Timer1 low Wert laden
sbi(TIMSK, TOIE1); //enable Timer1 interrupt
sei(); //global interrupt enable
for (;;) //Endlos(haupt)schleife
{
//Code nach belieben
}
}
[/code:1]
weitere Frage oder Kommentare?
Jörg _________________ Aus einem Auto Chat:
"Ich stehe da lieber daneben, wenn Gott gewollt hätte das Maschinenbauer etwas von Elektronik verstehen, hätte er die Atome in Melonengröße gestaltet"
|
|
| Nach oben |
|
 |
Oli
Anmeldungsdatum: 04.01.2003 Beiträge: 109
|
Verfasst am: 09.01.2003, 17:38 Titel: |
|
|
Speedy,
wie die Timer (und der ganze Rest) funktonieren, steht im Datenblatt des entpsr. Controllers, das Atmel freundlicherweise zum Downlaod anbietet.
Das muss man natürlich gelesen und verstanden haben.
Die wichtigsten "Assembler"-Befehle, die du zum Hardwarezugriff brauchst, sind outp() und sbi(). Das sind C-Macros, die genau den gleichnamigen Assemblerbefehl erzeugen.
outp(wert, port) schreibt den 'wert' an die IO-Adresse 'port'.
sbi(port, bit) setzt das entspr. 'bit' des IO-Ports.
Achtung:
in neueren GCC Versionen (ab 3.2), gibt es Makros outb() usw (b statt p) mit umgekehrter Parameter-Reihenfolge).
Aber diese IO-Makros sind dort eh missbilligt (deprecated), d.h. es wird deren Verwendung nicht mehr empfohlen. Statt dessen kann man nun die Ports direkt beschreiben, wie bei den meisten kommerziellen Compilern:
z.B.
PORTA = 0x12; // vorher: outp(0x12, PORTA);
PORTB |= _BV(5); // vorher sbi(PORTB, 5)
while (USR & _BV(UDRE) == 0); // vorher: loop_until_bit_is_set(USR, UDRE);
Es wird angeblich der gleiche Code erzeugt.
Geht aber wie gesagt erst ab GCC 3.2
Oli _________________ http://tscherwitschke.de
|
|
| Nach oben |
|
 |
Speedy
Anmeldungsdatum: 04.01.2003 Beiträge: 54
|
Verfasst am: 09.01.2003, 20:15 Titel: |
|
|
Hallo Joerg, Oli,
soweit habe ich das jetzt verstanden (hoffe ich ).
Aber leider will es nicht so recht klappen.
In meinem konkreten Fall will ich alle ? ms eine Funktion aufrufen.
Ich habe also erstmal eine globale Variable unsigned int func_call_ms deklariert und diese mit 0 initialisiert.
( unsigned int func_call_ms = 0; )
In der Funktion SIGNAL( SIG_OVERFLOW) habe ich dann vor dem Timer reload geprüft, ob die eingestellte Zeit schon rum ist.
...
...
if (func_cal_ms <= 250) // Nach Eurer Berechnung ca. alle 0,5 Sekunden
{
func_cal_ms++;
}
outp( TI1_H, TCNTT1H);
...
Den eingentlichen Funktionsaufruf habe ich dann am ende der Main Funktion untergebracht (jedoch innerhalb der Endlos-While).
...
...
if (func_call_ms > 250)
{
Meine_Function(); // eigentlicher Funktionsaufruf
func_call_ms = 0; // Rücksetzten meiner Timervariable
}
...
} // Ende While
} // Ende Main
Aber leider funktioniert das nicht richtig.
Zur kontrolle lasse ich mir einfach mal Zeichen auf die serielle übertragen.
Es wird 0 gesendet, wenn der Wert <= 250 ist.
Es wird x gesendet, wenn der Wert > 250 ist.
Es wird Z gesendet wenn die Funktion aufgerufen wurde.
Und meine Ausgabe sieht nach einschalten des Players wie folgt aus:
00000000000000000000000000000000000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx000000000000000000000000000000000000000000000000000000000000000000000000000000
Hinweis: die Anzahl von 0 und x stimmen nicht mit meiner seriellen Übertragung überein. Es soll nur verdeutlichen, das kein Z auftaucht, ob wohl der Timer eindeutig abgelaufen war!!!
Weiterhin wird zwar meine Variable wieder auf 0 gesetzt, aber sie erreicht nie mehr x oder den Funktionsaufruf
In der Funktion Meine_Function() wird nur das z ausgegeben [ putchar( 'z' ) ] sonst nix.
Was ist falsch?
1. Warum wird die Funktion nicht gestartet?
2. Warum erreicht die Variable nicht mehr den Wert 250?
Speedy
|
|
| Nach oben |
|
 |
Speedy
Anmeldungsdatum: 04.01.2003 Beiträge: 54
|
Verfasst am: 09.01.2003, 23:57 Titel: |
|
|
Hat sich erledigt.
War nur ein verdammter Schreibfehler
Speedy
|
|
| Nach oben |
|
 |
grobi71
Anmeldungsdatum: 13.05.2003 Beiträge: 8 Wohnort: 83646 Bad Tölz
|
Verfasst am: 04.02.2004, 13:39 Titel: |
|
|
Hallo,
Habe gerade meinen Compiler (WINAVR) upgedatet und erhalte nun beim
compilieren vom minimega_newb2 die Fehlermeldung:
In file included from serial.c:7:
my_defs.h: In function `timer2_start':
my_defs.h:170: error: invalid lvalue in unary `&'
make: *** [serial.o] Error 1
am Programm wurde eigentlich nichts geändert.
Gruß
Grobi
|
|
| Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|