Forum: Mikrocontroller und Digitale Elektronik LED Blinker Multitasking Attiny 85


von Holger W. (mb_holger)


Lesenswert?

Hallo,

Ich bin neu hier und Anfänger.
Ich habe zwei LED wechselnd zum Blinken gebracht mit dem Attiny 85,
mit folgendem Code in C
1
 /*
2
 * GccApplication25.c
3
 *
4
 * Created: 14.01.2015 22:24:28
5
 *  Author: mb_win 7
6
 */ 
7
8
9
#include <avr/io.h>
10
11
#define F_CPU 8000000UL       //Taktfrequenz 8MHz
12
13
#include <avr/io.h>
14
#include <util/delay.h>
15
16
int main(void){
17
  DDRB |= (1 << PB0);       // damit ist dann PB0 ein Ausgang
18
  DDRB |= (1 << PB1);       // damit ist dann PB1 ein Ausgang
19
  
20
  while(1){
21
    PORTB |= (1 << PB0);  //PB0 im PORTB setzen
22
    _delay_ms(250);       //250ms warten
23
    
24
    PORTB &= ~(1 << PB0); //PB0 im PORTB löschen
25
    _delay_ms(250);       //250ms warten
26
    
27
    PORTB |= (1 << PB1);  //PB0 im PORTB setzen
28
    _delay_ms(500);       //500ms warten
29
    
30
    PORTB &= ~(1 << PB1); //PB0 im PORTB löschen
31
    _delay_ms(500);       //500ms warten
32
      }
33
  return 0;
34
}
funktioniert wunderbar die zwei LED blinken abwechselnd.

Jetzt mein Problem.  Ich habe keine Lösung wie ich die zwei LED 
unabhängig blinken lassen kann. Wie kann ich zB. zwei Schleifen parallel 
ablaufen lassen oder eine andere Lösung , mit unabhängigen,definierten 
und genauen Blinkzeiten. Ich habe keine Idee und brauche Hilfe für einen 
Lösungsansatz für den C-Code.

vielen Dank
Holger

: Bearbeitet durch User
von Rico W. (bitkipper)


Lesenswert?

Sieh dir mal die ziemlich gute Erklärung von einem Forumsmitglied zum 
Ansatz der Protothreads an:

http://stefanfrings.de/avr_io/protosockets.html

Der "Trick" dahinter sind state machines, die mittels switch/case gelöst 
werden. Je nach Anforderung und von dir investiertem Aufwand kannst du 
dabei den Controller auch zwischen seinen Tasks schlafen legen.

von LostInMusic (Gast)


Lesenswert?

1
int i = 0, k = 0;
2
3
while(1){
4
  i++; if (i==25) {i = 0; PB0_toggle;}
5
  k++; if (k==53) {k = 0; PB1_toggle;}
6
7
  _delay_ms(10);     // 10 ms warten
8
  }
9
10
return 0;

von npn (Gast)


Lesenswert?

Am besten wird es sein, wenn du möglichst vergißt, daß es eine Anweisung 
"delay" oder "delay_ms" gibt. Stattdessen lies dich mal in das Thema 
TIMER ein. Damit kannst du viele unabhängige Sachen gleichzeitig machen, 
die sich dann auch nicht in die Quere kommen.
Im Forum findest du unzählige Beiträge zum Thema Timer.

von Peter D. (peda)


Lesenswert?


von Holger W. (mb_holger)


Lesenswert?

Ich bitte um eine kurze Erklärung zu diesem Code von LostInMusic.
vielen Dank

von Holger W. (mb_holger)


Lesenswert?

und auch noch Danke für die anderen Hinweise.
Holger

von LostInMusic (Gast)


Lesenswert?

Gerne. Beschreibe bitte, was Dir daran alles unverständlich ist.

von Karl H. (kbuchegg)


Lesenswert?

Was brauchst du da für Erklärungen?

Du stehst da und beobachtest eine Uhr. Jedesmal wenn du den 
Sekundenzeiger ticken hörst, streckst du sowohl in der linken als auch 
in der rechten Hand einen Finger aus. Wenn du danach

* an der rechten Hand 3 ausgestreckte Finger siehst, schaltest du Lampe 
1 um und ziehst die Finger der rechten Hand wieder ein

* an der linken Hand 4 ausgestreckte Finger siehst, schaltest du Lampe 2 
um und ziehst die Finger der linken Hand wieder ein

Fazit: Lampe 1 wird alle 3 Sekunden umgeschaltet, Lampe 2 wird alle 4 
Sekunden umgeschaltet.

Der Trick besteht darin, die 'Wartzeit' für das Umschalten von Lampe 1 
bzw. Lampe 2 nicht als unteilbare Zeit zu sehen, sondern auf einen 
gemeinsame kleinste Einheit runterzubrechen (hier: 1 Sekunde) und dann 
einfach entsprechende Vielfache dieses gemeinsamen kleinsten Einheit 
abzuzählen, wann die nächste Umschaltung fällig ist. Dieses Abzählen 
kann aber für alle Lampen reihum nacheinander erfolgen. Bei jedem Tick 
werden die Zähler aller Lampen um  1 erhöht.

Klar soweit?
Und jetzt studierst du den Code um die besprochenen Einzelteile im 
Programm wieder zu finden.

: Bearbeitet durch User
von npn (Gast)


Lesenswert?

LostInMusic schrieb:
> int i = 0, k = 0;
>
> while(1){
>   i++; if (i==25) {i = 0; PB0_toggle;}
>   k++; if (k==53) {k = 0; PB1_toggle;}
>
>   _delay_ms(10);     // 10 ms warten
>   }
>
> return 0;

Holger Weiß schrieb:
> Ich bitte um eine kurze Erklärung zu diesem Code von LostInMusic.
> vielen Dank

- i und k starten mit 0
- eine While-Schleife (Endlos)
- i wird erhöht, dann wird geprüft, ob i=25 ist
- wenn ja, wird i wieder auf 0 gesetzt und der Ausgangspin (PB0) 
getoggelt
- das gleiche mit k
- anschließend wird 10ms gewartet
- dann wird ein neuer Schleifendurchlauf begonnen.

Hier auch wieder das delay. Wenn du den gleichen Code statt in eine 
while-Schleife in eine Timer-ISR steckst, die aller 10ms aufgerufen 
wird, hast du das gleiche Ergebnis, ohne daß sich der µC die ganze Zeit 
mit Warten und Nichtstun beschäftigt. So wie hier kannst du nebenher 
keine anderen Sachen machen (Tasten abfragen, Display ansteuern usw.) 
Mit der Timer-Version kannst du es.

von LostInMusic (Gast)


Lesenswert?

>So wie hier kannst du nebenher keine anderen Sachen machen

Und warum soll das nicht gehen? Hier wird doch auch schon das Blinken 
der LED 2 nebenher zum Blinken der LED 1 gemacht (oder je nach 
Betrachtungsweise andersrum)? Nach demselben Schema kannst Du zusätzlich 
auch noch eine Taste parallel abfragen oder sonstwas veranstalten. Die 
Regeln für jede "Veranstaltung" lauten halt, dass sie im 10 
ms-Zeitraster stattfindet und selbst immer schnellstmöglich die 
Kontrolle wieder an die main-Schleife zurückzugeben hat. Außer dem 
delay_ms(10) darf es also nirgendwo sonst irgendwelche Delays geben.

Kooperatives Multitasking nennt sich der Spaß.

>Mit der Timer-Version kannst du es.

Mit einem Timer kann man das auch realisieren, und der Vorteil dieser 
Variante ist der genaue Zeittakt. Ansonsten gibt es keinen 
prinzipiellen Unterschied.

