Timer zählt nicht

wupps okeee sry ja das ja nur n 8 bit timer :)

na blubb nun komm ich drauf ..

du wolltest doch irgendwie eine Zeit messen zwischen 2 Interrupts oder ?

Code:
CS0 CS1 CS2 External clock source on T0 pin. Clock on rising edge.

du hast deinen Timer darauf eingestellt das er nur hochzählt wenn du ein Clock Signal an deinem T0 Pin anlegst !!!


Du willst doch die Zeit messen die zwischen deinen Interrupts kommt ...

dann musst du deinen Timer laufen lassen ...

Code:
If external pin modes are used for the Timer/Counter0, transitions on the T0 pin will clock the
counter even if the pin is configured as an output. This feature allows software control of the
counting.

.........

du musst einen Prescaler auswählen ...

dafür musst du wissen welche zeiten du ca. messen willst ..

wenn du einen 8Mhz Quarz hast .. hast du pro tackt 125ns bei einem Prescaler von 1.
hast du einen Prescaler von 1024 bist du bei 128µs pro Tackt ...( 8MHz / 1024 = 7812,0Hz.. 1/ 7,8khz ~ 128µs, dein Timer hat 0xff also 128µ * 0xff ~ 32ms).womit du auf eine maximal zeit von ~32ms kommst, kommst du drüber macht er die runden immer wieder nur bekommst du das nicht direkt mit...
 
Hallo,

DDRB = 0xFF darfst du nicht auskommentieren, sonst ist der PORTB Input.

Selbst wenn du die If-Abfrage nach unten schiebst, wird das nicht funktionieren. Die If-Abfrage wird dann wahr, wenn "hilf=1" ist. Das wird nur 1 wenn die ISR des externen Interrupts INT0 aufgerufen wird,
ich schätze mal dass du nach power on und stabilisiertem Takt ein paar 100ns Zeit hast, den Interrupt auszulösen ... das ist nicht viel :rolleyes: Danach landest du in der While(1)-Schleife.

Dirk
 
öööhhhmm^^ man ist das verwirrend wenn sich 2 unterhalten von dennen einer voll den plan hat der andere sich seid 4 wochen damit auseinander setzt aber dafür die aufgabenstellung kennt^^

also geplant ist das wenn eine steigen flanke kommt in den interrupt gesprungen wird der timer ausgeben und auf null gesetzten wird und bei der näcchsten steigenden Flanke das ganze nochmal und die if verzweigung soll halt prüfen ob es einen neuen wert gibt heißt ob man im interrupt war!

prescaler?! das heißt du willst immer nach eine bestimmten anzahl von takten in den interrupt springen oder wie genau meinst du das?
 
hi,

^^
nein ich will garnichts :p

nein scherz bei seite ..

Prinzipiell hat dein Externer Pinchange Interrupt INT0 überhaupt nichts mit deinem Timer zu tun .. der INT0 wird Angesprungen wenn eine Flanke auf deinem Externen Int passiert und dein Timer soll zählen ...

Ein Timer braucht von dem Quarz einen Tackt (ob intern oder extern ist egal). Damit dieser überhaupt "messen" kann ...

Du hast ihn nun so eingestellt, dass er auf dem externen Eingang T0 diesen Tackt erwartet und nicht von dem Quarz.
Somit wird sich dein TCNT0 nie von alleine Ändern nur durch ein Schalten am T0 ...

So du willst aber, dass durch den Quarz das automatisch passiert.
So ein Prescaler (Vorteiler) ist dafür da dass du nicht die 8MHz direkt nehmen musst sondern Aussuchen kannst mit welcher Geschwindigkeit der TCNT0 hochgeählt wird. Eben 8MHz (ich weiß nicht was du als Quarz hast aber vom Prinzip ist das egal ich geh einfach mal von 8MHz aus). Rechnung ist im Post oben von mir.

Schau mal im Datenblatt unter Table 14-9. Clock Select Bit Description (Ich hab nun mal einfach vom M168 geschaut ist ja in dem Punkt das selbe wie der M88).

Ich Empfehle dir einfach mal zum Testen CS2 & CS0 zu setzen ...
TCCR0B = (1<<CS2) | (1<<CS0);

ich schreib dir deinen Ablauf mal schemenhaft hin umsetzen bitte selbst ;)

Init deines Controllers mit Ports und DDRs und Interupt und Timer ...

