Forum: Compiler & IDEs verständnisfrage timer mega48


von andi (Gast)


Lesenswert?

Hallo,

Komme bei den Timern nicht zurecht.

Ich will mir einen Drehzahlmesser bauen der ein Signal Rechteck 
(KlemmeW) als eingang gibt.
Das Signal habe ich über einen Optokoppler an den AVR angebunden an PIN 
INT0.

Nun will ich einen Timer laufen lassen der alle 100ms einen flag setzt.
Die impulse die ich in dieser Zeit messe will ich zur errechnung der 
Drehzahl nehmen.

Mein Taktfrequenz 16MHz extern Quarz.
16bit timer.

bei prescaler 64 macht er 2500000Takte /s.

Im Timeroverflow muß er 3 mal überlaufen
weil 2500000/65536=3.

Ich muß also im Timer Overflow einen Zähler haben der bei 3 ein Flag 
setzt.

Ist die Berechnung des Timers korekt weil da komme ich nicht klar.
Habe schon die Tuts gelesen aber schalu werd eich nicht.


Besten Dank

Andi

von Karl H. (kbuchegg)


Lesenswert?

andi schrieb:

> Mein Taktfrequenz 16MHz extern Quarz.

OK. Also in 1 Sekunde hast du 16 Millionen CPU Takte

> 16bit timer.
>
> bei prescaler 64 macht er 2500000Takte /s.

250000

> Im Timeroverflow muß er 3 mal überlaufen
> weil 2500000/65536=3.

250000 / 65536
Eigentlich 3.81... mal.

Aber dann hast du ja 1 Sekunde abgemessen.
Das willst du aber ja gar nicht. Du bist doch auf 100ms, also 0.1 
Sekunden aus!


Das Problem ist, dass sich deine 16Mhz nicht besonders gut eigenen, um 
damit 0.1 Sekunde, 1 Sekunde oder irgendeinanderes auf 10 basierendes 
Vielfaches von 1 zu erhalten, wenn du nur Overflows benutzen kannst. 
16000000 / 65536 = 244.140625 und egal welchen Vorteiler du benutzt, du 
erhälst nie einen glatten Teiler.

Aber mit dem CTC MOdus kannst du das ändern, indem du den Maximalwert 
des Timers vorgeben kannst.

Siehe zb hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr

von andi (Gast)


Lesenswert?

Hallo


den CTC aktiviere ich mit

TCCR1A=0x00;
TCCR1B=(1 << WGM12) |(1<<CS10); //CTC und Vorteiler 1
OCR1A=; //für 100ms???
TIMSK1=(1 << OCIE1A)//Interupt compare match

Wie berechne ich OCR1A???

Danke

Gruß
Andi

von Karl H. (kbuchegg)


Lesenswert?

andi schrieb:

> Wie berechne ich OCR1A???

Warum bloss hab ich ständig das Gefühl, dass die Fragesteller sofort den 
Taschenrechner beiseite legen und das Hirn abschalten, wenn es um Timer 
geht und sie merken, dass ihnen jemand hilft.

Mit 16 Mhz und einem Vorteiler von x macht der Timer wieviele Zählungen 
in 1 Sekunde? Wieviele macht er dann daher in 0.1 Sekunde? Auf welchen 
Wert willst du daher OCR1A setzen, damit der Timer alle 0.1 Sekunden 
diesen Wert erreicht?

Heinweis: Der Wert kann als 16 Bit Wert nicht größer als 65535 sein. 
Kommt dir bei deiner Rechnerei was größeres raus, dann musst du einen 
größeren Vorteiler nehmen. Dadurch sinkt automatisch der Vergleichswert.

von andi (Gast)


Lesenswert?

Hallo,

Ich habe mal den Rechner rausgekramt

in 1 sek macht ein 16Mhz 16000000 ticks.

mit einen Vorteiler von 256 macht er dann 62500 ticks in einer sek.

Müsste so stimmen.

also bin ich unter dem 16Bit zählwert.

Also ist mein OCR1A = 62500 für eine sekunde??

für 100ms ist es 62500/10 6250??

Danke

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Also ist mein OCR1A = 62500 für eine sekunde??

62499

> für 100ms ist es 62500/10 6250??

6249

von Karl H. (kbuchegg)


Lesenswert?

andi schrieb:
> Hallo,
>
> Ich habe mal den Rechner rausgekramt
>
> in 1 sek macht ein 16Mhz 16000000 ticks.
>
> mit einen Vorteiler von 256 macht er dann 62500 ticks in einer sek.
>
> Müsste so stimmen.
>
> also bin ich unter dem 16Bit zählwert.
>
> Also ist mein OCR1A = 62500 für eine sekunde??
>
> für 100ms ist es 62500/10 6250??