von Karl H. (kbuchegg)


Lesenswert?

LostInMusic schrieb:

>>Mit der Timer-Version kannst du es.
>
> Mit einem Timer kann man das auch realisieren, und der Vorteil dieser
> Variante ist der genaue Zeittakt. Ansonsten gibt es keinen
> prinzipiellen Unterschied.

Ich weiss, du hast das nicht so gemeint.
Aber einen prinzipiellen Unterschied gibt es: Mit einem Timer umzugehen 
muss man erst mal lernen. Und genau da liegt das Problem: man kann nicht 
alles auf einmal lernen.
Von daher würde ich es so bewerten: zur Zeit ist für den TO die delay 
Lösung durchaus in Ordnung. Aber im Hinterkopf behalten, dass es 
andere/bessere Lösungsansätze gibt, die dann interessant werden, wenn er 
über mehr Wissen verfügt.

von npn (Gast)


Lesenswert?

LostInMusic schrieb:
> Und warum soll das nicht gehen?

So lange wie du das gesamte Programm, also alles was der µC machen 
soll, in dieser einen Schleife machst, geht das. Aber was ist 
beispielsweise mit Displayansteuerung, der Bedienung einer oder mehrerer 
Schnittstellen (UART, CAN, Ethernet) oder Berechnungen, also alles was 
Zeit braucht, geht das in die Hose. Denn alle Zeit, die nicht zum 
Toggeln der beiden LEDs benötigt wird, frißt der µC mit dem delay 
komplett auf.

Wenn du allerdings wirklich nur paar LEDs toggeln willst, kannst du das 
gerne mit dem delay machen. Dann darfst du aber für später keine 
Erweiterungen des Programms vorhaben...

von LostInMusic (Gast)


Lesenswert?

Einverstanden. Kann man so stehenlassen :-)

von Holger W. (mb_holger)


Lesenswert?

So jetzt TO nochmal, den code von LostInMusic habe ich schon verstanden, 
habe ihn aber nicht zum laufen gebracht ( bin bald verzweifelt und 
wollte auch nicht dumm fragen). Ich habe herausgefunden das die Zeilen

 i++; if (i==25) {i = 0; PB0_toggle;}
 k++; if (k==53) {k = 0; PB1_toggle;}

mit den Attiny 85 nicht funktionieren, PB0_toggle geht so nicht. Ich 
habe folgende Zeilen dafür geschrieben

 i++; if (i==20) {i = 0; PORTB ^= (1<<PB0); } // zustandswechsel PB0
 k++; if (k==10) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1

und es funktioniert. Für den Anfang bin ich da schon ein bisschen Stolz 
auf mich. Aber genaue vorbestimmte definierte Zeiten bekomme ich damit 
nicht hin. Die dely Lösung, kooperatives Multitasking (war gut um etwas 
zulernen. Heute Abend werde ich  mit dem Timer weitermachen, ich verfüge 
ja jetzt schon über mehr Wissen :-). Wenn ich am verzweifeln bin melde 
ich mich wieder. Vielen Dank der Thread hat mich etwas weiter gebracht.

Für grundlegende praktische Tipps zum Timer für den Anfang wäre ich 
dankbar.

Grüße Holger

von Holger W. (mb_holger)


Lesenswert?

so ich bin abgestorben mit den Timer.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
ISR(TIM0_OVF_vect)
5
{
6
  PORTB ^= ( 1 << PB1 );
7
}  // Ende ISR
8
9
int main()
10
{
11
  TCCR0B |= (1<<CS00 | 1<<CS02);
12
  sei();       // enable timer interrupt
13
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
14
15
  while(1){  
16
  } // Ende while
17
  return 0;
18
} //Ende main

der attiny 85 nimmt den Code fehlerfrei an aber es blinkt wie erwartet 
nichts. Ich will hier niemanden zu sehr für mich beanspruchen. Für einen 
Tipp würde ich mich freuen.
Holger

: Bearbeitet durch User
von LostInMusic (Gast)


Lesenswert?

Fast. Du musst nur noch das Enable-Bit für Deinen Timer-Interrupt setzen 
(TOIE0 im Register TIMSK).

>sei();       // enable timer interrupt

"enable all interrupts" triffts eher. sei bewirkt die globale 
Interruptfreigabe, d. h. es lässt alle (aktivierten) Interrupts zu. Das 
Gegenstück ist cli() - dies verbietet dem µC die Ausführung von 
Interrupts (aber nicht das Vormerken etwaiger Interruptereignisse in den 
zugehörigen Flags, um die Interrupts später behandeln zu können). 
Manchmal ist es zum Schutz gewisser sensibler Codeteile nötig, alle 
Interruptaktivitäten kurzzeitig zu sperren. Das erreicht man mit dann 
mit "cli - [Code] - sei".

>PB0_toggle geht so nicht

Natürlich nicht, war doch nur ein Fantasiename zur Benennung der 
Funktionalität.

von Holger W. (mb_holger)


Lesenswert?

Frage an den  Moderator . Der c code wird von ihnen farbig 
umformatiert. Gibt es eine Funktion im Forum dafür?

von Karl H. (kbuchegg)


Lesenswert?

Antwort:

Ja klar.

Einfach mal ein bischen nach unten scrollen.
Nein, nicht bis zum Eingabefeld. Ein bischen weiter oben. Grosse 
Überschrift "Formatierungen"

von Holger W. (mb_holger)


Lesenswert?

Danke jezt geht es farbig
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
ISR(TIM0_OVF_vect)
5
{
6
  PORTB ^= ( 1 << PB1 );
7
}  // Ende ISR
8
9
int main()
10
{
11
  TCCR0B |= (1<<CS00 | 1<<CS02);
12
  sei();       // enable timer interrupt
13
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
14
15
  while(1){  
16
  } // Ende while
17
  return 0;
18
} //Ende main

von Holger W. (mb_holger)


Lesenswert?

Habe es jetzt  geschafft eine LED blinkt im Takt 8MHz /256 /1024 /30
also mit 1,01725260421 /s. Kann man einen genauen Sekundentakt 
programmieren und kann man mehrere Timer laufen lassen? Bitte einen 
Tipp.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
// TIMER 0 
5
int k = 0;
6
ISR(TIM0_OVF_vect)
7
{
8
  k++; if (k==30) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1
9
}  // Ende ISR
10
11
int main()
12
{
13
  sei();       // enable timer interrupt
14
  TCCR0B |= (1<<CS00 | 1<<CS02);
15
  TIMSK = (1 << TOIE0);
16
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
17
18
  while(1){  
19
  } // Ende while
20
  return 0;
21
  
22
} //Ende main
23
} //Ende main

von Holger W. (mb_holger)


Lesenswert?

Kann man beim Timer auch einen Interrupt bei einen bestimmten 
Zählerstand
zB. bei 200 auslösen oder geht der Interrupt nur beim Überlauf?
Fragen über Fragen.
Holger

von LostInMusic (Gast)


Lesenswert?

>...Interrupt bei einen bestimmten Zählerstand zB. bei 200 auslösen

Ja! Die schlauen Entwickler von Atmel haben Deinen Wunsch vorausgesehen 
;-) und dazu bestimmte Timer mit dem CTC Mode (Clear Timer on Compare 
Match) ausgestattet.

- CTC Mode aktivieren.
- OCR0A auf gewünschten Wert setzen.
- Interrupt "Timer/Counter0 Compare Match" aktivieren.
- ISR(TIM0_OVF_vect) durch ISR(TIM0_COMPA_vect) ersetzen.

Der Timer0-Overflow-Interrupt ist dann überflüssig.

