Timer1 Atmega8A?

#3861782
Lesenswert?

Hallo,

ich wollte gern den PORTC durschalten lassen und leds der eihe nach 
leuchten lassen das muss aber genauer sein als mit einem normalen delay.

Deswegen dachte ich ein Timer muss her.

Nur leider will der nicht so wie ich.

Ich hoffe mir kann vllt jmd helfen.



initialisierung
1
void timer_init(void)
2
{
3
  OCR1A=200; //Prescaler 64 dh. ungefähr 1hz bei 3906
4
  TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);
5
  TIMSK |= (1<<OCIE1A);
6
  sei();  
7
}

Aufruf der init()
1
void vor (20)
2
{
3
  int i=0;
4
  
5
  for (i=0;i<20;i++)
6
  {
7
    if (endhinten==0)
8
    {
9
      if (timer_zaehler==0){PORTC=0b00001000;}
10
      if (timer_zaehler==1){PORTC=0b01100010;}
11
      if (timer_zaehler==2){PORTC=0b00100010;}
12
      if (timer_zaehler==3){PORTC=0b01010110;}
13
      if (timer_zaehler==4){PORTC=0b00010010;}
14
      if (timer_zaehler==5){PORTC=0b01000011;}
15
      if (timer_zaehler==6){PORTC=0b00010001timer_zaehler=0;}
16
      timer_init();
17
    }
18
  }
19
}

interupt routine
1
ISR(TIMER1_COMPA_vect)
2
{
3
  timer_zaehler=timer_zaehler+1;
4
}

und natürlich die globale variable timer_zaehler.

liegt es an der initialisierung ??
Weil die routine wird doch erst aufgerufen bzw. es wird in die ISR 
gesprungen nach dem aufruf der init() ? oder weil er dann hochgezählt 
hat und vergleicht und dann in den interrupt geht.
#3861849
Lesenswert?

????


FAQ: Timer

Und das Setzen der LED kannst du durchaus in der ISR machen.
Es gibt wirklich keinen Grund da grossartig zu künsteln. Die paar 
Takzyklen, die die Vergleiche brauchen, machen das Kraut auch nicht 
fett.
1
ISR(TIMER1_COMPA_vect)
2
{
3
  timer_zaehler=timer_zaehler+1;
4
  if( timer_zaehler == 7 )
5
    timer_zaehler = 0;
6

7
  if (timer_zaehler==0) {PORTC=0b00001000;}
8
  else if (timer_zaehler==1) {PORTC=0b01100010;}
9
  else if (timer_zaehler==2) {PORTC=0b00100010;}
10
  else if (timer_zaehler==3) {PORTC=0b01010110;}
11
  else if (timer_zaehler==4) {PORTC=0b00010010;}
12
  else if (timer_zaehler==5) {PORTC=0b01000011;}
13
  else if (timer_zaehler==6) {PORTC=0b00010001;}
14
}

wenn man ein bischen besser in C drauf ist, dann realisiert man auch, 
dass man die if-Orgie durch ein Array ersetzen kann
1
static uint8_t Werte[] = { 0b00001000,
2
                           0b01100010,
3
                           0b00100010,
4
                           0b01010110,
5
                           0b00010010,
6
                           0b01000011,
7
                           0b00010001
8
                         };
9
                           
10
ISR(TIMER1_COMPA_vect)
11
{
12
  timer_zaehler=timer_zaehler+1;
13
  if( timer_zaehler == 7 )
14
    timer_zaehler = 0;
15

16
  PORTC = Werte[timer_zaehler];
17
}

das ist nichts, was einem in einer ISR graue Haare bescheeren muss.
(Firma: Vescomp) #3861958
Lesenswert?

Ralf Svenson schrieb:
> aber irwie kommt da nichts bei rum es geht mir ja auch eher um die
> init().
> weil ich mir nicht sicher bin ob ich da etwas falsche gesetzt habe.
 Wenn jeder bit eine LED schalten soll, ja.

