PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : problem mit interrupt timer!!!



humma6
18.06.2007, 19:48
hallo!

ich hätte eine frage zu folgendem programm! und zwar kann ich mir nicht erklären wieso bei SIGNAL der aufruf alle 4096ms erfolgt! bräuschte man da nicht das tccr0 um den takt zu teilen?? und was macht das sei() genau? was ich auch nicht verstehe ist was man mit dem us % 10000 anfangen soll!!

bitte dringentst um hilfe!!


SIGNAL(SIG_OVERFLOW0) //Aufruf alle 4.096ms
{
// user code here
us += 4096;
if(us >= 10000) //0.01s sind abgelaufen
{
++hs;
us = us % 10000;
}
}

int main( void )
{
unsigned char Tasten;
int cou=0;

Disp_enable();
Disp_clear();



TIMSK |= 0x01; //Timer Interrupt freigeben

sei(); //Alle Interrupts einschalten

while(1) //endlosschleife
{
Tasten = Get_Tasten();


sprintf(zeile,"Zeit=%02i:%02i:%02i,%02i",std,min,sec,hs);
Disp_write_xy(0,0,zeile);


}
}


danke im voraus!

blan
19.06.2007, 10:39
hallo,

also erstmal solltest du das SIGNAL durch ISR ersetzen - SIGNAL ist veraltet.

Die Funktion sei() schaltet die Interrupts ein. Ohne diesen Befehl werden die Interrupts nicht ausgelöst. Intern werden wohl einfach paar Bits in ein Register geschrieben. Um es für jeden µC zu vereinheitlichen gibts dann halt die Funktion sei().

mfg blan

humma6
19.06.2007, 11:11
ah danke! und ws mir auch noch komisch vorkommt ist das hier niergedwo ein tccr gesetzt wird! und anscheinend trotzdem eine vorteilung stattfindet!?
woran kann das liegen?

blan
19.06.2007, 11:19
welchen µC verwendest du denn?
ich könnte mir vorstellen, dass das Register TCCR einfach schon bestimmte Bits gesetzt hat und die den prescaler setzen - praktisch so default-zustände. dazu muss man ein blick ins datenblatt werfen.

mfg blan

humma6
19.06.2007, 11:35
einen atmega128!

blan
19.06.2007, 12:58
also im datenblatt für den atmega128 auf der seite 103-105 steht, dass alles bits mit 0 initalisiert werden. ein prescaler mit 0 stoppt den timer - er sollte also garnicht erst laufen.

edit:

TIMSK |= 0x01;
die codestellt gefällt mir auch nicht. korrekt sollte es so aussehen:


TIMSK |= (1 << TOIE0);
ein wichtiger grundsatz bei der programmierung lautet: never use magic numbers.

mfg blan

humma6
19.06.2007, 14:24
heist das also wen ich hier einen vorteiler setzten würde würde der timer gar nicht laufen? und läuft er dann in meinem programm von haus aus mit 4096ms?

blan
19.06.2007, 16:09
heist das also wen ich hier einen vorteiler setzten würde würde der timer gar nicht laufen? und läuft er dann in meinem programm von haus aus mit 4096ms?

nein, wenn du keinen prescaler setzt dann läuft der timer überhauptnicht. außerdem kommt es noch draufan wie groß deine taktfrequenz ist. wirf doch ein blick in das datenblatt dort ist alles wunderbar beschrieben.

mfg blan

humma6
19.06.2007, 17:21
also würde das funtionieren?

unsigned int us; // Zeit in Microsekunden
unsigned int hs;

SIGNAL(SIG_OVERFLOW0) //Aufruf alle 4.096ms
{
// user code here
us += 4096;
if(us >= 10000) //0.01s sind abgelaufen
{
++hs;
us = us % 10000;
}

}

int main( void )
{

TCCR0 |= 0b00000110; //prescaler auf 256 setzten

TIMSK |= 0x01; //Timer Interrupt freigeben

sei(); //Alle Interrupts einschalten

while(1) //endlosschleife
{
}
}

humma6
19.06.2007, 17:56
ach und noch eine blöde frage habe ich! und zwar werden in der µc programmierung zeiger auschließlich zum ansprechen von registern benützt?

blan
19.06.2007, 18:22
bitte benutz für die zukunft die code-tags. beim lesen von so unformatiertem code bekomm ich augenkrebs ;)

wieso benutzt du weiterhin SIGNAL statt ISR?
außerdem versteh ich nicht warum du die register mit konkreten werten füllst und dann noch eine order-verknüpfung reinmachst, das bringt überhaupt nichts. und benutz bitte keine magic numbers auch wenn ein kommentar dahinter steht.



TCCR0 |= (1 << CS01) | (1 << CS02);
TIMSK |= (1 << TOIE0);


wenn du den code nicht versteht frag nach oder schau im wiki https://www.roboternetz.de/wissen/index.php/Avr-gcc

ob der code so funktioniert kann ich nicht sagen. außerdem weiss ich nichteinmal mit welcher frequenz dein takt läuft.

wie meinst du das mit den zeigern für register? ich benutz zum ansprechen meiner register nie ein zeiger. pointer werden z.B. benutzt um zeichenketten zu realisieren weil man unter C keine strings kennt.

mfg blan

humma6
19.06.2007, 18:53
sie müssen verstehen, dass ich am freitag matura habe und mein lehrer diesen code so formuliert hat! jetzt will ich nicht großartig viel daran ändern!
und mein takt ist 16MHz! und er hat auch gesagt das man pointer zum ansprechen von pins und registern benützt! also weis ich nicht genau!

mfg

blan
19.06.2007, 19:52
was ist denn nun die frage wie man den overflow alle 4096ms auslösen lässt oder warum er alle 4096ms auslöst?

beim ersten sollte sich das doch mit ein wenig mathe ausrechnen lassen...

mfg blan

humma6
19.06.2007, 20:09
wenn das stimmt wie ich den tccr gesetzt habe ist mir klar warum er alle 4096ms auslöst da dann alle 4096ms ein overflow stattfindet und somit die isr auslöst!

denn 16000000/256=62500

256/62500=4096ms!

aber ich bin mir nicht sicher ob das programm so richtig ist wie ich es hier gepostet habe!

mfg

blan
20.06.2007, 21:25
du kannst doch eine zählroutine machen und sobald bis zu einem bestimmten wert gezählt wurde wird der entsprechende code ausgeführt und die zählveriable wieder auf null gesetzt. leider versteh ich den code nicht ganz.

mfg blan

fluchtpunkt
21.06.2007, 14:09
am freitag matura
Ich sehe schwarz (nicht zu ernst nehmen)

Der Punkt zwischen 4 und 096 ist KEIN Tausendertrennzeichen, sondern so wie in allen Programmiersprachen ueblich ein Komma das wie ein Punkt aussieht. Das kann man auch am Code im Signalhandler erkennen!
Also schmeiss deinen Vorteiler wieder raus, bzw aender den auf den richtigen Wert.


Edit: Achja der Code ist trotzdem scheisse. Wenn man alle 10ms was ausfuehren will dann braucht man bei einem Interrupt alle 4.096ms ja minimum 3 Durchlaeufe, was dann schon wieder 12ms sind. Dann merkt man sich die 2ms und dann kommt der naechste Interrupt schon nach 2 Durchlaeufen also 8ms, der naechste dann wieder nach 12ms usw.

Und ich ahne schlimmstes was noch an die Stelle "// user code here" kommen soll.