Für Details wie immer Datenblatt konsultieren.

von Holger W. (mb_holger)


Lesenswert?

Noch eine spezielle Frage zum Timer mit dem CTC Mode. Kann man 
verschiedene
Interrupt Routinen über einen Timer ansprechen. zB bei Zählerstand 150 
die  Routine A und bei Zählerstand 230 die Routine B.

In einer Interrupt Routine des Timers die nächste ISR festzulegen also 
beim nächsten Interrupt  eine andere ISR auszuführen.

Kann man in der Hauptroutine auch Timer mit ISR festlegen die dann nur 
einmal ausgeführt werden oder auch verschachtelt sind oder gehen die 
Timer nit ISR nur global.


Meine Fragen deshalb weil die Anzahl der Timer je nach Chip begrenzt 
ist.
Für praktische Tipps bin sich dankbar.
Grüsse Holger

von Holger W. (mb_holger)


Lesenswert?

Hilfe ich bin am Verzweifeln. Habe einen CTC Timer im Attiny 13 
aktiviert.( Danke LostInMusic war sehr hilfreich für mich als Anfänger )
Mit der von mir berechneten Zeit funktioniert etwas nicht.
Nach meiner Berechnung sollte bei 9 MHz die ISR bei k=200 den Ausgang 
umschalten in Sekundentakt. Um einen genauen Sekundentakt an der LED 
einzustellen muss k=164 sein.(gemessen mit einen Zähler). Warum ist das 
so?
Habe ich mich verrechnet, arbeitet der Attiny nicht mit 9MHz ( nach 
meinen Berechnungen müsste er dann wesentlich unter 9Mhz arbeiten) , 
oder liegt es am  C Code ( wird hier etwas verzögert).

In den Fuses ist INTRCOSC_9MHZ6_14CK_64MS eingestellt.( arbeitet er bei 
9,6 MHz ? , ergibt aber bei meinen Berechnungen auch keinen Sinn)


Danke
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
// TIMER 0 
5
int k = 0;
6
ISR(TIM0_COMPA_vect)
7
{
8
  k++; if (k==164) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1
9
}  // Ende ISR
10
11
int main()
12
{
13
  // Timer 0 
14
  TCCR0A = (1<<WGM01); // CTC Modus
15
  TCCR0B |= (1<<CS02); // Prescaler 8
16
  // ((9000000/8)/5000) = 225 
17
  
18
  OCR0A = 224; // 9000000/8/225 entspricht 500 HZ   
19
  
20
  // Compare Interrupt 
21
  TIMSK0 |= (1<<OCIE0A);
22
  
23
  // Global Interrupts aktivieren
24
  sei();
25
  
26
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
27
28
  while(1){  
29
  } // Ende while
30
  return 0;
31
  
32
} //Ende main

von Stefan F. (Gast)


Lesenswert?

> Habe ich mich verrechnet?
Ja hast du. Der R/C Oszillator hat 9,6Mhz und standardmäßig wird das 
wegen der CLKDIV8 Fuse nochmal durch 8 geteilt, also 1,2Mhz.

Da du den Timer mit Prescaler 8 verwendest, ist die Taktfrequenz des 
Timers 150kHz. Wenn du ihn bis 224 zählen lässt, tritt bei jedem 224. 
Takt ein Interrupt auf. Also alle 2.493333 ms.

In der IRQ Routine teilst du die Frequenz nochmal durch 164, das ergibt 
dann eine Umschaltung der LED alle 0.2449 Sekunden. Also fast 2 Hz.

Dein Kommentar bezüglichb Division durch 225 ist falsch. Wenn der Zähler 
nur bis 224 zählt, dann musst du in der Berechnung auch durch 224 
teilen. Die 0 erfordert keinen Takt, denn auf null wird der Zähler ja 
bereits bei erreichen des Höchstwertes zurück gesetzt. Gleiches gilt 
auch für deine Software-Zählung bis 164.

Wo hast du die 5000 her?

von Holger W. (mb_holger)


Lesenswert?

Habe es jetzt am   Attiny 85 mit 8 MHz versucht:
- berechnet bei OCR0A = 199 : k = 200 und
- eingestellt bei OCR0A = 199 , k=148 um den Sekundentakt zu erhalten.
Was ist hier los ?????

von Stefan F. (Gast)


Lesenswert?

Sorry, ich habe mich mit den 224 / 225 vertan. Der Zähler springt doch 
erst einen Takt nach Erreichen des maximalen Wertes auf 0 um.

Aber damit ist dein Problem noch nicht geklärt.

> Was ist hier los ?????

> // 9000000/8/225 entspricht 500 HZ

Nein, das entspricht 5000 Hz. Bei Dir läuft er jedoch anscheinend weder 
mit 500 noch mit 5000 Hz.

Du solltest erstmal prüfen, ob der µC überhaupt mit der erwarteten 
Taktrat läuft:
1
main() {
2
  DDRB|=2;
3
  while (1) {
4
    PORTB^=2;
5
    _delay_ms(1000);
6
    PORTB^=2;
7
    _delay_ms(1000); 
8
  }
9
}

So müsste die LED im Sekundentak an und aus gehen, also mit 0,5 Hz. Wenn 
nicht, prüfe die CLKDIV8 Fuse. Wenn es dann immer noch nicht klappt, 
hast du eventuell den Abblock Kondensator vergessen oder versehentlich 
den Watchdog aktiviert.

Mach das erstmal, dann sehen wir weiter.

von Stefan F. (Gast)


Lesenswert?

Als nächstes würde ich die Zählung in der ISR weglassen, damit der 
LED-Ausgang anzeigt, wie hoch die Interrupt-Rate ist. Mess die mal mit 
einem Frequenzzähler oder Oszilloskop nach. Falls du keins hast, 
verbinde den Ausgang über einen 100k Ohm Widerstand mit der Soundkarte 
und nimm den Ton auf. Dann kannst du mit einer Audio-Software (z.B. 
Audacity) die Frequenz ermitteln.

von Holger W. (mb_holger)


Lesenswert?

