Interrupt&Timer :rechtekförmiges Signal

vianney

Neues Mitglied
11. Nov. 2009
7
0
0
Sprachen
Hallo, an alle die sich gut auskennen
ich bin student und mache derzeit mein Praxissemester bei Valeo, und ich hatte als Projekt die Erzeugung von einem rechteckformiges Signal mit einer Frequenz von 51KHz mit Hilfe der Minimexle (Atmega88) durchzuführen.

Meine Probleme sehen folgendes aus:
1-Timer: was für eins sollte ich benutzen und wie soll er programmiert wird
2-Brauche ich und wenn überhaupt welches, ein Outpout Compare Register, um mir die Werte vergleichen lassen zu können.
3-Interrupt: wie soll er aufgerufen wird
4-Erzeugung von Sekundentakt: Ich weisse, dass ich mir zu erst den richtigen Prescaler-faktor aussuchen muss, um die Periode mit der der Interrupt immer aufgerufen wird, aber wass ich nicht verstehe, ist ob ich überhaupt auch darf mir einen Millisekundentakt, bzw. einen mucrosekundentakt auch erzeugen kann, der mir die Takte die ich brauche zählen kann um den Interrupt abzurufen. Da ich ein Signal mit 51KHz brauche, hab ich dann eine Periode von 20mucrosec. es wäre güngstig wenn ich mir einen mucrosekundentakt erzeugen könnte (da ich übrelegt habe einen Prescaler-faktor von 8 zu benutzen).

Ich bedanke mich und freue mich schon auf ihre baldige Antworten.
Mit freundlichen Gruessen
 
Hi vianney,

verrate uns doch zuerst einmal, in welcher Programmiersprache Du programmieren möchtest und wie Deine HW aussieht! Hast Du schon zusätzliche Peripherie und wenn ja was?

Grüße,
Markus
 
Hallo markus,
Erstmal danke für die Antwort, ich habe vor mit Assembler (avr studio c) zu programmieren, und ich habe ein gnaze normal minimexle (ATMega 88). Ich werde nur danach mit einem Oszilloscope (zusammen verbinden), die Frequenz mienes erzeugten Signals auswerten, bzw. messen.
ich hoff ich habe versucht dir eine gute Antwort zu geben.
Grüß
 
Hallo Vianney,

das Rechecksignal 51kHz würde ich mit der Compare-Funktion eines Timers erzeugen, du kannst hierfür sicherlich den Timer0 verwenden. Am besten stellst du die OC-Pin Funktion auf "Toggle on Compare Match" ein. Der Compare-Event müsste dann etwa alle 10us auftreten.

Wir haben im Forum ein kleines Tool, welches den Prescaler bei vorgegebener fosc und Event-Time berechnet:

AVR-Timer-Calculator

In dem Thread sind auch noch einige Erklärungen zu Timerberechnungen, vielleicht hilft dir das ja weiter.

Du benötigst noch ein Signal für ein Sekundentakt, dieses würde ich wenn möglich von einem zweiten Timer (Timerinterrupt: overflow oder compare) ableiten, der langsamer läuft, als der Timer für die 51kHz-Erzeugung.

Schöne Grüße,
Dirk
 
Hi
Zuerst würd ich mal aus 51 KHz 102 KHz machen, und damit einen Interrrupt generieren. In der ISR programmierst du einen Signalwechsel, das geht locker mit XOR. Um auf 102 KHz zu kommen, brauchst du einen speziellen Quarz, denn ich glaube nicht, das du einfach auf einen vernünftigen und genauen Teiler bei 1/102000 kommst. das Ergebnis ist9,8039215686274509803921568627451 µs. Du müßtest einen Prescaler finden, der dir einigermaßen genau einen µs - Takt bildet. Nimmst du 10µs, dann kommst du "nur" auf 50KHz. ( was sind schon 2 %, so genau pfeift kein Schwein...:meeting: ) Außerdem hast du das Problem, aus der gleichen Quelle einen Sekundentakt abzugreifen. Da ich den Controller nicht kenne, weiß ich jetzt nicht, ob er 2 16 Bit-Zählregister hat. diese Info findest du aber im Datenblatt und auch die Prescaler-Einstellungen.
Gruß oldmax
 
Hallo, jungs
erstmal danke für ihre Meldungen, nd sry wenn ich später antwort, war krank (hat grippe nd hoff das hat nix mit schweinegrippe zutun hihi)
Zur Sache, ich habe schon mein Programm geschreiben, einfach mit dem Phase und frequnecy correct PWM, ich hab dafür oldmax kein interrup geschreiben, hab nur timer1 benutzt (TCCR), und mit dem Quarz, der auf der minimexle gebaut ist, hatte eine Frequenz von 18,432Mhz, damit könnte ich eine Frequenz von 51,2khz erzeugen, wobei ich mein TOP-Zahl für OCR bei 180 gemacht hab.
Aber ich treffe das Probelm dass das Oscilloscope mir eine Frequenz von 36,01khz guíbt, und verstehe net warum.
ich schicke euch anbei das Programm, damit ihr auch euch es anguckt und mir sagt ob ich einen fehler gemacht hab, und wenn überhaupt wo.
dank