Karl Heinz schrieb:
> if (timer_zaehler==0) {PORTC=0b00000001;}
>   else if (timer_zaehler==1) {PORTC=0b00000010;}
>   else if (timer_zaehler==2) {PORTC=0b00000100;}
>   else if (timer_zaehler==3) {PORTC=0b00001000;}
>   else if (timer_zaehler==4) {PORTC=0b00100000;}
>   else if (timer_zaehler==5) {PORTC=0b01000000;}
>   else if (timer_zaehler==6) {PORTC=0b10000000;}
 Wenn du mit Log.1 schaltest.
 Wenn mit Log.0, dann eben anders rum.
Gast #3861991
Lesenswert?

>Deswegen dachte ich ein Timer muss her.
>Nur leider will der nicht so wie ich.

Und was macht der?

>  OCR1A=200; //Prescaler 64 dh. ungefähr 1hz bei 3906
>  TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);

Dein Prescaler ist 1024.

>      if (timer_zaehler==6){PORTC=0b00010001timer_zaehler=0;}

Was ist das für eine Kacke? Du postest hier Code der nie
einen Compiler gesehen hat. Zeig den vollständigen Original Code
und nicht irgendeinen Copy and Paste Müll. Den kannst du dir
sonst wohin schieben.
#3862066
Lesenswert?

Ich ignoriere mal holger(Gast) und schiebe den code mal ein.
Und @Holger der Prescaler steht auf 1024 offensichtlich aber ich will 
ihn bei 64 fahren was dann 24 wären kommentier doch bitte nicht jede 
Codeleiche. Meine Frage war nur die init() mehr nicht.
1
#define F_CPU 1000000UL
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include<avr/interrupt.h>
5

6

7
void int0(void);
8
void int1(void);
9
void SPI_SlaveInit(void);
10
int SPI_Exchange(void);
11
void timer_init(void);
12

13
int data;
14
int endvorn=0;
15
int endhinten=0;
16
volatile int timer_zaehler=0;
17

18
static uint8_t Werte[] = {0b00001000,
19
              0b00001100,
20
              0b00000100,
21
              0b00000110,
22
              0b00000010,
23
              0b00000011,
24
              0b00000001};
25

26
int main()
27
{
28
  SPI_SlaveInit();  
29
  int0();    
30
  int1();
31
  DDRC= 0x0f;
32
  int i=0;
33
  while(1)
34
  {
35
    PORTC=0x00;      
36
    
37
    data = SPI_Exchange();
38
    
39
    //Vorwärts
40
    if (data>0)
41
    {  for (i=0;i<data;i++)
42
      {
43
        timer_init();
44
      }
45
    }
46
    
47
    //Rückwärts
48
    if (data<0)
49
    {  for (i=0;i>data;i--)
50
      {
51
        timer_init();
52
      }  
53
    }
54
    
55
    
56
    if (endhinten==1)//wenn eine endlage erreicht
57
    {
58
      SPDR=0x01;
59
      endhinten=0;
60
    }
61
    if (endvorn==1)
62
    {
63
      SPDR=0x01;
64
      endvorn=0;
65
    }
66
  }
67
}
68

69
int SPI_Exchange(void)
70
{
71
  
72
}
73

74
void SPI_SlaveInit(void)
75
{
76

77
}
78

79
void timer_init(void)
80
{
81
  OCR1A=24; //Prescaler 64 dh. ungefähr 1hz bei 3906
82
  TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);
83
  TIMSK |= (1<<OCIE1A);
84
  sei();  
85
}
86

87

88

89
void int0(void)
90
{        
91
  
92
}
93
void int1(void)
94
{
95
  
96
}
97

98

99
ISR(INT0_vect)
100
{   
101
}
102
ISR(INT1_vect)
103
{  
104
}
105
ISR(TIMER1_COMPA_vect)
106
{
107
  
108
  if (data>0)
109
  {  
110
    PORTC = Werte[timer_zaehler];
111
    timer_zaehler=timer_zaehler+1;
112
    if( timer_zaehler == 7 ){timer_zaehler = 0;}
113
    
114
    
115
  }
116
  if(data<0)
117
  {  
118

119
    if( timer_zaehler == 0 ){timer_zaehler = 7;}
120
    PORTC = Werte[timer_zaehler];
121
    timer_zaehler=timer_zaehler-1;
122
    
123
  }
124
}