Die CLKDIV8 Fuse ist raus. Beide arbeiteten nicht mit nochmal durch 8 
geteilt. Die 5000 um einen definierten Zählwert ohne Komma im ms Bereich 
zu erhalten um dann in der IRQ Routine mit ganzen Zahlen zu arbeiten.
5000 für einen Takt von 0,2 ms ( bei 1000 wäre es eine ms ,geht aber 
nicht weil der der Zähler nur bis 255 geht.
!!!!! Ich glaube ich habe den Fehler gefunden, die IRQ Routine arbeitet 
ja mit der Frequenz vom Chip und nicht mit Prescaler 8. Ich habe alles 
zusammengeschmissen. !!! böser Fehler. Ich muss neu rechnen. Mal sehen 
ob
es möglich ist genau einen Sekundentakt auszurechnen.

von Holger W. (mb_holger)


Lesenswert?

Beim Attiny 85 mit _delay_ms(1000) und #define F_CPU 8000000UL sind es 
gemessen mit den Oszilloskop 993 ms. Ich müsste es mal mit einen 
externen Quarz versuchen, mal sehen ob ich das schaffe. Ich werde es 
versuchen.
Ist etwas besonderes beim Attiny mit externen Quarz zu beachten?  Ein 
Tipp wäre hilfreich.
Danke

von LostInMusic (Gast)


Lesenswert?

Vorschlag:

- als Taktquelle den "Calibrated Internal Oscillator" wählen (8 MHz)
- CLKDIV8-Fuse enablen
- T/C0 im CTC-Mode mit Prescaler 64
- OCRA0 auf 125 setzen

Dann wird der Compare-Match-Interrupt mit 125 Hz aufgerufen (8000000 Hz/ 
8  64  125 = 125 Hz). Das ist ein ganz brauchbarer Wert.

In der ISR teilst Du die 125 Hz dann per Software auf 1 Hz runter:
1
k++; 
2
if (k==125) k = 0;
3
if (k==0) LEDFlash;   // LED kurz aufblitzen lassen

Damit wird die LED fortwährend im Sekundentakt aufblitzen.

Um eine LED im Sekundentakt blinken (statt blitzen) zu lassen, musst 
Du sie im Takt von 2 Hz togglen. 2 Hz lässt sich leider nicht erzeugen, 
weil Du das k==125 natürlich nicht in k==62.5 ändern kannst 
(mathematisch: 2 ist kein ganzzahliger Teiler von 125). Eine mögliche 
Lösung:
1
h = 1 - h;     // abwechselnd 0 und 1
2
k++; 
3
if (k==62+h) k = 0;
4
if (k==0) LED_toggle;

von Holger W. (mb_holger)


Lesenswert?

Nein der Fehler war ich habe mit Prescaler 8 gerechnet und CS02 gesetzt 
also Prescaler 256 programmiert. *Da kann nur Unsinn rauskommen.*

Noch mal zu Berechnung Attiny 8 Mhz, Prescaler 8 und OCR0A = 199 , also 
aller 0,2 ms wird die IRQ Routine angwurfen. Um auf 1 Sekunde zu kommen 
muß die ISR 5000 mal angefurfen werden. Die Zeit die die ISR verbraucht 
spielt keine Rolle weil der Zähler unabhängig läuft.

Gemessen mit Oszilloskop sind es 994 ms das entspricht dem 
_delay_ms(1000) gemessen 993 ms. *Ist die Differenz zur ganzen Sekunde 
die Toleranz in der Frequenz ? oder habe ich noch einen Fehler?*

Gemessen mit einen alten RFT Zähler 994,19 ms bei 18 C°. Ich habe den 
Attiny mit den Lötkolben eingheizt, da geht die Zeit gleich auf 989 ms 
runter. Bei Wärme läuft der Attiny deutlich schneller.

Da ich erst seit seit 3 Tagen mich mit diesen Sachen beschäftige bin ich 
schon stolz auf mich. Aber auch ein Lob an das Forum. Hier kamen einige 
Denkanstöße. Alleine hätte ich vielleicht aufgegeben.


richtiger Code
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
// TIMER 0 
5
int k = 0;
6
ISR(TIM0_COMPA_vect)
7
{
8
  k++; if (k==5000) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1
9
}  // Ende ISR
10
11
int main()
12
{
13
  // Timer 0 
14
  TCCR0A = (1<<WGM01); // CTC Modus
15
  TCCR0B |= (1<<CS01); // Prescaler 8 !!!!!!!!!!
16
  // ((8000000/8)/5000) = 200 
17
  
18
  OCR0A = 199; // 8000000/8/200 entspricht 5000Hz also 0,2 ms  
19
           // 1000 ms / 0,2 ms = 5000 das ist k in ISR
20
  
21
  // Compare Interrupt erlauben
22
  TIMSK |= (1<<OCIE0A);
23
  
24
  // Global Interrupts aktivieren
25
  sei();
26
  
27
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
28
29
  while(1){  
30
  } // Ende while
31
  return 0;
32
  
33
} //Ende main

von Holger W. (mb_holger)


Lesenswert?

Ich muss noch mal nerven zum Sonntag. Noch eine spezielle Frage zum 
Timer mit dem CTC Mode.
Kann man  verschiedene Interrupt Routinen über einen Timer ansprechen. 
zB bei Zählerstand 150  die  Routine A und bei Zählerstand 230 die 
Routine B.

In einer Interrupt Routine des Timers die nächste ISR festzulegen also
beim nächsten Interrupt  eine andere ISR auszuführen.

Kann man in der Hauptroutine auch Timer mit ISR festlegen die dann nur
einmal ausgeführt werden oder auch verschachtelt sind oder gehen die
Timer mit ISR nur global.


Meine Fragen deshalb weil die Anzahl der Timer je nach Chip begrenzt
ist.

Für praktische Tipps bin sich dankbar.
Grüsse Holger

von Walter (Gast)


Lesenswert?

Holger Weiß schrieb:
> Kann man  verschiedene Interrupt Routinen über einen Timer ansprechen.
> zB bei Zählerstand 150  die  Routine A und bei Zählerstand 230 die
> Routine B.

nein, aber du kannst den Interrupt schneller kommen lassen und dann 
mittels eines Zählers in der Interruptroutine verschiedene Aktionen 
machen

von Holger W. (mb_holger)


Lesenswert?

Ein 8-Bit Timer und ein 16-Bit Timer kann doch unabhänig und 
gleichzeitig laufen (oder?) und unterschiedliche ISR aufrufen oder sehe 
ich das falsch ? oder ist nur eine ISR für Timer zugelassen die von 
allen Timern aufgerufen wird ?

von Walter (Gast)


Lesenswert?

Holger Weiß schrieb:
> Ein 8-Bit Timer und ein 16-Bit Timer kann doch unabhänig und
> gleichzeitig laufen (oder?) und unterschiedliche ISR aufrufen

ja, pro Timer gibt es einen Satz Interuptroutinen, die Liste findet sich 
im Datenblatt

von Holger W. (mb_holger)


Lesenswert?

Danke. Ist noch jemand am Computer? Ich werde morgen Abend mal einen 
externen Quarz an den Attiny 13 oder 85 anschließen. Die Ungenauigkeit 
in der Frequenz möchte ich abstellen und mit den genialen RFT Zähler 
genaue Zeiten messsen bis auf die halbe_Femtosekunde :~) genau.

Meine Frage: Ich bin bei den Fuses nicht so sicher. 2 Attiny und einen 
Atmega 32 habe ich schon unbrauchbar genacht mit Fuses. 1 oder 2 Tipps 
für den exteren Quarz und den Fuses wären gut, weil heute Sontag ist.
Grüße Holger

von Holger W. (mb_holger)


Lesenswert?

Sonntag das n vergessen.

von LostInMusic (Gast)


Lesenswert?

>2 Attiny und einen Atmega 32 habe ich schon unbrauchbar genacht mit Fuses.

Dann bau mal mit dem nächsten µC einen Taktgenerator, mit f = irgendwas 
zwischen 20 und 200 kHz. Falls sich die falsche Fuse-Einstellung bei 
Deinen verunglückten Exemplaren auf die Taktquelle bezieht, kannst Du 
sie mit einem externen Takt nämlich leicht "wiederbeleben".

Gute Nacht.

von c-hater (Gast)


Lesenswert?

Holger Weiß schrieb:

> Ich werde morgen Abend mal einen
> externen Quarz an den Attiny 13 oder 85 anschließen.

Beim Tiny13 wird dir das kaum gelingen. Der kann keine Quarze 
oszillieren lassen. Ein auch nur ganz flüchtiger Blick in's Datenblatt 
hätte diesen Fakt auch für dich offenbart...

Wenn du beim Tiny13 einen Quarztakt haben willst, mußt du einen externen 
Quarzoszillator benutzen.

> Meine Frage: Ich bin bei den Fuses nicht so sicher. 2 Attiny und einen
> Atmega 32 habe ich schon unbrauchbar genacht mit Fuses.

Auch das hätte durch intensive Lektüre der Datenblätter vermieden werden 
können.

Nimm' einfach mal zu Kenntnis: Wer lesen kann, ist klar im Vorteil.

von Peter D. (peda)


Lesenswert?

