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
voidtimer_init(void)
2
{
3
OCR1A=200;//Prescaler 64 dh. ungefähr 1hz bei 3906
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.
Ralf Svenson schrieb:> {PORTC=0b00010001timer_zaehler=0;}
Sehr "spartanisch" - ein Semikolon nach der Zuweisung würde das
Rücksetzen des Zählers erlauben. Das da der Compiler nicht meckert ...
Timer habe ich erstmal gar nicht angeschaut ...
Bei genauerer Betrachtung:
Ralf Svenson schrieb:> void vor (20)
Interessant - und was soll das bewirken? Vielleicht bin ich zu sehr
Anfänger, aber das verstehe ich nicht ...
Ralf Svenson schrieb:> if (endhinten==0)
Aha, und wo wird "endhinten" gesetzt, gelöscht, etc.
Gibt es auch einen "kompletten" Code?
Ralf Svenson schrieb:> timer_init();
Der ist auch gut :-) Je nachdem, wie und wo Du
Ralf Svenson schrieb:> void vor (20)
aufrufst (so das denn in dieser Form funktioniert) setzt Du den Zähler
für den Timer zurück. In einer Sekunde (1 Hz) kann der MC viel
abarbeiten - da wird die ISR ggf. nie aufgerufen ...
????
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
elseif(timer_zaehler==1){PORTC=0b01100010;}
9
elseif(timer_zaehler==2){PORTC=0b00100010;}
10
elseif(timer_zaehler==3){PORTC=0b01010110;}
11
elseif(timer_zaehler==4){PORTC=0b00010010;}
12
elseif(timer_zaehler==5){PORTC=0b01000011;}
13
elseif(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
staticuint8_tWerte[]={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.
Ralf Svenson schrieb:> ich wollte gern den PORTC durschalten lassen und leds der eihe nach> leuchten lassen das muss aber genauer sein als mit einem normalen delay.
Wie genau muss es denn sein? Wenn ich da was von 1 Hz lese kann ich mir
das gar nicht vorstellen, dass delay() zu ungenau sein soll.
Ja das mit dem array ist auch eine gute idee ich wollte es eben nur
schnell auf die schnelle lösen.
timer_zaehler ist volatile.
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.
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.
>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.
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
voidint0(void);
8
voidint1(void);
9
voidSPI_SlaveInit(void);
10
intSPI_Exchange(void);
11
voidtimer_init(void);
12
13
intdata;
14
intendvorn=0;
15
intendhinten=0;
16
volatileinttimer_zaehler=0;
17
18
staticuint8_tWerte[]={0b00001000,
19
0b00001100,
20
0b00000100,
21
0b00000110,
22
0b00000010,
23
0b00000011,
24
0b00000001};
25
26
intmain()
27
{
28
SPI_SlaveInit();
29
int0();
30
int1();
31
DDRC=0x0f;
32
inti=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
intSPI_Exchange(void)
70
{
71
72
}
73
74
voidSPI_SlaveInit(void)
75
{
76
77
}
78
79
voidtimer_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
voidint0(void)
90
{
91
92
}
93
voidint1(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.
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 ...
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.
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 ...
der Initialisierer schrieb:> Ralf Svenson schrieb:>> so oft die init() aufrufen wie sie gebraucht wird>>> Wie oft willst du denn eine Init brauchen? Die brauchst du genau 1x...
Okay aber ab da fängt er ja an zu zählen ich möchte aber das er nach dem
durchlauf von z.b. 12 mal aufhört und erst dann wieder anfängt wenn er
wieder gebraucht wird.
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
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...
jz schrieb:> 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...
Und das soll jetzt eleganter sein?
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;elsePORTC=1;
Falls es das war, was du (ziemlich ungeschickt)
andeuten wolltest.
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
intLEDs=1;
2
for(inti=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
uint8tLEDs=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.
Marc Vesely schrieb:> Falls es das war, was du andeuten wolltest.
Nein das ist es nicht.
PORTC hat nur 7 Bit. C7 wird immer als 0 gelesen. Damit steht das dann
nach einem Durchlauf.
mfg.
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.
Marc Vesely schrieb:> Und auch mit 0x80 wird es funktionieren:
if ((PORTC != 0) && (PORTC <> 0x80)) PORTC <<= 1; else PORTC =1;
Nein, wird es nicht. Oder doch, mit einem Aussetzer.
Kopf ==>> Wand.
Marc Vesely schrieb:> Zufrieden ?
Nein.
Marc Vesely schrieb:> if ((PORTC != 0) && (PORTC < 0x40)) PORTC <<= 1; else PORTC =1;
PC6 ist Reset. Da läuft er zwar rüber aber die Anzeige bleibt auch
einmal dunkel.
1
if(PORTC<0x20)PORTC<<=1;elsePORTC=1;
Initialisiert wird das natürlich nur einmal am Anfang (PORTC = 1;)
mfg.
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.
Thomas Eckmann schrieb:> PC6 ist Reset. Da läuft er zwar rüber aber die Anzeige bleibt auch> einmal dunkel.
Manoman, bist du kleinlich.
Geschieden wegen seelischer Grausamkeit ?
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
;-)
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 ...
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
voidtimer_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.
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?
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.
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.
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 ?
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 ...
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.
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.
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 ...
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 einerLED 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.
Marc Vesely schrieb:> Deinen Namen in Unversteher ändern und still sein
Nur weil ich unbequem bin ?
Wo hast Du denn geholfen - außer den Kamm zu schwellen?