Genau.
Allerdings ist 6250 weit unter dem erlaubten Maximum von 65535. Daher 
könntest du deinen Vorteiler mal etwas kleiner versuchen.

Nur das letzte Ergebnis zählt! Das muss kleiner als 65536 sein.

von Andi (Gast)


Lesenswert?

Hallo

Habe das ganze im AVR Hochgeladen udn muß feststellen das bei 
OCR1A=25000(bei Vorteiler64 =250000/s ->/10(100ms) 25000) meine 
Segmentanzeige die einen Zähler anzeigt der Zähler bei jedem Interupt so 
ausieht als ob es 1sekunde ist.
Wenn ich als OCR1A=2500 nehme könnte es 100ms sein.

Was mache ich falsch

hier mal mein code


timer init

cli();

TCCR1A=0x00;
TCCR1B=(1<<WGM12) | (1<<CS11) | (1<<CS10);
OCR1A=25000;
TIMSK1=(1<<OCIE1A);
sei();


SIGNAL(TIMER1_COMPA_vect)
{
timer1=1;
}




while(1)
{
if(timer1==1)
 {
 set_disp1(tt++,1,0,0); //zum ermitteln wie schnell der Timer läuft
 set_disp1(freq,1,0,0); //Hier die anzahl der gezählten impulse
 freq=0;
 timer1=0;
}
}



das kapier ich jetzt nicht


Ich habe ein Rechtecksignal mit 850µs Periode (1 Impuls).
Mit Oszi gemssen.

Das Signal greife ich über einen Interrupt INT0 ab bei steigender 
Flanke.

MCUCR |= 1<<ISC00 | 1<<ISC01;
EIMSK=(1<<INT0);


SIGNAL(INT0_vect)
{
freq++;
}


esüsten laut Oszi 12Impulse in 10ms sein und 120 in 100ms bei mir sind 
es zwischen 98 und 101.

Ich vermute mein Timer arbeite nicht genau.

Vielen Dank

Gruß

Andi

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:

> Ich vermute mein Timer arbeite nicht genau.

Der Timer schon.
Aber hast du die 16Mhz kontrolliert?
Stimmen deine Fuse Einstellungen, so dass der Quarz auch wirklich 
benutzt wird?
Hast du das kontrolliert?

von Andi (Gast)


Lesenswert?

Hallo

Ja ich habe dei Fuse im AVR Studio auf extern 8-...Mhz angepasst.

Werde nochmals mit Bascom Kontroliieren muß aber meinen alten PC mit LPT 
auskramen.

Ich nutzte ja nur noch den MKI Clone mit AVR Studi.

Danke

von Karl H. (kbuchegg)


Lesenswert?

Wenn du irgendwo eine LED drann hast oder sonst irgendeinen Ausgang, an 
dem du die Spannung leicht sichtbar machen kannst
1
#define F_CPU 16000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
#define LED_PORT  PORTB
7
#define LED_PIN   PB1
8
9
int main()
10
{
11
  while( 1 ) {
12
    LED_PORT |= ( 1 << LED_PIN );
13
    _delay_ms( 1000 );
14
    LED_PORT &= ~( 1 << LED_PIN );
15
    _delay_ms( 1000 );
16
  }
17
}

mit -Os compilieren.

Läuft dein µC mit 16Mhz, dann ist die LED 1 Sekunde an, 1 Sekunde aus. 
Läuft dein µC nur mit 1Mhz dann sind es 16 Sekunden an, 16 Sekunden aus.

Bei Taktfrequenzen dazwischen, bewegt sich auch die Leuchtdauer zwischen 
diesen beiden Extremen.

von Andi (Gast)


Lesenswert?

Hallo

Das habe ich alles schon probiert

Ich habe meine Sieben Segment anzeige dazu benutzt einen Zähler von 0-60 
zu zählen.

bei 25000 ( genau 24999) zählt die Siebensegment alle 1sec. sollten ja 
schon die 100ms sein.

bei 2500 (2499) sind es dann die 100sec. Zahlen rasen durch die letzten 
stellen. Die erste stelle in sekunden haut ja soweit hin.

aber warum ist es das 10fache an unterschied zwischen den OCR1A???

Gruß

Andi

von Stefan E. (sternst)


Lesenswert?

CKDIV8 Fuse?

von Karl H. (kbuchegg)


Lesenswert?

Zeig mal das Programm. Aber bitte vollständig!

Konzentrieren wir uns für erste auf einen Zähler, der am 7_seg einfach 
nur hochzählt. Also ohne das ganze Signal-Einlesen Gedöns und 
Frequenzauswertung.