Holger Weiß schrieb:
> Ich bin bei den Fuses nicht so sicher. 2 Attiny und einen
> Atmega 32 habe ich schon unbrauchbar genacht mit Fuses.

Im AVR-Studio ist die Auswahl der Fuses doch narrensicher.

Von RSTDISBL und DWEN Finger weg!
Dann hilft nur noch ein STK500 zum Wiederbeleben.

von Holger W. (mb_holger)


Lesenswert?

naja ich bin kein Narr, deshalb nicht sicher genug. habe doch etwas 
falsches verstellt. Die Verstellen sind jetzt in der runden Ablage.
M
it dem Attiny 85 und externen Quarz sollte es funktionieren. Ich muss 
mich nur noch schlau machen wie der Quarz angebaut wird und welche Fuses 
ich setze. Damit ich mit den Timern weiter experimentieren kann.

Hat jemand eine interessante Anregung für einen Versuch oder eine 
Aufgabe für mich zu dem Timern Attiny 85.

Holger

von Entnervter (Gast)


Lesenswert?

c-hater schrieb:
> Nimm' einfach mal zu Kenntnis: Wer lesen kann, ist klar im Vorteil.

Genau. Dann hättest Du diesen Satz des TO vielleicht besser deuten 
können:

Holger Weiß schrieb:
> Da ich erst seit seit 3 Tagen mich mit diesen Sachen beschäftige bin ich
> schon stolz auf mich. Aber auch ein Lob an das Forum. Hier kamen einige
> Denkanstöße. Alleine hätte ich vielleicht aufgegeben.


SCNR

von Holger W. (mb_holger)


Lesenswert?

Eine Frage zum Timer. Ich habe herausgefunden, dass bei dem Code C jeder 
Chip eigene Bezeichnungen für die Timer hat.

zB. attiny 85
TIMSK = (1 << TOIE0); // bei attiny 85

und bei attiny 13
TIMSK0 = (1 << TOIE0); // bei attiny 13

bei der Anpassung das Codes an den Atmega 32 scheitere ich. Stehen die 
Programmbezeichnungen im Datenblatt? Bitte eine kurze Erklärung für 
einen Anfänger.

Warning  1  'TIM0_COMPA_vect' appears to be a misspelled signal handler 
[enabled by default]

Error  2  'TCCR0A' undeclared (first use in this function)
Message  3  each undeclared identifier is reported only once for each 
function ............
Error  4  'TCCR0B' undeclared (first use in this function)
Error  5  'OCR0A' undeclared (first use in this function)
Error  6  'OCIE0A' undeclared (first use in this function)


hier der Code für Attiny 85 der funktioniert, den ich auf den Atmega32 
senden will, da kommen die oben genanten Fehlermeldungen.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
// TIMER 0 
5
int k = 0;
6
ISR(TIM0_COMPA_vect)
7
{
8
  k++; if (k==5000) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1
9
}  // Ende ISR
10
11
int main() 
12
{
13
  // Timer 0 
14
  TCCR0A = (1<<WGM01); // CTC Modus
15
  TCCR0B |= (1<<CS01); // Prescaler 8 !!!!!!!!!!
16
  // ((8000000/8)/5000) = 200 
17
  
18
  OCR0A = 199; // 8000000/8/200 entspricht 5000HZ also 0,2 ms  
19
           // 1000 ms / 0,2 ms = 5000 das ist k in ISR
20
  
21
  // Compare Interrupt erlauben
22
  TIMSK |= (1<<OCIE0A);
23
  
24
  // Global Interrupts aktivieren
25
  sei();
26
  
27
  DDRB |= (1 << PB1); // damit ist dann PB1 ein Ausgang
28
29
  while(1){  
30
  } // Ende while
31
  return 0;
32
  
33
} //Ende main

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Holger Weiß schrieb:
> bei der Anpassung das Codes an den Atmega 32 scheitere ich. Stehen die
> Programmbezeichnungen im Datenblatt?

Ja.

> Warning  1  'TIM0_COMPA_vect' appears to be a misspelled signal handler
> [enabled by default]

TIM0_COMP_vect, es gibt hier keine Unterscheidung A<->B.

> Error  2  'TCCR0A' undeclared (first use in this function)

TCCR0, aus demselben Grund.

> Error  4  'TCCR0B' undeclared (first use in this function)

dito.

> Error  5  'OCR0A' undeclared (first use in this function)

OCR0

> Error  6  'OCIE0A' undeclared (first use in this function)

OCIE0

Sämtliche Bezeichnungen findest Du im Datenblatt.

Du musst auch ein wenig aufpassen: Ab und zu "wandern" bestimmte Bits je 
nach Atmega in verschiedene Register, z.B. bei den WGM-Bits. Hier 
solltest Du immer erst ins Datenblatt schauen, auch wenn eine Zuweisung 
erstmal augenscheinlich bei einer Portierung auf einen anderen ATmega 
durch den Compiler geht. Deshalb hast Du noch keine Sicherheit, ob das 
gesetzte Bit tatsächlich in dem benutzten Register tatsächlich steckt.

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

Holger Weiß schrieb:
> Die Verstellen sind jetzt in der runden Ablage.

Nicht so voreilig.
Solange RSTDISBL und DWEN nicht verstellt sind, lassen sie sich mit 
einem 2. ATtiny als Taktgeber wiederbeleben.

von Holger W. (mb_holger)


Lesenswert?

eine Fehlermeldung kam noch
So funktioniert es:

TIM0_COMP_vect musste noch TIMER0 COMP werden. beim Atmega32

ganz böse Fallen für den Anfang.


Beim Attiny 13: TIMSK0 |= (1<<OCIE0A) und TIM0_COMPA_vect

beim Attiny 85: TIMSK |= (1<<OCIE0A) und  TIM0_COMPA_vect

beim Atmega 32: TIMSK |= (1<<OCIE0)  und  TIMER0_COMP_vect

Das kann ja noch kompliziert werden. Jetzt blinkt die LED in 
Sekundentakt am Atmega 32.

Gibt es eine Zusammenstellung für die gebräuchlichen Chips und häufigen 
Codes oder hilft hier nur das Datenblatt.

Bei der Zeitmessung der LED´s mit den Zähler konnte ich feststellen das 
der Takt stark von der VVC abhängt, aber der Takt beim Atmega32 exakt 
konstant gehalten wird, während bei de Attiny´s Schwankungen im Takt 
auftraten.

Schwankung Attiny in der Konstanz um eine Millisekunde.
Schwankung Atmega 32 in der Konstanz nur um 0,03 Millisekunden.
falls das jemanden interessiert.

Ist es richtig wenn ich aller (0,2ms) 200 Zählertakte die ISR aufrufen 
will  OCR0A = 199 einzugeben da erst bei 200 die ISR angeht?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Holger Weiß schrieb:
> Beim Attiny 13: TIMSK0 |= (1<<OCIE0A) und TIM0_COMPA_vect
>
> beim Attiny 85: TIMSK |= (1<<OCIE0A) und  TIM0_COMPA_vect
>
> beim Atmega 32: TIMSK |= (1<<OCIE0)  und  TIMER0_COMP_vect

Mit Hilfe des Preprocessors kannst Du den Source einheitlich halten:
1
#if defined (__AVR_ATtiny87__)
2
    TIMSK0 |= (1<<OCIE0A);
3
#if defined (__AVR_ATtiny85__)
4
    TIMSK |= (1<<OCIE0A);
5
#if defined (__AVR_ATmega32__)
6
    TIMSK |= (1<<OCIE0);
7
#endif


