Hallo Zusammen, ich möchte über einen Timerinterrupt alle 100ms drei 74HC595 Schieberegister mit Daten befüllen. Wie könnte ich das mit einem der beiden 8 Bit Timer lösen? Alles was ich bisher dazu gefunden habe, benutzt dafür den 16 Bit Timer. Den kann ich aber nicht nutzen, weil ich per SoftwareSerial ein Modul steuern muss. Oder kann trotzdem der Timer 2 dafür verwendet werden? Der Arduino läuft mit 16Mhz. Das Problem ist also, einen Timerinterrupt zu erstellen der alle 100ms eine Aktion auslöst und nur einen 8 Bit Timer dafür zu verwenden. Liebe Grüße aus Hessen, Sebastian
Gast
#5225149
Guck mal, der hat das schon fertig. http://forum.arduino.cc/index.php?topic=488430.0
Wenn der Timer mit größtmöglichem Vorteiler nicht auf 100ms kommt, wirst du halt in der ISR noch einen Softwarezähler einbauen müssen. Oliver
Gast
#5225165
Arduino hat doch millis()
Danke für die schnellen Antworten. :D @Oliver Das mit dem Softwarezähler hatte ich mir auch schon überlegt. Mir fehlt ein bisschen der Ansatz, wie ich den Timer passend initalisiere und dann nochmal einen Softwarezähler einbaue. Etwa so? (ist etwas zusammengeklaut...)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
@Tommy An millis() hatte ich noch gar nicht gedacht. Das könnte auch eine Option sein. Da müsste man nur im loop() schauen, ob 100 oder mehr Ticks durch sind... Danke nochmals und schönen Abend noch. Sebastian
@Sebastian V. (n8falter74) >ich möchte über einen Timerinterrupt alle 100ms drei 74HC595 >Schieberegister mit Daten befüllen. Kann man machen. > Wie könnte ich das mit einem der >beiden 8 Bit Timer lösen? Kann man. >Das Problem ist also, einen Timerinterrupt zu erstellen der alle 100ms >eine Aktion auslöst und nur einen 8 Bit Timer dafür zu verwenden. Un das ist jetzt sooo schwer? Hast du dich schon mal ANSATZWEISE mit einem Timer beschäftigt? Wieviele CPU-Takte vergehen in 100ms bei 16 MHz? Wie oft läuft in der Zeit ein 8 Bit Zähler über? Welche Rolle spielt der Hardware-Vorteiler? Denk mal drüber nach . . .
Gast
#5225313
Vorteiler: 256. F_CPU : 256 : 10 = Zählwert für deinen Timer, damit dieser alle 100ms Interrupt generiert. Bei 16MHz wäre das ein Wert von 6250.
> Un das ist jetzt sooo schwer? Hast du dich schon mal ANSATZWEISE mit > einem Timer beschäftigt? > > Wieviele CPU-Takte vergehen in 100ms bei 16 MHz? > > Wie oft läuft in der Zeit ein 8 Bit Zähler über? > > Welche Rolle spielt der Hardware-Vorteiler? > > Denk mal drüber nach . . . Hallo Falk, etwas habe ich mich schon mit Timern beschäftigt. Nachdem ich nicht weitergekommen bin, habe ich hier freundlich um Hilfe gebeten. Bei 16 Mhz würde ich von 1,6 Mio CPU Takten in 100ms ausgehen. Ein 8 Bit Zähler läuft dabei 6250 mal über. Mit den Prescalern 64 256 1024 komme ich nur auf krumme Werte. Wenn das Problem für Dich so einfach ist, kannst Du mir sicher auch mit einem vernünftigen Tipp helfen. :) Lieben Gruß aus Hessen Sebastian
Gast
#5225334
Leg doch deine software uart auf nen 8bit timer. Soo niedrige baudraten das der dafür nicht reicht, wirst du wohl kaum haben. Alternativ, bau dir ne clock mit clockticks, und zähl die.
Moin,
16MHz sind 0,0625µs pro Takt.
Vorteiler 1024 macht 64µs pro Überlauf bei 8 Bit.
64us_counter definiert als 16bit unsigned
Timer0_isr:
Inrc 64us_counter
If 64us_counter = 1562 then
...mach alle 100ms was
64us_counter = 0
End if
Return
Fertig.
Das geht 32µs falsch, was 0,032% entspricht.
Da das genau einen halben Zähler falsch ist, könnte man das auf Null
bekommen (mit dem Fehler als Jitter), wenn man bei jedem Treffer der
If-Abfrage zwischen 1562 und 1563 wechselt.
Gruß,
Norbert
@ Sebastian V. (n8falter74) >etwas habe ich mich schon mit Timern beschäftigt. Das hat man in deinem ersten Beitrag aber nicht gesehen. Da will der geneigte Leser/Helfende schon mal sehen, was der Fragende gedacht und ggf. gerechnet hat. >Bei 16 Mhz würde ich von 1,6 Mio CPU Takten in 100ms ausgehen. >Ein 8 Bit Zähler läuft dabei 6250 mal über. >Mit den Prescalern 64 256 1024 komme ich nur auf krumme Werte. Welche denn?? N = F_CPU Vorteiler ISR-Frequenz = 16 MHz 1024 10 Hz = 1562,5 Ein 8 Bit Zähler ist bei 10 Hz halt trotz Vorteiler zu klein. 10 Hz sind für einen uC auch eher langsam. 100-1000 Hz sind da eher üblich, kleinere Frequenzen macht man wie bereits gesagt über einen weiteren Softwareteiler. Bei 100 Hz wäre eine Zählerperiode von 156,25 korrekt. Das passt zwar in 8 Bit, aber nicht die Nachkommastellen. Also eher was pragmatisches. Nutzte den CTC Modus des Timer 2 mit 156 als Periode. Das ist nur einen Tick schneller als 100 Hz, hier ist das unkritisch, du baust ja keine Uhr. Wenn doch, dann so. AVR - Die genaue Sekunde / RTC
@falk @norberts Danke für Eure Antworten. Im Post Beitrag "Re: Arduino 8Bit Timer für 100ms Intervall verwenden" habe ich eine Timer0 Initalisierung, die ich im Internet gefunden habe, von 2 kHz auf 1 kHz abgeändert. In der ISR zähle ich dann eine Variable bis auf 100 hoch und führe dann jeweils den Code aus, der alle 100ms laufen soll. Ich habe das noch nicht testen können. Aber das entspricht ja eigentlich dem, was ihr beide mir vorgeschlagen habt. Allerdings habe ich irgendwo gelesen, dass das Verändern von globalen Variablen in einer ISR problematisch ist. Habt ihr das schon so in einem Projekt umgesetzt? Grüße aus Hessen Sebastian
@Sebastian V. (n8falter74) >eine Timer0 Initalisierung, die ich im Internet gefunden habe, von 2 kHz >auf 1 kHz abgeändert. In der ISR zähle ich dann eine Variable bis auf >100 hoch und führe dann jeweils den Code aus, der alle 100ms laufen >soll. Ist OK. >Allerdings habe ich irgendwo gelesen, dass das Verändern von globalen >Variablen in einer ISR problematisch ist. Nur wenn man es falsch macht. Außerdem muss die Variable teiler nicht global sein, sie kann auch statisch lokal sein. Dann gibt es erst recht keine komischen Nebeneffekte.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
https://www.mikrocontroller.net/articles/Interrupt#Interruptfeste_Programmierung > Habt ihr das schon so in einem Projekt umgesetzt? Unzählige Mal. ;-)
Gast
#5225771
Sebastian V. schrieb: > Allerdings habe ich irgendwo gelesen, dass das Verändern von globalen > Variablen in einer ISR problematisch ist. Wieso? Jede Information zwischen ISR und anderen Programmteilen wird über globale Variablen ausgetauscht. Sie muss nur als 'volatile' gekennzeichnet werden und wenn sie länger ist als der Prozessor in einem Schritt verarbeiten kann, dann müssen für die Operationen außerhalb der ISR die Interrupts gesperrt werden (Stichwort atomic).
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.