Code:
int main()
{
char wort[100] = {'H','a','l','l','o',' ','W','e','l','t','\n','\0'};
int zahl = 467;
//char wort[10];
TCNT0 = 0x00;

das kannst ja mal soweit lassen...

deine Ports und alles noch Initialisieren .. DDRB = 0xFF; ... das ganze halt Uart ... halt einfach dein Init .. das sollte mit als erstes passieren

jetzt Starte den Timer wie ich oben geschrieben hatte .. mit cs2 und cs0

jetzt die
Code:
	while (1)  // Blinken
	{

		PORTB = TCNT0;										// Counter ausgeben
		_delay_us(100000);	
		PORTC |= (1<<PC3);									//LED an
		_delay_us(100000);
		PORTC &= ~(1<<PC3); 							 	// LED aus
		
	}

So jetzt müste sich PORTB wie wild verhalten .. lass den puts und das ganze mal eifnach weg brauchst du erst mal nicht ...


lies dich aber bitte noch in Timer weiter ein .. das war nun nur ein "crash" kurs du musst mit den Zeiten sehr aufpassen da der Timer sonst überläuft und joar...

Was Dirk und ich von anfang an sagten .. ein Timer bei dem der Prescaler auf dem Oszillator liegt läuft sobald der Prescaler gesetzt ist los ... das ist reine Hardware an der Stelle.

Hoffe ich konnts dir damit etwas klarer machen
gruß,
Manuel
 
jaein ;) aber trotzdem vielen dank!

mir fehlen einfach noch viel zu viel grundkenntnisse die ich nur durchs lesen nich verstehe bzw. die anwendung nich verstehe ...aber das wird schon ^^

danke nochmal!
 
ne nich wirklich es liegt an mehreren sachen schätz ich ^^

es macht auch was es will ... mal funkt das mal nur das dann springt in den interrupt obwohl nix angeschlossen ist ...

ich sag ich weiß davon leider viel zu wenig um irgendwas zu erkennen ...
 
Ja die Grundkentnisse in dem Punkt zu stärken wäre auf jeden fall sehr sehr wichtig ... ^^

mit was arbeitest du den STK 500 oder eigene Hardware hast du ein Dragon/ JTAG ICE um zu Debuggen oder machst alles im Simulator ... ?
 
ehm wenn ich dich richtig verstehe eigene hardware ^^ hab mir ne Platine gebastelt ... und jab benutze JTAG ICE

ja mit den Grundkenntnissen is es halt sonne sache wenn man keine zeit hat weil das Projekt fertig werden muss... ich finds halt selber auch schade gerade wenn man die interesse hat es richtig zu vestehen ... und nur son tutorial hilft halt auch nicht immer weiter
 
So jetzt mal was ganz quick & Dirty ...

Code:
#define F_CPU 8000000UL

//#define Aufgabe


#define LED_PORT PORTC
#define LED_PIN PC3
#define OUT_PORT PORTC
#define OUT0 PC2
#define OUT1 PC3
#define OUT2 PC4
#define OUT3 PC1
#define OUT4 PC0

#define IN_PORT1 PINB
#define IN_PORT2 PIND
#define IN10 PB0
#define IN11 PB2
#define IN20 PD6
#define IN21 PD7


#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

volatile int zeit = 0;

ISR(INT0_vect)
{
// das hier ist der Int von PD2, (INT0) wird immer getriggert wenn pd2 auf low geht..
// Doch Achtung ...durch 8MHz / 1024 ~ 7,8khz ergibt also 128µsek je Tick ...
// ergibt bei einem Integer eine maximale laufzeit von 8,36544 sek. bis der Timer überläuft
// dann beginnt er wieder mit 0 (nur so wie hier bekommst du nichts mit ... 
// erweitert werden sollte das über ein Timer Interrupt der das dann mitzählt
// Ich habe den 16 Bit timer genommen da mit dem 8 Bit Timer nur 32ms max mitzählen könntest...
#ifdef Aufgabe
#else
	TCCR1B = 0; // steigende Flanke
	zeit = TCNT1;
	TCNT1 = 0; // <- hier mal den breakpoint setzen ..
	TCCR1B |= (1 << CS12) | (1 << CS10); // prescaler 1024 und los mit dem Timer
#endif
}

int main()
{

// Port Init

DDRC = (1<<PC3) | (1 << PC4);
PORTC = (1<<LED_PIN); //Led leuchten

DDRD = 0x00;
PORTD = (1<<PD2) | (1<<PD3) ; // Pullup, PD2 benötigt für INT, sobald auf low geht Int auslösen

DDRB = 0xFF;
PORTB = 0;

//externer Interrupt 0
EICRA |= (1<<ISC11) | (0<<ISC10) ; // fallende Flanke
EIMSK |= (1<<INT0);

sei();

//Timer
TCNT1 = 0x00;
TCCR1B |= (1 << CS12) | (1 << CS10); // prescaler 1024 und gleich mal los um den ersten mitzubekommen


	while (1) // Blinken
	{
	// wenn du das testn magst ... 
	#ifdef Aufgabe
	TCCR1B = 0; // einfach mal stoppen
	zeit = TCNT1;
	TCNT1 = 0;
	TCCR1B |= (1 << CS12) | (1 << CS10); // prescaler 1024 und los mit dem Timer

	// hier machen wir erst mal nichts .. nur ein Dummy delay ...
	_delay_us(12800);
        #endif
	

	}
}