Die ISR-Vektoren kann Du µC-spezifisch schreiben als:
1
#if defined (__AVR_ATtiny87__)
2
#define T0_COMP_vect      TIM0_COMPA_vect
3
#if defined (__AVR_ATtiny85__)
4
#define T0_COMP_vect      TIM0_COMPA_vect
5
#if defined (__AVR_ATmega32__)
6
#define T0_COMP_vect      TIMER0_COMP_vect
7
#endif

Dann:
1
ISR (T0_COMP_vect)
2
{
3
    ....
4
}

Mit der Zeit wirst Du dann auf die Idee kommen, solche Konstrukte für 
eigene "Bibliotheken" zu verwenden, um einen möglichst portablen Code zu 
erhalten.

> Gibt es eine Zusammenstellung für die gebräuchlichen Chips und häufigen
> Codes oder hilft hier nur das Datenblatt.

Datenblatt.

> Ist es richtig wenn ich aller (0,2ms) 200 Zählertakte die ISR aufrufen
> will  OCR0A = 199 einzugeben da erst bei 200 die ISR angeht?

Schaue hier: AVR-GCC-Tutorial/Die Timer und Zähler des AVR

von Holger W. (mb_holger)


Lesenswert?

External Crystal/Ceramic Resonator Einstellung:

Fuse Einstellung : EXTRCOSC_8MHZ_12MHZ_18CK_64MS ist richtig für den 
externen Quarz 8 MHz an dem Atmega32 ?

Was sagen die 18CK und 64MS aus?

von Holger W. (mb_holger)


Lesenswert?

Ich habe mich schlau gemacht, muß folgendes nehmen
EXTHIFXTALRES_16KCK_64MS , ist das richtig?

von Holger W. (mb_holger)


Lesenswert?

JA war richtig. super mit externen Quarz. Der Takt ist absolut genau 
8MHz
Die LED blinkt absolut konstant mit 999,986 ms. Wenn ich den Quarz mit 
dem Lötkolben einheize verändert sich die Zeit nur minimal auf 999,984 
ms. Es ist schon erstaunlich was alles so in dem Chip steckt.

Habe jetzt meinen alten RFT Zähler G2001.500 angemacht und die Zeit 
gemessen : 999,994 ms.  Ein Spitzenwert. So habe ich mir das 
vorgestellt.

von Holger W. (mb_holger)


Lesenswert?

Ich führe ja schon Selbstgespräche.

Hat jemand eine interessante Anregung für einen Versuch oder eine
Aufgabe für mich zu den Timern Attiny 85 oder Amega32 so zur Übung für 
einen Anfänger.


Holger

von noname (Gast)


Lesenswert?

Wie wäre es mit einer Lichtschranke ?

Da hätte man eine wenig Optoelektronik, auf dem Mµ Pinchange Interrupt 
bzw. steigende\fallende Flanke mit ISR, EEprom bzw. ein Anzeigeelement 
um die Zeiten auszugeben, ein wenig Logik, ein wenig Physik ...

von Max B. (theeye)


Lesenswert?

Holger Weiß schrieb:
> Hat jemand eine interessante Anregung für einen Versuch oder eine
> Aufgabe für mich zu den Timern Attiny 85 oder Amega32 so zur Übung für
> einen Anfänger.

Auf meiner Tiny-Projektliste steht noch ein "Briefkastenmelder". LED 
hinter das Namensschild, wenn Klappe geöffnet wird (Reed Schalter) LED 
an. Automatisch zurücksetzen, wenn die große Klappe zur Entnahme der 
Briefe geöffnet wird.

Mal so als Idee. Ansonsten Google mal nach attiny Projekten.

Gruß Max

von Holger W. (mb_holger)


Lesenswert?

Ich werde mal einen Zeitmesser für die Belichtungszeiten meiner analogen 
Kameras bauen, mit einer Anzeige an den Atmega32. Bisher habe ich die 
Zeiten mit dem Zähler gemessen. Mal sehen hoffentlich ist das nicht zu 
kompliziert für den Anfang.

Interessant wäre auch die Daten aus dem Analog-Digital-Umsetzer auf 
einer SD Karte zu loggen mit einer txt Datei die man in Exel einlesen 
kann.
Ist das möglich mit einen Atmega32 wie kann man eine SD Karte einbinden. 
Ist das sehr kompliziert und welche Hardware brauche ich dazu.
Die Aufzeichnung soll ohne PC funktionieren.

Holger

von npn (Gast)


Lesenswert?

Holger Weiß schrieb:
> Ich werde mal einen Zeitmesser für die Belichtungszeiten meiner
> analogen
> Kameras bauen, mit einer Anzeige an den Atmega32. Bisher habe ich die
> Zeiten mit dem Zähler gemessen. Mal sehen hoffentlich ist das nicht zu
> kompliziert für den Anfang.
>
> Interessant wäre auch die Daten aus dem Analog-Digital-Umsetzer auf
> einer SD Karte zu loggen mit einer txt Datei die man in Exel einlesen
> kann.
> Ist das möglich mit einen Atmega32 wie kann man eine SD Karte einbinden.
> Ist das sehr kompliziert und welche Hardware brauche ich dazu.
> Die Aufzeichnung soll ohne PC funktionieren.
>
> Holger

Als Hardware brauchst du eigentlich nur paar Widerstände und einen 
SD-Karten-Leser. Schau doch mal bei Ulrich Radig vorbei:
http://www.ulrichradig.de/
und dann auf "AVR" gehen, dann auf "MMC/SD". Dort ist alles beschrieben.

von c-hater (Gast)


Lesenswert?

Holger Weiß schrieb:

> Interessant wäre auch die Daten aus dem Analog-Digital-Umsetzer auf
> einer SD Karte zu loggen mit einer txt Datei die man in Exel einlesen
> kann.

Sehr spannendes Vorhaben, es gibt ja nur (gefühlt) 20.000 Lösungen für 
AVR-Datenlogger bisher...

Ich würde dir eher empfehlen, dir eine der bestehenden Lösungen zu 
greifen und zu versuchen, sie bis zur letzten Zeile zu verstehen, 
inklusive aller dort benutzten "Copy&Paste-Importe".

Da lernst du sehr viel mehr als mit noch viel mehr Copy&Paste und 
sinnlosem Rumgefrage in 1000 Jahren lernen kannst...

von npn (Gast)


Lesenswert?

c-hater schrieb:
> Sehr spannendes Vorhaben, es gibt ja nur (gefühlt) 20.000 Lösungen für
> AVR-Datenlogger bisher...

Du vergißt wiedermal, daß er noch vor 4 Tagen das hier geschrieben hat.
Holger Weiß schrieb:
> Ich bin neu hier und Anfänger.
> Ich habe zwei LED wechselnd zum Blinken gebracht mit dem Attiny 85,

Und vor paar Minuten hat er danach gefragt:
Holger Weiß schrieb:
> Hat jemand eine interessante Anregung für einen Versuch oder eine
> Aufgabe für mich zu den Timern Attiny 85 oder Amega32 so zur Übung für
> einen Anfänger.

Mußt du da wirklich wieder einen deiner arroganten Kommentare ablassen?
Er will lernen und braucht was als Übung.

von c-hater (Gast)


Lesenswert?

npn schrieb:

> Du vergißt wiedermal, daß er noch vor 4 Tagen das hier geschrieben hat.

Nein, das hab' ich nicht vergessen.

> Er will lernen und braucht was als Übung.

Genau das ist, was ich meine. Copy&Paste übt und lehrt garnix und 
erzeugt so auch keinerlei Kompetenz, um was wirklich eigenes machen zu 
können.

von Holger W. (mb_holger)


Lesenswert?

Danke npn der Tipp ist gut.
Holger