Es läuft soweit nur leider hab ich eine endlosschleife und er fährt 
nicht meinen Übergebenen Wert dachte die for mit ihrem abbruch kriterium 
löst das für mich.
Gast #3862080
Lesenswert?

Ralf Svenson schrieb:
> schiebe den code mal ein.

Und welchen? Wieder mal nur das, was andere sehen sollen? Prima - guter 
Ansatz! Immerhin sind die Anregungen von Karl-Heinz ja wohl 
eingeflossen.

Von SPI war keine Rede, von anderen Interrupts auch nicht - und die 
werden auch noch "dunkel" gehalten. O.K., viel Spaß noch ...
#3862105
Lesenswert?

Okay ich weiss nicht was das Problem der latend aggresiven Stimmung ist 
aber keine Sorge der Rest Funktioniert einwandfrei.

Ich wollte abfragen ob der SPI negativ ist was auch funktioniert.
und dann eben so oft die init() aufrufen wie sie gebraucht wird laut 
Übergabewert.

Der Code läuft mit einem Delay ohne Probleme natürlich leicht 
abgeändert.

Aber ich brauche eben einen Interrupt da der zuverlässiger läuft.
Gast #3862114
Lesenswert?

Ralf Svenson schrieb:
> Aber ich brauche eben einen Interrupt da der zuverlässiger läuft

Zuverlässiger - sind die denn renitent? Da musst Du Dir wohl 
erzieherische Maßnahmen überlegen!

Ralf Svenson schrieb:
> Der Code läuft mit einem Delay ohne Probleme natürlich leicht
> abgeändert.

Klar, damit kann hier jeder Kaffeesatz-Leser etwas anfangen.

Ich trinke selten Kaffee - aber kein Problem, ich schlachte eine Ziege 
und schaue mal, was die Innereien so sagen ...
Gast #3862188
Lesenswert?

Na da gibt's 2 Möglichkeiten. Entweder du setzt ein flag bei dem 
Erreichen der 12 Durchläufe, welches du vorab abfragst. Oder du stellst 
die Interrupt Routine einfach mit cli() wieder ab
Gast #3862192
Lesenswert?

Karl Heinz schrieb:
> wenn man ein bischen besser in C drauf ist, dann realisiert man auch,
> dass man die if-Orgie durch ein Array ersetzen kann

Da bist du aber auch nicht so fit im eleganten Code...
1
ISR(TIMER1_COMPA_vect)
2
{
3
  timer_zaehler++;
4
  timer_zaehler = timer_zaehler % 7;
5

6
  int LEDs = 1;
7
  for(int i = 0; i<timer_zaehler; i++)
8
    LEDs = LEDs * 2;
9

10
  PORTC = LEDs;
11
}
(Firma: Vescomp) #3864035
Lesenswert?

jz schrieb:
> Da bist du aber auch nicht so fit im eleganten Code...
1
> ISR(TIMER1_COMPA_vect)
2
> {
3
>   timer_zaehler++;
4
>   timer_zaehler = timer_zaehler % 7;
5
> 
6
>   int LEDs = 1;
7
>   for(int i = 0; i<timer_zaehler; i++)
8
>     LEDs = LEDs * 2;
9
> 
10
>   PORTC = LEDs;
11
> }

 Du aber auch nicht.
 Wenn schon elegant, dann vielleicht so:
1
ISR(TIMER1_COMPA_vect)
2
{
3
  if (PORTC < 0x80) PORTC <<= 1; else PORTC = 1;
4
}
(Firma: Vescomp) #3864112
Lesenswert?

Thomas Eckmann schrieb:
> Aber nur vielleicht. Es sei denn, es würde auch funktionieren. Daran
> ändert 0x80 auch nichts.

 Es funktioniert, keine Sorge.
 Selbst wenn PortC am Anfang nicht initialisiert ist, dauert es
 höchstens 6 ISR Aufrüfe bis alles stimmt.
 Und sollte PortC am Anfang auf 0x00 stehen und nicht auf irgendeinen
 Wert gesetzt werden, dann sollte der TO sich ein anderes Hobby suchen
 oder folgende Zeile am Programmstart einfügen:
1
 PORTC = 1;

 oder die Zeile in der ISR so ändern:
1
if ((PORTC <> 0) && (PORTC < 128)) PORTC <<= 1; else PORTC =1;

 Falls es das war, was du (ziemlich ungeschickt)
 andeuten wolltest.
#3864122
Lesenswert?

Ich empfehle allen, inklusive jz, mal einen Blick ins Eröffnungsposting 
zu werfen, welche Bitmuster eigentlich auszugeben sind.
Zugegeben. Es gibt vom TO mindestens 3 unterschiedliche 'Bemusterungen', 
2 in Codeform und 1 in beschriebener Form.
Solange nicht klar ist, was da jetzt eigentlich wirklich gilt, ist es 
müssig über "elegant" zu streiten. Mit Arrays kann man jedes beliebige 
Muster erreichen, einfach nur in dem man die Musterbytes gegen andere 
austauscht. Insofern ist das für mich die eleganteste Methode. Ist man 
nur auf das Durchschieben von Bits aus, dann gibt es natürlich was 
eleganteres.

Nur über eines bin ich mir sicher. Das hier
1
  int LEDs = 1;
2
  for(int i = 0; i<timer_zaehler; i++)
3
    LEDs = LEDs * 2;
ist definitiv nicht elegant. Den völlig sinnlos in 16 Bit Arithmetik zu 
treiben, ist nicht elegant. Da wäre ein
1
  uint8t LEDs = 1 << timer_zaehler;
noch eleganter gewesen bzw. überhaupt gleich ein
1
  PORTC = 1 << timer_zaehler;
bzw. überhaupt gleich ein Schieben von timer_zaehler, bzw. (wie Marc 
anmerkt) gleich ein schieben des Ports bzw. bzw.
Gast #3864135
Lesenswert?

Ralf Svenson schrieb:
> Okay ich weiss nicht was das Problem der latend aggresiven Stimmung ist
> aber keine Sorge der Rest Funktioniert einwandfrei.

Das ist hier wie beim Hahnenkampf. Es geht vorrangig nicht um die Hilfe
für den Fragesteller, sondern um Blenden, Fetzen und Selbstdarstellen
von Leute, die sich für die weltbesten Programmierer halten.


Gehe nicht darauf ein, bedanke Dich für sinnvolle Postings, überlies
Schwachsinn und Provokationen. Das ist hier die beste Vorgehensweise.
#3864146
Lesenswert?

Heizgals schrieb:
> Ralf Svenson schrieb:
>> Okay ich weiss nicht was das Problem der latend aggresiven Stimmung ist
>> aber keine Sorge der Rest Funktioniert einwandfrei.
>
> Das ist hier wie beim Hahnenkampf.

nein.
Es geht nicht zu wie beim Hahnenkampf.
Es geht hier darum, dass jemand etwas bauen will, aber nicht das dazu 
notwendige Minimalwissen hat.

Das ist wie in den Alpen. Da gibt es die einen, die gelernt haben sich 
in den Bergen zu bewegen und es gibt die anderen, die von all dem nichts 
wissen. Es sind regelmässig letztere, die in ihren Halbschühchen und 
unzureichender Ausrüstung im absehbaren Schlechtwetter von der 
Bergrettung vom Berg geholt werden müssen.
Mit einem kleinen Unterschied: Wenn sie dann im Hubschrauber sitzen, 
sind die wenigstens kleinlaut und sehen ein, dass sie Mist gebaut haben 
und es doch nicht so verkehrt gewesen wäre, auf die Einheimischen zu 
hören und erst mal im Klettergarten unter Anleitung wenigstens die 
Grundlagen zu lernen.
Gast #3864150
Lesenswert?

Karl Heinz schrieb:
> Das ist wie in den Alpen. Da gibt es die einen, die gelernt haben sich
> in den Bergen zu bewegen und es gibt die anderen, die von all dem nichts
> wissen. Es sind regelmässig letztere, die in ihren Halbschühchen und
> unzureichender Ausrüstung im absehbaren Schlechtwetter von der
> Bergrettung vom Berg geholt werden müssen.