das führt zwar nicht zum lern Erfolg aber wir sehen ob deine Hardware Funktioniert ...

Setz jetzt mal auf "TCNT1 = 0; // <- hier mal den breakpoint setzen .." im ISR einen Breakpoint ...

wenn jetzt deine Lichtschranke eine Low Flanke gibt -> PATSCH gibts ein Interrupt ...

SO und jetzt einfach noch meine Kommentare oben lesen ... dann sollte es hoffe ich klar werden -> Achtung hab die Frequenz auf 8MHz gestellt ...

Nun damit du auch noch etwas lern Erfolg hast hierbei ...

ich hab in deiner Main nur ein Delay ... (wird so erst mal wegoptimiert da es nichts macht).... deswegen wenn du normal eine Pause machst wirst du irgendwo landen :p

Jetzt mach mal
Code:
//#define Aufgabe
die // weg und Compilier neu ..

mach einen Breakpoint auf
Code:
TCCR1B = 0; // einfach mal stoppen
in der Main ...und lass es Starten

leg jetzt in dein Watch Fenster die Variable zeit.

So ... jetzt muss dort eine 0 sein ...

wenn du es nochmal laufen lässt muss dort eine 100 stehen -> bitte erklären wieso :p
und ich hau dir auf die Finger wenn du mir nun das falsche sagst *gggg*

Viel spass damit ;) ...der Code läuft auf jeden fall so

€dit ich hoffe mal bei dir auch .. hab ne ur alte winavr version drauf ^^ also ka .. bzw dran denken wegen der Optimierung vom gcc die auf -Os zu stellen ..

Gruß,
Manuel
 
=) du bist ja der hammer ^^

eh m um dir die antwort zu geben müsste ich verstehen was du in der rechnung machst wie kommst du auf 128µs und dann auf die max. laufzeit

ich bins im tutorial jetzt tausendmal durchgegangen aber die rechnen andere sachen bzw ich finde keinen zusammenhang zu deinem :eek:
und es steht nach dem dritten durchlauf ein 107 in zeit ...und es wechselt bei jedem weiteren durchlauf von 107 auf 108 und von 108 auf 107
 
Hi na 107 kann schon auch sein das liegt vermutlich daran weil du bei dir einen 7,xxxxxx Quarz verwendet hast ?

Es ist ganz einfach wie ich auf den Timer wert komme ...

und zwar ich geh einfach mal von 8MHz aus ... also 1/8MHz = 125ns.
So dein Timer wird von deiner Clock source getacktet ... wenn du einen Prescaler (Vorteiler halt dran hast sonst ist der Clock eingang offen und es Tacktet nix)...

Also bei einem Prescaler von 1 gehen die 8MHz an den Timer und er Clockt diesen mit 8MHz somit wenn im TCNTx eine 1 steht sind 125ns vergangen.

bei einem Prescaler von 2 eben 4MHz ....

...

bei einem Prescaler von 1024 eben 7,8125 Khz und somit wird alle 128µs der Timerwert um 1 erhöht.

durch das Delay von 12800us durch die Delay Funktion unten ... ergibt dir einfach einen Wert von 100 da einfach 12800 us / 128 us = 100 ..

Um das ganze noch zu veranschaulichen .. Figur 17-2 aus dem Datenblatt ...


€dit ... das du auf 108 kommst denke ich liegt daran dass du einen 7,37MHz Quarz verwendest ... deine delay macht es zwar richtig (wenn F_CPU angepasst ist ..) an der Stelle aber dein Timer hat ja nur die 7,37MHz zur Verfügung .. eigentlich hätte ich einen Wert von 94 rum erwartet ... aber daran würde ich mich nun nicht aufhängen ...

€dit2
was mir noch einfällt .. du sagst du schaust die Tutorials an aber verstehst es nicht ..
Die Tutorials die meisten zu mindest gehen alle auf ein Timer der meinetwegen alle 1ms ein Interrupt auslöst ...
Da willst du ja was anderes du willst ja einfach mitzählen wie lange die Zeit verstrichen ist .. (du kannst das ja auch einfach wieder auf Sekunden rück rechnen ..) wenn du in deinem TCNT1 Register eben eine 10000 hast bei 135,68µs (wenn nen 7,...) Quarz hast .. sind eben 1,3568 Sekunden verstrichen (hab ich aber auch im Code oben beschrieben ..) ich denke du solltest damit schon weiter kommen .. sonst einfach weiter Fragen ;) ich geb noch nicht so schnell auf :p


gurß,

Manuel
 
Hey
ja auf die zahl im delay hab ich natürlich nicht mal geachtet ;) :eek:

aber das hab ich jetzt sogar verstanden ^^ danke!...

hu das sagst du was... ich kann fragen stellen das glaubst du nich ; ) aber danke!!! =)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)