von Holger W. (mb_holger)


Lesenswert?

Ja das ist schon richtig, c-hater. nur Copy&Paste lernt nichts.
Mir geht es nicht um Copy&Paste. Das kenne ich aus meinem Beruf. Ohne 
grundlegendes Verständnis und Copy&Paste wird das Ergebnis nur 
schlechter Gut Entwickeltes wird an einer anderen Stelle oder bei 
punktuellen  Anpassungen ohne Verständnis nur schlechter und fehlerhaft.

Aber ich brauche schon einen Anfang und ich will das Rad nicht neu 
erfinden. Wenn ich etwas schon Erfundenes nehme zum üben, für mich 
anpasse und damit Prinzip verstehe, komme ich ein ganzes Stück weiter. 
Die eine oder andere Frage taucht halt mal auf beim experimentieren und 
ein paar Denkanstöße und Hinweise für den Anfang sind schon sehr 
hilfreich. Die eine oder andre eigene kleine sinnvolle Anwendung will 
ich dann schon mal eigenständig entwickeln können.

Holger

von spess53 (Gast)


Lesenswert?

Hi

...und ich will das Rad nicht neu erfinden.

Dieser Spruch kotzt mich langsam an. Es ist der, den alle benutzen, die 
nichts wirklich lernen wollen. Um zu wirklich zu lernen muss man ein 
paar Räder neu erfinden.

MfG Spess

von Holger W. (mb_holger)


Lesenswert?

Ich bin erstaunt, den Erfinder von Rädern hier anzutreffen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Holger Weiß schrieb:
> Ich bin erstaunt, den Erfinder von Rädern hier anzutreffen.

Och... davon gibt es sogar mehrere ;-)

Aber manchmal ist es nicht verkehrt, das Rad neu zu erfinden. Auch Räder 
können immer noch verbessert werden.

von Holger W. (mb_holger)


Lesenswert?

Hallo,
Ich habe eine spezielle Frage um zeitlichen Ablauf.

Wieviele Takte bzw Zeit verbraucht zb. die ISR
1
ISR(TIM0_COMPA_vect)
2
{
3
  k++; if (k==164) {k = 0; PORTB ^= (1<<PB1); } // zustandswechsel PB1
4
}  // Ende ISR

oder die Schleife
1
while(1){  
2
  } // Ende while

Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?

Grüße Holger

von Karl H. (kbuchegg)


Lesenswert?

Holger Weiß schrieb:

> Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?

Indem man sich vom Compiler ein Assembler Listing erzeugen lässt und 
dann für die Instruktionen Takte zählt.

von Route_66 H. (route_66)


Lesenswert?

Holger Weiß schrieb:
> Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?

Über den Assemblertext.

von Karl H. (kbuchegg)


Lesenswert?

Holger Weiß schrieb:
> Ich bin erstaunt, den Erfinder von Rädern hier anzutreffen.

Wer Radmacher werden will, kommt nicht umhin mit einfachen Rädern sein 
Handwerk erst mal zu lernen. Selbst wenn sich die dazu benutzte Technik 
seit 3000 Jahren nicht wesentlich verändert hat.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Karl Heinz schrieb:
> Selbst wenn sich die dazu benutzte Technik
> seit 3000 Jahren nicht wesentlich verändert hat.

Solange gibt es schon 3D-Drucker?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Peter Dannegger schrieb:
> Karl Heinz schrieb:
>> Selbst wenn sich die dazu benutzte Technik
>> seit 3000 Jahren nicht wesentlich verändert hat.
>
> Solange gibt es schon 3D-Drucker?

Klar, Schnitzeisen und ein Stück Holz.

von Joachim B. (jar)


Lesenswert?

Holger Weiß schrieb:
> Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?

Karl Heinz schrieb:
> Compiler ein Assembler Listing erzeugen lässt und
> dann für die Instruktionen Takte zählt.

ist das nicht was für langweilige Winterabende?

ich setze einen Port am Anfang, am Ende wieder zurück und sehe die Zeit 
auf dem Oszi, wieviel Takte das sind sehe ich ja an Zeit / Taktzeit 
(=1/F_CPU)

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Joachim B. schrieb:
> ich setze einen Port am Anfang, am Ende wieder zurück und sehe die Zeit
> auf dem Oszi, wieviel Takte das sind sehe ich ja an Zeit / Taktzeit
> (=1/F_CPU)

Ich setze im Simulator 2 Brechpunkte und lasse mir die Zeit oder Zyklen 
dafür anzeigen.

von Karl H. (kbuchegg)


Lesenswert?

Joachim B. schrieb:
> Holger Weiß schrieb:
>> Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?
>
> Karl Heinz schrieb:
>> Compiler ein Assembler Listing erzeugen lässt und
>> dann für die Instruktionen Takte zählt.
>
> ist das nicht was für langweilige Winterabende?

Natürlich.
Aber wenn mir das nächste mal an einem Winterabend langweilig ist, 
strick ich mir erst mal ein Oszi :-)


(Wir ham ja nix ghabt, nachm Krieg. Was hamma denn ghabt? Nix hamma 
ghabt!=

von npn (Gast)


Lesenswert?

Karl Heinz schrieb:
> strick ich mir erst mal ein Oszi :-)

Häkeln oder klöppeln wird besser :-)

von Holger W. (mb_holger)


Lesenswert?

Mit Rädern kann man auch strickeln und häkeln. Wieder etwas gelernt! Ich 
muss nur noch etwas üben.


Einen Oszi habe ich, ist ein guter Tipp.

Peter Dannegger schrieb:
> Ich setze im Simulator 2 Brechpunkte und lasse mir die Zeit oder Zyklen
> dafür anzeigen.
auch ein guter Tipp.

Ich werde mal testen ob bei den beiden Varianten die Zeiten gleich sind.

Danke Holger.

von Holger W. (mb_holger)


Lesenswert?

Holger Weiß schrieb:
> Ich werde mal testen ob bei den beiden Varianten die Zeiten gleich sind.

Ich nehme auch Wetten auf das Ergebnis an.
Holger

von Holger W. (mb_holger)


Lesenswert?

Hallooooo. Wer redet mit mir?

von c-hater (Gast)


Lesenswert?

Peter Dannegger schrieb:

> Ich setze im Simulator 2 Brechpunkte und lasse mir die Zeit oder Zyklen
> dafür anzeigen.

Ja, und du fällst grandios auf die Schnauze, wenn du einen anderen 
Compiler benutzt oder auch nur eine ander Version desselben Compilers 
oder auch nur denselben Compiler mit anderen Optionen...

Für mich ist Programmieren etwas deterministisches. Ein 
deterministisches Zeitverhalten gehört da ganz selbstverständlich dazu, 
jedenfalls überall dort, wo es relevant ist, also eigentlich immer dann, 
wenn man eine Hardware auch nur annähernd bis an ihre Leistungsgrenze 
ausnutzen will (oder muss).

Alles andere ist Nasenpopelei. Das geht dann auch in C. Allerdings kann 
man dann auch einfach die wirklich komfortablen echten Hochsprachen 
dafür verwenden, dann gibt es keinen Grund mehr, sich mit der kruden 
Syntax und den vielen eingebauten Sprachfallen von C rumzuschlagen...

von Holger W. (mb_holger)


Lesenswert?

Ich habe es mit dem Simulator getestet, aber nur mit 1 MHz. Da mußte ich 
umrechnen zum Takt 8 MHz . Wo kann man im Simulator die Taktfrequenz 
einstellen?
Im Ergebnis Timer blink LED
Gemessen mit OSZI 1000 ms
im Simulator mit Brechpunkt 1000 ms