Einfach nur eine Timer-ISR die bei jedem Aufruf einen Zähler um 1 
hochzählt. In der Hauptschleife wird der Zähler auf die 7-Seg 
ausgegeben.

(BTW: wie wird die 7_seg angesteuert?)

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:
> Hallo
>
> Das habe ich alles schon probiert

Auch den LED Test?
Das ist der ultimative Test. Nur wenn der stimmt, hast du nichts 
übersehen und der µC arbeitet wirklich mit 16Mhz.

(Ich denke nämlich auch, dass du irgendeine Fuse übersehen hast und der 
µC eben nicht mit 16Mhz sondern mit weniger arbeitet. Ein Faktor 8 ist 
von einem Faktor 10 mit freiem Auge schon nicht mehr so leicht 
auseinanderzuhalten)

von Andi (Gast)


Lesenswert?

Hallo

Ich habe die Fuse wie schon gesagt im AVR Studio unter AVRIPS MKIIClone 
für Atmel48 nur folgenden Eintrag geändert.

von inetrn (Mhz auf

SUT_CKSEL Ext. Crystal Osc. 8.0-    MHz; Start-up time PWRDWN/RESET: 16K 
CK/14 CK + 65 ms.

sonst keine weitere fuse gesetzt.

Die 7Segment ist ein viereblock mit ansteuerung eines MAX7219 über spi.


#include <avr/io.h>
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "main.h"


#define F_CPU 16000000





volatile uint32_t freq=0;
volatile uint8_t timer1=0;
volatile uint32_t res = 0;
volatile uint8_t tt=0;

SIGNAL(TIMER1_COMPA_vect)
{
if(timer1==0)timer1=1;

}
SIGNAL(INT0_vect)
{

freq++;

}




void set_ports(void)
{
port_spi_7SEG_cs(); //CS 7SEG

port_spi_sck(); //SCK
port_spi_mosi();//MOSI
port_spi_miso();//MISO
SEG_cs_high();

}






void main(void)
{

set_ports();

init_7seg1();
test_7seg_on(0);
_delay_ms(1000);
test_7seg_off(0);

set_brightness(0x02,0);

cli();
TCCR1A=0x00;
TCCR1B=(1<<WGM12) | (1<<CS11) | (1<<CS10);
OCR1A=2499;
TIMSK1=(1<<OCIE1A);

EICRA=(1<<ISC00) | (1<<ISC01);
MCUCR |= 1<<ISC00 | 1<<ISC01;
EIMSK=(1<<INT0);


sei();




while(1)
{


if(timer1==1)
   {

/*
if(tt<3)res+=freq;
 tt++;
 if(tt==3)
 {
 res/=3;
 res=(res*600)/(6);//alle 6 Impulse von der Lima (6 Spulen)
 set_7seg(res,1,0,0);
 tt=0;
 }
 res=0;
 freq=0;
 timer1=0;
*/
if(tt<60)set_7seg(tt++,1,0,0);
if(tt>60)tt=0;

 }



  }
}


Hier mal der code für das Hochzählen ohne den Eingang für die 
Frequenzmessung.


Danke

Andi

von Andi (Gast)


Lesenswert?

Hallo

Achso die den Vorteiler CKDIV8 ist kein hacken drin ist ja gut so wäre 
natürlich ein Fehler.

Gruß
Andi

von Andi (Gast)


Lesenswert?

Hallo

Habe das ganze mal ohne 7 segment im AVR Studio Simulator laufen mit 
Simulator Frequenz 16MHZ.

Da bekomme ich bei 2499 alle 1 sek ein tick.

Jetzt blicke ich überhaupt nicht mehr durch.

Dort sollte auch in etwa alle 100ms ein tick kommen.

Wenn ich OCR1A auf 24999 stelle bekommeich alle 10sek. ein tick im 
simulator.

Was ist da Falsch ist die Timer init falsch???

Danke Gruß
Andi

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:
> Ich habe die Fuse wie schon gesagt im AVR Studio unter AVRIPS MKIIClone
> für Atmel48 nur folgenden Eintrag geändert.
>
> von inetrn (Mhz auf
>
> SUT_CKSEL Ext. Crystal Osc. 8.0-    MHz; Start-up time PWRDWN/RESET: 16K
> CK/14 CK + 65 ms.
>
> sonst keine weitere fuse gesetzt.


> Achso die den Vorteiler CKDIV8 ist kein hacken drin
(Bei welchem Brennprogram)

Hast du oder hast du nun die CKDIV8 Fuse angerührt oder nicht?
Per Default, also wenn du sie nicht verändert hast, ist der zusätzliche 
Teiler durch 8 aktiviert. Wenn du die Fuse nicht angerührt hast, läuft 
dein µC mit 2 Mhz und nicht mit 16Mhz

Was ist so schwer drann, den Blinktest den ich schon seit Stunden 
vorschlage endlich einmal zu machen. Dann wüsstest du es ganz genau!

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:
> Hallo
>
> Habe das ganze mal ohne 7 segment im AVR Studio Simulator laufen mit
> Simulator Frequenz 16MHZ.
>
> Da bekomme ich bei 2499 alle 1 sek ein tick.

Keine Ahnung was du eingestellt hast.
Wenn ich das bei mir durch den Simulator jage, kriege ich
bei OCR1A = 2499  alle 10ms
bei OCR1A = 24990 alle 100ms einen Tick

von Andi (Gast)


Lesenswert?

Hallo,

Di Fuse habe ich nicht angerührt ist auch im AVR Tutorial hier 
beschrieben das sie default auf 0 ist also im AVR Studio kein haken so 
ist es auch bei mir.

Den Blicktest habe ich in form eines zähler der mir auf der 7 seg eine 1 
2 3 4 5 6 7 8 9 0 anzeigt mit der einstellung 24999 macht er 1 (ca 1sek) 
2 (ca 1sek) 3 usw.
Ob nun eine led aus oder an geht ist doch denk ich das gleiche.

Nur mir macht das Problem im Simulator kopf zerbrechen.
dort ist bei OCR1A=24999 = 10 sek statt in der realen umgebung = 1 sek.
Wieso das.???

Danke

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:
> Hallo,
>
> Di Fuse habe ich nicht angerührt ist auch im AVR Tutorial hier
> beschrieben das sie default auf 0 ist also im AVR Studio kein haken so
> ist es auch bei mir.

Dann gratuliere ich:
Dein µC läuft mit 2Mhz

> Ob nun eine led aus oder an geht ist doch denk ich das gleiche.
Nein
Ist er nicht.
Das Programm das ich dir geschrieben habe, hängt einzig und alleine von 
der Taktfrequenz ab und von sonst gar nichts. Von keinen 
Timereinstellungen, von keinem Vorteiler, von gar nichts.
Einzig und alleine die Taktfrequenz ist entscheidend. Und zwar 
diejenige, mit der der µC tatsächlich läuft. Der Test ist so angelegt, 
dass er nur davon und von nichts anderem abhängt. Und der Test ist so 
gemacht, dass man mit freiem Auge 16Mhz, 8Mhz oder eben 2Mhz 
unterscheiden kann. Mach den Test und du wirst sehen, dass das erwartete 
Verhalten, 1 Sekunde ein; 1 Sekunde aus, nicht vorhanden ist. Statt 
dessen sind die ein/aus Zeiten 8 Sekunden. Wenn du heute um 1/2 6 diesen 
Test gemacht hättest, hättest du dir viel Zeit sparen können.

von Andi (Gast)


Lesenswert?

Hallo


Im Simulator mache ich bei if(timer1==1) in der While einen Breakpoint 
und der kommt nach 10sek bei OCR1A=24999.

Was ich jetzt noch bemerkte ist die der Wert Stop Watch in µs nehme ich 
an dort steht ein us.

Dort steht beim eintreffen des breakpoints bei OCR1A=24999; 100000µs das 
entspricht 1ms=1000µ meiner 100ms.

Aber warum kommt der Breakpoint gefühlt nur alle 1sec.

Das begreife ich nicht.

Gruß

ANdi

von Andi (Gast)


Lesenswert?

Hallo

Nochmal ne Frage zu dieser Fuse CKDIV8

muß da ein Hacken rein oder nicht???
Bei mir ist keiner drin im Fuse einstellungen AVR Studio.

Danke

Gruß

Andi

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:

> Aber warum kommt der Breakpoint gefühlt nur alle 1sec.

gefühlt?

Das ist eine Simulation!
Der SImulator benötigt auch seine Zeit um ein simuliertes Programm auf 
einer simulierten Hardware zu simulieren. Darum nennt man das 
Simulation. Entscheidend ist das was bei der Anzeige Stop-Watch steht 
und nicht welches Gefühl du bei der Programmausführung hast.

von Andi (Gast)


Lesenswert?

Hallo

Habe gerade das Manual vom 48iger nach der Fuse durchsucht und da steht 
default 0 programmed.
also heist es tatsächlich 2Mhz.
Kann es sein das es nur bei den 48iger so ist???

Bei meinen Mega 8 und 128iger mit denen ich sonst hantiere habe ich nie 
Probleme mit den Timern gehabt.

So ein mißt auch.

Werde morgen mal den Fuse setzten auf 1 stellen.

Danke
Danke

Gruß

Andi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.