Das ist nicht das richtige Argument. Ich sage: Es ist für Frauen
bequemer mit hochhackigen Schuhen steile Berge zu erklimmen, da sich der
Fuß dabei immer in der Horizontalen befindet.

SCNR
;-)
Gast #3864541
Lesenswert?

Karl Heinz schrieb:
> Es geht hier darum, dass jemand etwas bauen will, aber nicht das dazu
> notwendige Minimalwissen hat.

Nö - es geht hier darum, dass viele ihren Senf zu etwas geben, wozu der 
TO sich nur zurückhaltend äußert ... vielleicht aus gutem Grund.

Und ... Hahnenkampf ist gar nicht mal so weit hergeholt :-), wenn man 
den Thread so liest ...

Zielführend muss nicht immer besonders "elegant" sein und es muss auch 
nicht mit möglichst wenigen Befehlen erreicht werden. Schön, dass ihr 
alle solche C-Profis abgebt - ich bin Anfänger und ziehe einfache, 
nachvollziehbare Lösungen vor :-)

Ja - von mir kommt keine Lösung - aber ich kann da sowieso nicht 
mithalten ...
#3864551
Lesenswert?

Versteher schrieb:
> Karl Heinz schrieb:
>> Es geht hier darum, dass jemand etwas bauen will, aber nicht das dazu
>> notwendige Minimalwissen hat.
>
> Nö - es geht hier darum, dass viele ihren Senf zu etwas geben, wozu der
> TO sich nur zurückhaltend äußert ... vielleicht aus gutem Grund.

Nö.
Seine main() ist ziemlicher Unsinn.
Das sollte eigentlich jeder sehen können, der mit dem Begriff 
'Initialisierung' wenigstens ein bischen was anfangen kann.

Wer sowas schreibt
1
...
2
    data = SPI_Exchange();
3
    
4
    //Vorwärts
5
    if (data>0)
6
    {  for (i=0;i<data;i++)
7
      {
8
        timer_init();
9
      }
10
    }
11
...
12

13
void timer_init(void)
14
{
15
  OCR1A=24; //Prescaler 64 dh. ungefähr 1hz bei 3906
16
  TCCR1B=(1<<CS10)|(1<<CS12)|(1<<WGM12);
17
  TIMSK |= (1<<OCIE1A);
18
  sei();  
19
}
20
...

hat nicht nur ein paar Kleinigkeiten nicht verstanden oder ein paar 
blöde Fehler gemacht. Sondern da fehlt es weit.
Zu seiner Ehrenrettung kann man höchstens noch sagen, dass keineswegs 
der Einzige ist, der denkt, er könne sich zur Tour de France anmelden, 
obwohl er noch gar nicht mit Stützrädern ordentlich radfahren kann. 
Erleben wir hier jede Woche x-mal.
#3864606
Lesenswert?

Versteher schrieb:
> Karl Heinz schrieb:
>> Tour de France
>
> Guter Vergleich :-) - der TO will ein paar
>
> Ralf Svenson schrieb:
>> leds der eihe nach
>> leuchten lassen
>
> Das ist nicht unbedingt "high sophisticated" - oder?

Richtig. Das ist nicht "high sophisticated".
Umso schlimmer ist der Unsinn, den er da zusammenkopiert hat. Denn wenn 
er ein paar einfache Grundlagen beherrschen würde, dann würde er das 
hinkriegen. Eben weil es nicht 'high sophisticated' ist.
Denn letzten Endes ist es egal, ob es die Tour de France ist oder irgend 
ein Vorstadt-Hobby Rennen oder der Sonntag Nachmittag Ausflug. Wer noch 
nicht mal mit Stützrädern Fahrrad fahren kann, hat bei all dem nichts 
verloren.
Da hilft es dann auch nicht auf die loszugehen, die anmerken man möge 
doch bitte erst mal mit Stützrädern auf einem Übungsgelände anfangen, 
ehe man davon träumt am Wochenende eine Radtour zu machen. Aber wir 
kennen ja unsere regelmässigen Forums-Pappenheimer. Da können die 
Trauben nicht hoch genug hängen.
(Firma: Vescomp) #3864657
Lesenswert?