also gleich.

c-hater schrieb:
> Ja, und du fällst grandios auf die Schnauze, wenn du einen anderen
> Compiler benutzt

Heißt das verschiedene Compiler unterschiedlich übersetzen.
Welche echten Hochsprachen, für dem Atmega 32 sind empfehlenswert.

Holger

von Holger W. (mb_holger)


Lesenswert?

c-hater schrieb:
> die wirklich komfortablen echten Hochsprachen

Pascal? für den Atmega?

von Holger W. (mb_holger)


Lesenswert?

Sind alle schon im Bett?

von Holger W. (mb_holger)


Lesenswert?

Welcher Pascal Compiler ist empfehlenswert für einen Anfänger. 
(Atmega32)
Holger

von npn (Gast)


Lesenswert?

Hallo Holger,

die folgenden beiden sind am meisten bekannt. Beide sind kommerziell, 
sie haben jeweils auch Demo-Versionen, die eingeschränkt sind.
Ich habe aber selber mit beiden noch nicht gearbeitet, kann also keine 
weiteren Aussagen dazu treffen.
http://www.mikroe.com/mikropascal/avr/
http://www.e-lab.de/AVRco/

Daneben gibt es noch LunaAVR, macht auch keinen schlechten Eindruck und 
wird ständig weiterentwickelt.
http://avr.myluna.de/doku.php

Ich denke, da hast du erstmal was zum Lesen und Testen...

mfg

von Sebastian W. (wangnick)


Lesenswert?

Hallo Holger,

Holger Weiß schrieb:
> Jetzt mein Problem.  Ich habe keine Lösung wie ich die zwei LED
> unabhängig blinken lassen kann. Wie kann ich zB. zwei Schleifen parallel
> ablaufen lassen oder eine andere Lösung , mit unabhängigen,definierten
> und genauen Blinkzeiten. Ich habe keine Idee und brauche Hilfe für einen
> Lösungsansatz für den C-Code.

Bei einem Prozessorkern kann es keine echte parallele Verarbeitung 
geben. Das ist auch in "großen" Betriebssystemen nicht anders. Die 
angeblich parallele Verarbeitung wird in Wirklichkeit durch kleine 
Prozessorzeitscheiben realisiert, die ein Scheduler sequentiell den 
laufbereiten Prozessen/Threads zuteilt. Das nennt sich dann präemptives 
Multitasking. Dafür gibt es auch einfache Bibliotheken für 
AVR-Controller.

Ebenso ist die Anzahl der Timer begrenzt. Man kann aber beliebig viele 
Softwaretimer mit nur einem einzigen Hardwaretimer simulieren. Dazu 
führt man eine Liste aller Softwaretimer und deren Rückrufroutinen, am 
besten sortiert nach der anstehenden Triggersequenz.

Joachim B. schrieb:
> Holger Weiß schrieb:
>> Wie kann man aus dem c Code die Anzahl der verbrauchten Takte ableiten?
>
> Karl Heinz schrieb:
>> Compiler ein Assembler Listing erzeugen lässt und
>> dann für die Instruktionen Takte zählt.

Diesen Rat solltest Du als Anfänger auf jeden Fall befolgen, du wirst 
dabei viel Nützliches lernen.

Holger Weiß schrieb:
> Welche echten Hochsprachen, für dem Atmega 32 sind empfehlenswert.

Hochsprachen sind Geschmackssache. Manche würden auch zum Beispiel C++ 
(von Arduino benutzt) nicht als Hochsprache bezeichnen. Pass auf, dass 
Deine Frage nicht einen der berüchtigten Sprachkriege auslöst :)

LG, Sebastian

von Holger W. (mb_holger)


Lesenswert?

Peter Dannegger schrieb:

> Ich setze im Simulator 2 Brechpunkte und lasse mir die Zeit oder Zyklen
> dafür anzeigen.

Ich finde keine Einstellmöglichkeit vom Takt im Simulator. Ich habe  in 
den Fuses des Simulators 8 MHZ eingestellt.
Es wird immer der Simulator mit 1 MHZ ausgeführt und die Fuses auf 1 MHZ 
zurückgestellt.

Die Empfehlung  Erst, wenn er dann mal läuft kannst du im Menü unter 
"Debug" --> "AVR-Simulator-Options" den Typ und die Taktfrequenz 
einstellen.....

Das finde ich im AVR Studio 6.2 nicht ???

von npn (Gast)


Lesenswert?

Holger Weiß schrieb:
> Die Empfehlung  Erst, wenn er dann mal läuft kannst du im Menü unter
> "Debug" --> "AVR-Simulator-Options" den Typ und die Taktfrequenz
> einstellen.....
>
> Das finde ich im AVR Studio 6.2 nicht ???

Wenn der Simulator läuft, kannst du im Fenster Processor View die 
Taktfrequenz einstellen. Also dort, wo auch der Cycle Counter und Stop 
Watch in der Tabelle angezeigt wird. Da ist auch der Eintrag Frequency 
vorhanden. Standardmäßig steht dort 1MHz. Ein Klick auf die Zahl und du 
kannst beispielsweise 16MHz einstellen. Enter und das war's...

von npn (Gast)


Lesenswert?

npn schrieb:
> Holger Weiß schrieb:
>> Die Empfehlung  Erst, wenn er dann mal läuft kannst du im Menü unter
>> "Debug" --> "AVR-Simulator-Options" den Typ und die Taktfrequenz
>> einstellen.....
>>
>> Das finde ich im AVR Studio 6.2 nicht ???
>
> Wenn der Simulator läuft, kannst du im Fenster Processor View die
> Taktfrequenz einstellen. Also dort, wo auch der Cycle Counter und Stop
> Watch in der Tabelle angezeigt wird. Da ist auch der Eintrag Frequency
> vorhanden. Standardmäßig steht dort 1MHz. Ein Klick auf die Zahl und du
> kannst beispielsweise 16MHz einstellen. Enter und das war's...

Funktioniert's denn jetzt?

von Holger W. (mb_holger)


Lesenswert?

Hallo pnp,

Ja so funktioniert es exakt.

npn schrieb:
> Daneben gibt es noch LunaAVR, macht auch keinen schlechten Eindruck und
> wird ständig weiterentwickelt.
> http://avr.myluna.de/doku.php


Ich habe heute mal mit LunaAVR den Compare Match Timer mit blink 1s 
programmiert. Nach einigen Schwierigkeiten hat es funktioniert.

Hier das Beispiel.
1
avr.device = atmega32  //Controller-Typ festlegen
2
avr.clock = 8000000     //Dem Compiler mitteilen mit welcher Taktrate der Controller läuft
3
avr.stack = 64        //Den Programmstack einstellen
4
5
#define LED1 as PortB.0  
6
LED1.mode = output  
7
8
Avr.Interrupts.Enable // Globale Interrupts einschalten
9
Timer0.Cmp.Isr = meineServiceRoutine // Serviceroutine zuweisen
10
timer0.pwm.mode = 2
11
avr.ocr0 = 199
12
Timer0.Cmp.Enable // Timer einschalten
13
Timer0.clock = 8 // Prescaler einstellen
14
15
dim k as integer
16
k=0
17
18
do
19
loop
20
21
Isr meineServiceRoutine
22
K=k+1
23
when K=5000 do LED1.toggle
24
when k=5000 do k=0
25
26
EndIsr

Ist ähnlich Pascal meiner Meinung. Mit Pascal hatte ich mal vor 30 
Jahren zu tun, danach bis jetzt nur Windows. Ich muss erstmal wieder 
reinkommen in die Materie. Das Forum hier war sehr hilfreich.

Holger

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.