CodeBox C

#include <avr/io.h>

void Init_Ports(void);
void Init_Timer(void);

int main (void)

#include <avr\io.h>
#include<avr\interrupt.h>

void Init_Ports(void);
void Init_Timer(void);

int main (void)
//Hauptschleife

{
DDRB |= (1 << PB1);

while(1)
{


PORTB |= (1 << PB1); //Signal nach obern bezeichnet
Init_Timer_1(180);


PORTB &= ~(1 << PB1); // Signal nach unten bezeichnet
Init_Timer_1(180);


}
}
void Init_Timer_1(void)
{




TCCR1A |= ((1<<WGM10) |(1<<WGM13) | (1<<COM1A0) |(1<<COM1A1));

TCCR1B |= (1<<CS10);

OCR1A = 180;

}
 
Hallo,

Aber ich treffe das Probelm dass das Oscilloscope mir eine Frequenz von 36,01khz guíbt, und verstehe net warum.
Digitales Speicherscope mit eigenem Frequenzzähler oder hast du mit Cursorpaaren die Zeit gemessen und in Frequenz umgewandelt ?

Bedenke : Oszilloskope sind nicht für Spannungs- und Frequenzmessung gebaut sondern zum Kurven darstellen. Also immer einen Meßfehler von ein paar Prozent mit einkalkulieren.

Gruß
Dino
 
Hi
Du hast da ein paar interesante Informationen geliefert... Quarz 18,432 MHz, gesuchte Frequenz 51,2 khz. Also, 18432000 / 51200 = 36000.
Klingelt's ? Ist das nicht die Zahl, die du mit dem Oszi gemessen haben willst? Ich denke mal, da wirst du dein Programm ein klein wenig ändern müssen.
Gruß oldmax
 
hi odlmax
das ist genau die frequenz die ich haben will, die wird beim Rechtecksignal gemessen, aber wo der fehler liegt, hab ich keine ahnung, vlt hab ich etwas falsch gerechnet.
ich bin davon ausgegangen, dass beim pahse und frequency correct PWM, die formul so lautet f_pwm=(f_I/O):2*N*TOP
wobei N:prescaler-faktor, TOP: Anzahl der OCR
Aber wenn ich es benutze, bzw. die richtige N und TOP auswähle, komme ich auf eine gemessene Frequenz von 36khz.
verstehe ich net
dank
 
Hallo Vianney,

kontrolliere mal die Einstellung der Bits. Das Bit WGM13 befindet sich nicht im Register TCCR1A sondern im Register TCCR1B.

Was ich auch nicht verstehe, in der Endlosschleife in main() initialisierst du ständig den Timer1, das macht man zu Begin von main eigentlich nur einmal, es sei denn man möchte den Timer anhalten oder den PWM Mode ändern.
Du übergibst auch der Routine Init_Timer_1 einen Wert, diese erwartet jedch keinen, normalerweise müsste der Compiler hier warnen. Dann änderst du in der Endlosschleife das PortB Register (PB1). Ich vermute mal, du möchtest an PB1 die PWM haben, die Portfunktion wird vom Timer1 "überschrieben", wenn du COM1A1 und COM1A0 entsprechend einstellst.

Gruß,
Dirk
 
hallo dirk,
du hattes recht das WGM13 befindet sich im TCCRB, das hab ich geändert, mit der Geschichte mit dem Timer, dem ich immer einen Wert übergegeben hab hat sich auch geklärt.
Trotzdem kreige ich es nicht in der Reihe, und abgesehen von der Einstllungen, die über die COM1A1 und COM0A1 machen werden sollen, sind auch aber der geht immer noch net.
Außerdem hab ich ein anderes Programm mit dem Timer0 geschrieben, hat geklappt das war sogar voll einfacher, aber ich will eigentlich für meine Kenntnisse wiessen was das Probelm mit dem Timer1 war.
Hier schicke ich noch anbei der aktuelle Zustand meines Programms, damit du siehst was ich schon geändert hab.

#include <avr\io.h>
#include<avr\interrupt.h>


void Init_Ports(void);
void Init_Timer_1(void);
int i;
int main (void)


//Hauptschleife

{
DDRB |= (1 << PB1); //PortB1 als Ausgang




while(1)
{


PORTB |= (1 << PB1); //Signal nach obern bezeichnet
Init_Timer_1();


PORTB &= ~(1 << PB1); // Signal nach unten bezeichnet
Init_Timer_1();


}
}
void Init_Timer_1(void)
{



//Initialisierung Timer 0
// Clear Timer on Compare (CTC)
TCCR1A |= (1<<WGM10)|(1<<COM1A0)|(1<<COM1A1) ; // WGM13, WGM10=1, Phase correct PWM_Mode
//COM1A0,COM1A1=1 Ausgang(PortB) wird bei 0 zurückgesetz wenn Zähler(TOP)
// =OCR1A(=180)
// Prescaler
TCCR1B |= (1<<CS10)|(1<<WGM13); //Systemtakt ohne Prescaler
//Outpout compare Register A belegen
OCR1A = 180; //Belegen der Outpout Compare Register von 0-179


dank
 

Ü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)