Versteher schrieb:
> Bist Du nicht immer der, der auch Anfängern Grundlagen vermittelt?

 LOL.
 Hat er ja versucht, dann kam einer auf die Idee mit "elegant", wobei
 sein geposteter Code alles andere als elegant war.
 Elegant, einfach und verständlich sind 3 paar Schuhe.

 Wenn er versucht, dem TO etwas verständlich zu erklären, heisst es:
 Es ist nicht besonders elegant.

 Wenn man es elegant versucht, heisst es:
Versteher schrieb:
> nicht mit möglichst wenigen Befehlen erreicht werden. Schön, dass ihr
> alle solche C-Profis abgebt - ich bin Anfänger und ziehe einfache,
> nachvollziehbare Lösungen vor :-)

 Was den nun ?
Gast #3864697
Lesenswert?

Karl Heinz schrieb:
> Versteher schrieb:
>> Karl Heinz schrieb:
>>> ein paar einfache Grundlagen
>>
>> Bist Du nicht immer der, der auch Anfängern Grundlagen vermittelt?
>
> Ja.
> Aber wo willst du hier anfangen?
> Da gibts nur eines: Projekt zurückstellen und ab ins Tutorial und mal
> die ersten Schritte lernen. C Buch kaufen und die ersten Grundlagen
> lernen.

O.K. - dann schreibt halt auf die Einstiegsseite, dass Anfänger hier 
nicht zu suchen haben!

Ist ja O.K., wenn hier Profis unter sich sind - muss man nur wissen ...
Gast #3864712
Lesenswert?

Marc Vesely schrieb:
> LOL.
>  Hat er ja versucht, dann kam einer auf die Idee mit "elegant", wobei
>  sein geposteter Code alles andere als elegant war.
>  Elegant, einfach und verständlich sind 3 paar Schuhe.
>
>  Wenn er versucht, dem TO etwas verständlich zu erklären, heisst es:
>  Es ist nicht besonders elegant.

Stichwort: Hahnenkampf.

Das ist das "lustige" an diesem Forum - es gibt immer Besserwisser - und 
dann schaukelt sich die Diskussion auf - ohne Rücksicht auf den TO.
Gast #3864725
Lesenswert?

Heizgals schrieb:

> Gehe nicht darauf ein, bedanke Dich für sinnvolle Postings, überlies
> Schwachsinn und Provokationen. Das ist hier die beste Vorgehensweise.

Als wenn der TO in der Lage wäre, den Sinngehalt von Postings zu 
erfassen und korrekt zu bewerten....

Wäre er das wirklich, bräuchte er hier keine derartigen Fragen zu 
stellen, sondern könnte seine trivialen Probleme selber lösen.
Gast #3864730
Lesenswert?

c-hater schrieb:
> Wäre er das wirklich, bräuchte er hier keine derartigen Fragen zu
> stellen, sondern könnte seine trivialen Probleme selber lösen.

Auf Dich habe ich ja geradezu gewartet - macht doch einfach das Forum zu 
und erzählt euch gegenseitig, wie kompetent ihr nicht vorhandene 
Probleme löst ...
(Firma: Vescomp) #3864740
Lesenswert?

Versteher schrieb:
> Ist ja O.K., wenn hier Profis unter sich sind - muss man nur wissen ...
 Sagt wer ?

Versteher schrieb:
> O.K. - dann schreibt halt auf die Einstiegsseite, dass Anfänger hier
> nicht zu suchen haben!
 Sagt wer ?

 Wenn man versucht, jemanden zu erklären, dass er mit einer LED etwas
 viel besser verstehen wird, dann wird man als überheblich angespuckt.

 Wenn man versucht, jemandem etwas verständlich zu erklären, dann wird
 sein Code als dumm und unelegant angespuckt.

 Und dann kommen auch Leute wie du, die dem TO nicht helfen, aber sonst
 an allem etwas auszusetzen haben.
 Deinen Namen in Unversteher ändern und still sein.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren