Forum: Mikrocontroller und Digitale Elektronik Probleme beim Multiplexen und Zählen


von Ulan (Gast)


Lesenswert?

Tagwohl miteinander!


vor einiger Zeit habe ich hier schon mal was gefragt und auch toll hilfe 
bekommen...also probiere ichs noch mal hier.

Ich habe folgende Situation:

Ich habe mir ein 7-Seg-ührchen gebastelt und möchte die zeit separat 
einstellen mittels 4 Tasten.

Hier mal den Code mit hoffentlich hilfreichem Kommentar (Probleme unten 
beschrieben):
1
#include "C8051F020.h"  //Header C8051F020
2
3
sbit S0 = P3^0; //Modus SetUp/Watch
4
sbit S1 = P3^1; //exit SetUp Digit_N
5
sbit S2 = P3^2; // Digit_N ++
6
sbit S3 = P3^3; //next Digit
7
8
//S_N bezeichnet hier einen Schalter
9
10
sbit muxSeg4 = P1^7;  //Pins fürs muxen, funktioniert tiptop...
11
sbit muxSeg3 = P1^6;
12
sbit muxSeg2 = P1^5;
13
sbit muxSeg1 = P1^4;
14
15
char digit1, digit2, digit3, digit4; //Stellen der 7Seg HH:MM
16
 
17
const char segCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  //7 Segment LookUpTable
18
19
char buttonVar;  //Variablen für "Flankenerkennung"
20
char varTasteS3;
21
22
/*---Funktionsprototypen-------------------*/
23
24
void init(void);                             
25
26
void setTimeDigit1(char *);
27
void setTimeDigit2(char *, char);
28
void setTimeDigit3(char *);
29
void setTimeDigit4(char *);
30
31
void multiplexing(char*, char*, char*, char*);
32
33
34
//Main-------------------------------------------------------------------------------------------------------
35
36
void main(void)
37
{
38
    /*----Init Variables------------------------------*/
39
   muxSeg1 = 0;
40
   muxSeg2 = 0;
41
   muxSeg3 = 0;
42
   muxSeg4 = 0;
43
44
   digit1 = 1;
45
   digit2 = 2;
46
   digit3 = 3;
47
   digit4 = 4;
48
49
   buttonVar = 0;
50
   varTasteS3 = 0;
51
52
   init();
53
54
   while(1)
55
   {
56
      if(S0==1) //solange S0 "high" ist, kann ich die Zeit einstellen 
57
      {
58
         char tasteS3;         //Flankenerkennung von S3, da sonst dauer prellung --> durchrattern
59
         tasteS3 = (S3 != 0);
60
         if(!tasteS3 && buttonVar)
61
         {
62
            varTasteS3 ++;  //wenn eine Flanke da ist, zählen
63
            muxSeg1=1;      //Segment 1 ein
64
            if(varTasteS3 < 5) 
65
            {
66
               if(varTasteS3 == 1)
67
               {
68
                  setTimeDigit1(&digit1);
69
               }
70
               else
71
               {
72
                  P5=segCode[digit1];  //P5 ist AnzeigePort
73
               }
74
               muxSeg1=0;
75
               muxSeg2=1;
76
               if(varTasteS3 >= 1)
77
               {
78
                  if(varTasteS3 == 2)
79
                  {
80
                     setTimeDigit2(&digit2, digit1);
81
                  }
82
               }
83
               else
84
               {
85
                  multiplexing(&digit1, &digit2, &digit3, &digit4);
86
               }
87
               muxSeg2=0;
88
               muxSeg3=1;
89
               if(varTasteS3 >= 2)
90
               {
91
                  if(varTasteS3 == 3)
92
                  {
93
                     setTimeDigit3(&digit3);
94
                  }
95
               }
96
               else
97
               {
98
                  multiplexing(&digit1, &digit2, &digit3, &digit4);
99
               }
100
               muxSeg3=0;
101
               muxSeg4=1;
102
               if(varTasteS3 >= 3)
103
               {
104
                  if(varTasteS3 == 4)
105
                  {
106
                     setTimeDigit4(&digit4);
107
                  }
108
               }
109
               else
110
               {
111
                  multiplexing(&digit1, &digit2, &digit3, &digit4);
112
               }
113
               muxSeg4=0;
114
            }
115
            else
116
            {
117
               varTasteS3 = 0;
118
            }
119
         }
120
         buttonVar = tasteS3; //"Speichern" der Flanke
121
      }
122
      else
123
      {
124
         while(S0==0)
125
         {
126
         multiplexing(&digit1, &digit2, &digit3, &digit4); //wenn S0 low dann zeit anzeigen
127
         }
128
      }
129
   }
130
}  
131
   //Funktionen------------------------------------------------------------------------------------------------
132
   
133
   /*---Systeminitialisierung--------------------------------------------*/
134
   void init(void)
135
   {   
136
      WDTCN = 0xDE;               //Watchdog disable (ermöglicht Debugging)
137
      WDTCN = 0xAD;
138
      P1MDOUT = 0x00;                 //Port1 als Ausgang definiert Segmente  
139
      P2MDOUT = 0x00;            //Port2 als Ausgang definiert
140
      P3MDOUT = 0x00;            //Port3 als Eingang definiert
141
      P74OUT   = 0x0C;                //Port5 als Ausgang definiert Zeit
142
      XBR2    = 0x40;              //Crossbar enable
143
   }
144
   
145
   /*---SetUp Digit1----------------------------------------------------*/
146
   void setTimeDigit1(char *digit1)
147
   {
148
      char buttonVar = 0;
149
      char tasteS2; 
150
     
151
         while(S1==0)
152
         {
153
            tasteS2 = (S2 != 0);
154
            if(!tasteS2 && buttonVar)
155
            {
156
               *digit1 = *digit1 + 1;
157
               P5=segCode[*digit1];
158
            }
159
               if(*digit1==2)
160
               {
161
                  *digit1 = 0;
162
               }
163
            buttonVar = tasteS2;
164
         }
165
}
166
/*---SetUp Digit2---------------------------------------------------*/
167
void setTimeDigit2(char *digit2, char digit1)
168
{
169
170
   char buttonVar = 0;
171
   char tasteS2;
172
173
      while(S1 == 0)
174
      {
175
         tasteS2 = (S2 != 0);
176
         
177
         if(!tasteS2 && buttonVar)
178
         {
179
            switch(digit1)
180
            {
181
             case 0||1 :
182
               *digit2 = *digit2 + 1;
183
               if(*digit2 > 9)
184
               {
185
                  *digit2 = 0;
186
               }
187
               break;
188
             case 2 :
189
               *digit2 = *digit2 + 1;
190
               if(*digit2 >2)
191
               {
192
                  *digit2 = 0;
193
               }
194
               break;
195
            }
196
            P5 = segCode[*digit2];
197
         }
198
         buttonVar = tasteS2;
199
      }
200
}
201
202
/*---SetUp Digit3------------------------------------------------------*/
203
void setTimeDigit3(char *digit3)
204
{
205
   char buttonVar = 0;
206
   char tasteS2;
207
208
      while(S1 == 0)
209
      {
210
         P5=segCode[*digit3];  
211
         tasteS2 = (S2 != 0); 
212
         if(!tasteS2 && buttonVar)
213
         {   
214
            P5 = segCode[*digit3];
215
            *digit3 = *digit3 + 1;
216
            if(*digit3 > 5)
217
            {
218
               *digit3 = 0;
219
            }
220
         }
221
         buttonVar = tasteS2; 
222
      }  
223
}
224
225
/*---SetUp Digit4------------------------------------------------------*/
226
void setTimeDigit4(char *digit4)
227
{
228
   char buttonVar = 0;
229
   char tasteS2;
230
231
      while(S1 == 0)
232
      {
233
         P5=segCode[*digit4]; 
234
         tasteS2 = (S2 != 0); 
235
         if(!tasteS2 && buttonVar)
236
         {   
237
            P5 = segCode[*digit4];
238
               *digit4 = *digit4 + 1;
239
               if(*digit4 > 9)
240
               {
241
                  *digit4 = 0;
242
               }
243
         }
244
         buttonVar = tasteS2; 
245
      }  
246
} 
247
248
/*---Multiplexing der Anzeige-------------------------------*/
249
void multiplexing(char *digit1, char *digit2, char *digit3, char *digit4)
250
{
251
   muxSeg1 = 1;
252
      P5 = segCode[*digit1];
253
         muxSeg1 = 0;
254
255
   muxSeg2 = 1;
256
      P5 = segCode[*digit2];
257
         muxSeg2 = 0;
258
259
   muxSeg3 = 1;
260
      P5 = segCode[*digit3];
261
         muxSeg3 = 0;
262
263
   muxSeg4 = 1;
264
      P5 = segCode[*digit4];
265
         muxSeg4 = 0;
266
}



Was Funktioniert:

Alle Funktionen der einzelnen Digits laufen alleine tiptop
muxen geht auch

Was nicht Funktioniert:

Die Einstellbarkeit der einzelnen Digits ist mehr oder weniger Zufall, 
einmal gehts gut, ein anderes mal nicht --> Anzeige von falschen werten 
oder nicht einstellen können

Auch möchte ich immer alle Digits durch muxen, damit die ganze Zeit 
während des Einstellprozedere angezeigt wird und nicht nur das aktuelle 
Digit.

Ich komm einfach nicht darauf was das Problem ist und sehe im Moment 
auch nix mehr (wenn ihr wisst was ich meine...).

Falls jemand einen Vorschlag hat, wie ich das ganze sauber in kriege 
(ohne interrupts oder dergleichen (hab ich noch nicht ganz drauf und 
will es erst ohne machen)) nur her damit.

Falls was unklar ist, versuche ich lieben gerne zu erklären!


Dank euch schon mal und Gruss mit rauchendem Kopf

Ulan

von Jens (Gast)


Lesenswert?

So wie ich das sehe, hast du die Tasten nicht entprellt. Bau bei der 
Tastenabfrage mal eine Wartezeit mit ein, vielleicht hilft das.
Gruß

von Falk B. (falk)


Lesenswert?

@  Ulan (Gast)

>Ich habe mir ein 7-Seg-ührchen gebastelt

Kaum. Eine Uhr hat was mit genauer Zeit zu tun und dafür braucht man 
einen Timer. Den sehe ich bei dir nicht.

>Hier mal den Code mit hoffentlich hilfreichem Kommentar (Probleme unten
>beschrieben):

Lies mal was über Netiquette. Lange Quelltexte gehören in den 
Anhang.

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:
> @  Ulan (Gast)
>
>>Ich habe mir ein 7-Seg-ührchen gebastelt
>
> Kaum. Eine Uhr hat was mit genauer Zeit zu tun und dafür braucht man
> einen Timer. Den sehe ich bei dir nicht.

@TO
zusätzlich ist dieser Timer dann auch noch für das Multiplexen 
zuständig.
Dein Multiplexen ist unsinnig. Die einzelnen Digits werden reihum bei 
jedem Aufruf der Timer-ISR eins nach dem anderen durchgeschaltet. Das 
die Anzeige gemultiplext ist, darf in der Hauptschleife überhaupt nicht 
bemerkbar sein. Das erledigt der Timer mit seiner ISR komplett 
eigenständig im Hintergrund.

Dein Code ist nett (na ja) erfordert aber einen Komplettumbau. So wie er 
jetzt ist, kommst du nicht weiter. Der ganze Ansatz ist nicht geeignet.

Aber eins nach dem anderen. Erst mal brauchst du einen Timer samt 
Interrupt Service Routine (ISR)

von MaWin (Gast)


Lesenswert?

Für mich sieht das Programm weitestgehend nach falschem Ansatz aus.
Wieso sollte man die Zeit nicht per Multiplex darstellen, während der 
Benutzer auf die Knöpfe drückt ?
Warum so unsäglich viel Code für so eine simple Aufgabe ?
Warum so fehlerhaft programmiert, daß Tasten nicht in Zeitabständen 
grösser als Prellen kleiner als Reaktionszeit abgefragt werden, also 
z.B: während des Multplexens ?

Es gibt hunderte Application Notes wie man Uhren baut, z.B. von 
Microchip, warum guckst du nicht einfach vorher in so was rein ?

http://www.google.de/#hl=de&sclient=psy-ab&q=microchip+appnote+clock&oq=microchip+appnote+clock&aq=f&aqi=&aql=&gs_nf=1&gs_l=hp.3...668.5371.0.5490.23.22.0.1.1.0.397.3243.0j15j3j1.20.0.d0qFCWa7Bck&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&fp=d186524993104fa5

von Ulan (Gast)


Angehängte Dateien:

Lesenswert?

@ Jens

Jene welche zwingend entprellt sein müssen, sind es

@Falk


>>Ich habe mir ein 7-Seg-ührchen gebastelt
>
> Kaum. Eine Uhr hat was mit genauer Zeit zu tun und dafür braucht man
> einen Timer. Den sehe ich bei dir nicht.

Ja ich weiss, die ganze Zeitrechnung ist eine andere Sache. Die 
Funktioniert auch tiptop. Der Code ist nur für das Einstellen der Zeit 
mittels der Hardware (Werte werden nachher übergeben und 
weiterverwendet).


>>Hier mal den Code mit hoffentlich hilfreichem Kommentar (Probleme unten
>>beschrieben):

>Lies mal was über Netiquette. Lange Quelltexte gehören in den
>Anhang.

Entschuldige bitte! Kann ich das noch ändern...oder Du?
Auf jeden Fall den Code nochmals als Anhang (wenns klappt)


Dank euch!

von Karl H. (kbuchegg)


Lesenswert?

Ulan schrieb:

> Ja ich weiss, die ganze Zeitrechnung ist eine andere Sache. Die
> Funktioniert auch tiptop. Der Code ist nur für das Einstellen der Zeit
> mittels der Hardware (Werte werden nachher übergeben und
> weiterverwendet).

?
Sag blos .... du brauchst für eine Uhr 2 Prozessoren

von Peter D. (peda)


Lesenswert?

Ulan schrieb:
> vor einiger Zeit habe ich hier schon mal was gefragt und auch toll hilfe
> bekommen...also probiere ichs noch mal hier.

Aber wie man sieht, hast Du davon rein garnichts gelesen und umgesetzt.

Was soll das?
Soll ich jetzt alles nochmal erzählen?


Peter

von Karl H. (kbuchegg)


Lesenswert?

Ah. Der Thread hier
Funktion in einer Funktion aufrufen [C]

jetzt erklärt sich auch, was mit "Funktion in einer Funktion aufrufen" 
gemeint war. Gesucht waren eigentlich Timer und Interrupt Funktionen.

von Ulan (Gast)


Lesenswert?

@Karl Heinz

>Sag blos .... du brauchst für eine Uhr 2 Prozessoren

Nein, natürlich nicht .... komplett bescheuert bin ich nicht ;-D

>Dein Code ist nett (na ja) erfordert aber einen Komplettumbau. So wie er
>jetzt ist, kommst du nicht weiter. Der ganze Ansatz ist nicht geeignet.

Danke (soweit es das na ja zulässt), meine Künste stecken noch in den 
Kinderschuhen | Babysocken

>Aber eins nach dem anderen. Erst mal brauchst du einen Timer samt
>Interrupt Service Routine (ISR)

hmm...ich würd's wirklich wirklich gerne ohne lösen...also die 
Zeiteinstellung (ist ja im Ansatz einfach)

@MaWin

>Warum so fehlerhaft programmiert, daß Tasten nicht in Zeitabständen
>grösser als Prellen kleiner als Reaktionszeit abgefragt werden, also
>z.B: während des Multplexens ?

Warum "so fehlerhaft" 80% funktioniert...son schmarrn kanns nicht sein, 
und sonst wüsste ich gerne warum


>Es gibt hunderte Application Notes

Danke aber meine Verständnis ist ein wenig beschränkt was Hersteller 
"AppNotes" anbelangt...bin kein Fachmann...


Dank euch schon mal

von Ulan (Gast)


Lesenswert?

@Karl Heinz

Ja, der Fred...

das hat sich mittlerweile erledigt, glaub ich...

von Karl H. (kbuchegg)


Lesenswert?

Ulan schrieb:

>>Aber eins nach dem anderen. Erst mal brauchst du einen Timer samt
>>Interrupt Service Routine (ISR)
>
> hmm...ich würd's wirklich wirklich gerne ohne lösen...also die
> Zeiteinstellung (ist ja im Ansatz einfach)

Einen Timer benutzen zu können gehört zum kleinen 1*1 der 
µC-Programmierung. Das ist wie Autoreifen wechseln zu wollen ohne einen 
Radmutternschlüssel zu benutzen. Wer Mechaniker werden will, muss mit 
einem Radmutternschlüssel umgehen können. Alle anderen fahren in die 
Werkstatt und bezahlen jemanden, der weiß wies geht.

Sorry. Aber so ist das nun mal. Wer ein Bild malen will, muss lernen mit 
Leinwand, Pinsel UND Farbe umzugehen.

> das hat sich mittlerweile erledigt, glaub ich...
Ziemlich offensichtlich nicht. Du hast nur das Problem so lange vor dir 
hergeschoben, bis es nicht mehr möglich ist, es zu ignorieren. Und dein 
Problem lautet: Wie schaffe ich es, dass eine bestimmte Funktionalität 
automatisch regelmässig ausgeführt wird. Und die Lösung dafür lautet: 
Timer + zugehöriger ISR.

von Ulan (Gast)


Angehängte Dateien:

Lesenswert?

Grüss euch!!

Sodala, nun hab ich den Code mal überarbeitet...jetzt funktioniert schon 
Mal viel mehr.

zwei kleine Probleme habe ich allerdings noch:

-Wenn ich das erste digit stelle, kann ich den Wert "0" nicht setzen und 
ich sehe echt nicht, warum das nicht geht...

-Wenn das erste digit "1" ist, kann ich das zweite digit stellen aber 
wenn digit1 == 2 ist, kann ich digit2 nicht stellen...

kann mir jemand sagen warum? ich debuge nun schon eine weile..werde aber 
nicht schlauer...

und am Rande noch:

Die kleinen Delays zwischendurch werden noch in eine Funktion gepackt ^^


falls sonst noch jemand etwas sieht bezüglich Optimierung OHNE timer und 
ISR einbau...her damit !! ;-D

----

@Karl Heinz

mir ist durchaus bewusst, dass timer und interrupts etwas essentielles 
sind...nur habe ich das Problem, das mir im Moment niemand das Zeug 
erklären kann (aus dem DS des uP werde ich nicht viel schlauer, da steht 
alles mögliche aber natürlich ohne Beispiel o. ä.).

Ich werd' mir die Sachen alsbald möglich reinziehn..versprochen :-)


Dank euch und Gruss

Ulan

von Karl H. (kbuchegg)


Lesenswert?

Ulan schrieb:

> mir ist durchaus bewusst, dass timer und interrupts etwas essentielles
> sind...nur habe ich das Problem, das mir im Moment niemand das Zeug
> erklären kann (aus dem DS des uP werde ich nicht viel schlauer, da steht
> alles mögliche aber natürlich ohne Beispiel o. ä.).
>
> Ich werd' mir die Sachen alsbald möglich reinziehn..versprochen :-)

Kleiner Einschub.
Die Zeit, die du hier aufgewendet hast, wäre in Timer+ISR besser 
investiert gewesen. Du hast hier Unmengen von Code für etwas, was sich 
in 2 Bildschirmseiten (wenn überhaupt) formulieren lässt, wenn man es 
richtig macht. Dazu gehört zb auch die Verwendung von Arrays für die 
einzelnen Digits. Denn dann brauchst du nicht 4 verschiedene Funktionen 
für die einzelnen Digits, sondern nur eine.
Oder anders ausgedrückt: Mach es richtig und 60% deines Codes löst sich 
im Nichts auf).
Drum geh ich auch auf den Code nicht weiter ein, sondern gebe ab an 
andere.

von Ulan (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb

> Die Zeit, die du hier aufgewendet hast, wäre in Timer+ISR besser
> investiert gewesen.

glaub ich dir gerne aber so hab ich wenigstens das andere noch ein wenig 
geübt...

> Du hast hier Unmengen von Code für etwas, was sich
> in 2 Bildschirmseiten (wenn überhaupt) formulieren lässt, wenn man es
> richtig macht.

ja, es ist eine Unmenge...aber kein Software-Entwickler ist perfekt von 
Himmel gefallen...oder etwa doch?

> Dazu gehört zb auch die Verwendung von Arrays für die
> einzelnen Digits.

Wie darf ich das jetzt verstehen? tip, beispiel, link?

> Oder anders ausgedrückt: Mach es richtig und 60% deines Codes löst sich
> im Nichts auf).

wie gesagt, ich habe C weder erfunden noch Erfahrung mit der Kelle 
gefressen.

> Drum geh ich auch auf den Code nicht weiter ein, sondern gebe ab an
> andere.

In Ordnung, ich hoffe, dass sich jemand anderes meiner erbarmt und danke 
Dir für Deine Beträge


Gruss

Ulan

von Karl H. (kbuchegg)


Lesenswert?

Ulan schrieb:

>> Dazu gehört zb auch die Verwendung von Arrays für die
>> einzelnen Digits.
>
> Wie darf ich das jetzt verstehen? tip, beispiel, link?
1
char digit1, digit2, digit3, digit4; //Stellen der 7Seg HH:MM

--->
1
char  digit[4];

Deine Funktionen setTimeDigit sind vom Prinzip her alle gleich. Da du 
die digits sowieso global hast, kannst du auch auf das Array gleich 
direkt zugreifen anstelle sie über die Argumentliste zu übergeben. Die 
Funktion muss nur wissen, welches digit (Nummer von 0 bis 3) gerade 
bearbeitet werden soll.

-> du kriegst EINE Funktion, die ein wenig aufwändiger ist, weil sie 
alle Sonderfälle für alle Digits können muss, dafür fallen dir aber 3 
andere Funktionen komplett weg. So viel Mehraufwand ist das aber nicht 
in dieser einen Funktion.

-> In Summe kommt weniger Code raus. Und zwar beträchtlich weniger.

PS: Ich würde auch nicht die digits einzeln einstellen lassen, sondern 
die Stunden und Minuten.
d.h. die Stunden laufen bei Tastendruck von 0 bis 23, die Minuten von 0 
bis 60. Ist für den Benutzer viel einfacher (und auch für dein 
Programm), wenn er sich nicht aus der Situation rausmanövrieren muss, 
dass er erst mal ein anderes digit in den erlaubten Bereich für ein 
2.tes digit bringen muss.
Um die Stunden von 19 auf 20 schalten zu können, muss er erst die 9 zu 
einer 0 machen, weil du (zu Recht) verhinderst, dass er die Zehner von 1 
auf 2 stellen kann, solange die Einer auf 9 steht.

Schau dir übliche kommerzielle Uhren an. Alle lassen die Minuten/Stunden 
als ganzes hochzählen und nicht die Zehner und Einer getrennt. Das hat 
schon seinen Grund, setzt allerdings einen funktionierenden Autorepeat 
auf den Tasten vorraus, wofür man sinnvollerweise wieder einen Timer :-) 
einsetzt. Und damit sind wir wieder am Ausgangspunkt.

von Ulan (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb

> Deine Funktionen setTimeDigit sind vom Prinzip her alle gleich. Da du
> die digits sowieso global hast, kannst du auch auf das Array gleich
> direkt zugreifen anstelle sie über die Argumentliste zu übergeben. Die
> Funktion muss nur wissen, welches digit (Nummer von 0 bis 3) gerade
> bearbeitet werden soll.

hmm wenn man es so betrachtet, macht das Sinn...werde das dann bei 
Version 2 machen :-)

> -> du kriegst EINE Funktion

Jap, ich sehe..

> PS: Ich würde auch nicht die digits einzeln einstellen lassen, sondern
> die Stunden und Minuten.

Da hast Du absolut recht, nur finde ich persönlich, dass sich so die 
Zeit viel schneller einstellen lässt (wenn man keinen repeat hat - so 
wie ich) da ich ja sonnst im schlimmsten Fall 59x drücken muss..

>Und damit sind wir wieder am Ausgangspunkt.

die Geschichte wiederholt sich ja bekanntlich ^^
Dann mach ich mich mal an die Timer ran, gehe ich hierzu richtig in der 
Annahme, dass es da keine grundlegende Theorie gibt, welche man sich zu 
Gemüte führen kann um mal einen Sinnvollen Überblick zu kriegen (ich 
programmiere auf dieser "Stufe" erst seit gut 6 Wochen ^^)?

Dank'schön für die Ausführung!

von Peter D. (peda)


Lesenswert?

Ulan schrieb:
> ja, es ist eine Unmenge...aber kein Software-Entwickler ist perfekt von
> Himmel gefallen...oder etwa doch?

Nein, aber es ist viel einfacher, wenn man schrittweise vorgeht.

- LED blinken mit Delay-Loop (1Hz)
- LED blinken mit Timeroverflow
- LED blinken mit Timerinterrupt
- ein Digit aus SRAM (1Byte) ausgeben mit Timerinterrupt
- alle 4 Digits (eins je Interrupt!) aus SRAM (4Byte) ausgeben mit 
Timerinterrupt
- Timer schneller machen (~400Hz), dann leuchten alle Digits 
gleichzeitig (fürs Auge)

Damit hast Du erstmal das Multiplex erschlagen und kannst es ablegen. 
D.h. Deine weitere Entwicklung beeinflußt es nicht mehr, es läuft ja 
vollkommen unabhängig von der Mainloop.
Dann erst gehts weiter:
- Funktion, um Ziffern in 7-segment zu wandeln
- Funktion, um Zahlen in Ziffern zu zerlegen
- Eine Variable in 1s Schritten hochzählen und anzeigen

usw.

Durch Dein völlig konfus verwursteltes Konstrukt kann keiner mehr 
durchsehen, Du daher auch nicht. Man muß eine Aufgabe immer in einzelne 
Schritte zerlegen, die sich nicht gegenseitig behindern.

Eine einmal fertiggestellte Funktion legt man ab und benutzt sie nur 
noch. Niemals wurstelt man darin die nächsten Aufgaben mit hinein.

Wer alles gleichzeitig entwickeln will, fällt auf die Nase, egal ob 
Anfänger oder Profi.


Peter

von MaWin (Gast)


Lesenswert?

> Warum "so fehlerhaft" 80% funktioniert...son schmarrn
> kanns nicht sein, und sonst wüsste ich gerne warum

Nein, du willst offenbar gar nichts gerne wissen,
sondern du willst es gemacht bekommen.

> Danke aber meine Verständnis ist ein wenig beschränkt
> was Hersteller "AppNotes" anbelangt...bin kein Fachmann...

Irgendwas ist bei dir mächtig schief gelaufen in der Schule,
du hast bis heute nicht verstanden, was "Lernen" ist,
vermtulich etwas schwieriges dem man besser aus dem Weg geht.

Viel Spass noch auf deinem weiteren Weg im Leben, mit
"geht zu 80%" wird dein Arbeitgeber nicht zufrieden sein,
dein Kunde erst recht nicht.

von Ulan (Gast)


Lesenswert?

@peda


>- LED blinken mit Delay-Loop (1Hz)
>- LED blinken mit Timeroverflow
>- LED blinken mit Timerinterrupt
>- ein Digit aus SRAM (1Byte) ausgeben mit Timerinterrupt
>- alle 4 Digits (eins je Interrupt!) aus SRAM (4Byte) ausgeben mit
>Timerinterrupt

jaha...da verstehe ich im Moment nur Bahnhof...wie gesagt, ich hab noch 
keine Ahnung von Timern

>Dann erst gehts weiter:
>- Funktion, um Ziffern in 7-segment zu wandeln
>- Funktion, um Zahlen in Ziffern zu zerlegen
>- Eine Variable in 1s Schritten hochzählen und anzeigen

glaube mir, das habe ich gemacht...schritt für schritt, so wie es sich 
gehört. das hier sind nur Probleme, welche beim "run-in" aufgetreten 
sind und folgerichtig beseitigt gehören.
das ganze zerlegen und rechnen der Zeit funktioniert tiptop.


>Durch Dein völlig konfus verwursteltes Konstrukt kann keiner mehr
>durchsehen, Du daher auch nicht.

Da muss ich Dir leider teilweise widersprechen...es wurde erst - und das 
gebe ich zu - verwurstelt, als ich das erste mal debugte nachdem ich die 
Funktionen zusammen gefügt hatte

@Mawin


>Nein, du willst offenbar gar nichts gerne wissen,
>sondern du willst es gemacht bekommen.

Was heisst gemacht bekommen...steht das irgendwo?
weiter führe ich gar nicht aus, kommt eh nur für'n Barsch zurück


>Irgendwas ist bei dir mächtig schief gelaufen in der Schule,
>du hast bis heute nicht verstanden, was "Lernen" ist,
>vermtulich etwas schwieriges dem man besser aus dem Weg geht.

welche qualifizierter Erguss an Menschenkenntnis und Freundlichkeit

>Viel Spass noch auf deinem weiteren Weg im Leben,

danke, da mach ich mir keine Sorgen

von Peter D. (peda)


Lesenswert?

Ulan schrieb:
> das ganze zerlegen und rechnen der Zeit funktioniert tiptop.

Dein Hauptproblem ist aber das Multiplexen in der Mainloop. Irgendwann 
wirst Du merken, daß es Dir die CPU-Leistung mit der Schöpfkelle 
auffrißt oder anfängt zu flackern.
Es gehört in den Timerinterrupt. Erst danach kann alles andere 
funktionieren.

Und hör auf, sinnlos mit Pointern um Dich zu schmeißen. Anfänger meiden 
doch sonst immer Pointer.


Peter

von Ulan (Gast)


Lesenswert?

@peda

>Dein Hauptproblem ist aber das Multiplexen in der Mainloop. Irgendwann
>wirst Du merken, daß es Dir die CPU-Leistung mit der Schöpfkelle
>auffrißt oder anfängt zu flackern.

Dessen bin ich mir bewusst, aber das lass ich momentan noch sein 
(versteh mich bitte nicht falsch) und konzentriere mich jetzt auf die 
digits

>Und hör auf, sinnlos mit Pointern um Dich zu schmeißen. Anfänger meiden
>doch sonst immer Pointer.

erschien mir als einfache Variante - akzeptiere aber gerne, dass es 
Schwachsinn ist...
Warum sollte ich die meiden...erscheint mir nicht all zu starker Tabak 
zu sein...oder beeinträchtigten die Dinger sonst etwas?


Dank Dir


Ulan

von Karl H. (kbuchegg)


Lesenswert?

Ulan schrieb:

>>Und hör auf, sinnlos mit Pointern um Dich zu schmeißen. Anfänger meiden
>>doch sonst immer Pointer.
>
> erschien mir als einfache Variante - akzeptiere aber gerne, dass es
> Schwachsinn ist...
> Warum sollte ich die meiden...erscheint mir nicht all zu starker Tabak
> zu sein...oder beeinträchtigten die Dinger sonst etwas?


Na dann erklär doch mal, warum du hier
1
void multiplexing(char *digit1, char *digit2, char *digit3, char *digit4)
Pointer übergibst.

Ohne dir zu nahe treten zu wollen: Das sieht so aus, als ob du einfach 
nach dem Schema vorgehst - Argumentliste, da müssen Pointer rein - 
fertig.

Vielleicht tue ich dir unrecht, aber ich hab nicht das Gefühl, dass du 
weißt was du hier tust.


Nicht falsch verstehen. Wir alle wissen, dass es am Anfang nicht leicht 
ist. Im Idealfall lernst du alles gleichzeitig und zu 100%. Das das 
nicht geht, wissen alle. Aber es gibt sinnvolle Reihenfolgen. Und es 
bringt auch nichts, wenn man zu früh mit einsatztauglichen Projekten 
anfängt. Ohne einen gewissen Grundstock wird das nämlich nichts.
Das ist wie bei allem anderen im Leben: Erst mal hat man eine Lernphase 
und macht Übungsstücke, die man danach getrost wegwerfen kann oder die 
in einer Vitrine landen. Sobald aber ein 'Kunde' im Spiel ist, sollte 
man schon einen gewissen Erfahrungsschatz haben.
Die ersten Übungsstücke in einer mechanischen Werkstatt sind 
Feilübungen, der klassische Winkel mit allem Drum und Dran. Und erst 
wenn man da durch ist, macht es Sinn das Erste mal ein benötigtes 
Ersatzteil für eine Maschine herzustellen.

von Peter D. (peda)


Lesenswert?

Ulan schrieb:
> Warum sollte ich die meiden

Weil das den Leser irritiert. Er wird versuchen, Deine Absicht dahinter 
zu ergründen und wird sie nicht finden.

Einen Pointer nimmt man um Code und Zeit zu sparen. Statt 100 Variablen 
übergibt man nur den Pointer auf das Array mit den 100 Variablen.

Oder wenn das Unterprogramm mehrere Variablen modifizieren muß, die 
nicht global sind.

Ansonsten bedeutet ein Pointer immer mehr Code, als die Variable direkt.


Peter

von Ulan (Gast)


Lesenswert?

@Karl Heinz

> Na dann erklär doch mal, warum du hier
1
void multiplexing(char *digit1, char >*digit2, char *digit3, char *digit4)
> Pointer übergibst.
>
> Ohne dir zu nahe treten zu wollen: Das sieht so aus, als ob du einfach
> nach dem Schema vorgehst - Argumentliste, da müssen Pointer rein -
> fertig.

Da hast Du soweit recht. Ich dachte mir, wenn ichs an anderen Orten auch 
so gemacht habe, mach ichs hier auch so...

> Vielleicht tue ich dir unrecht, aber ich hab nicht das Gefühl, dass du
> weißt was du hier tust.

Ja Dein Gefühl trübt Dich nicht ganz...ich weiss nicht mit 
hundert-prozentiger Sicherheit was ich tue, aber solange es 
funktioniert, ist es für mich vorerst in Ordnung (Hardware-nahe usw. 
kommt dann noch).

>Nicht falsch verstehen. Wir alle wissen, dass es am Anfang nicht leicht
>ist.

Gottseidank einer der es sagt...

>Und es bringt auch nichts, wenn man zu früh mit einsatztauglichen Projekten
>anfängt. Ohne einen gewissen Grundstock wird das nämlich nichts.

es muss ja nicht gleich auf Anhieb funktionieren, wenn mit der Zeit 
immer mehr richtig wird, habe ich persönlich viel mehr davon.

>Das ist wie bei allem anderen im Leben: Erst mal hat man eine Lernphase
>und macht Übungsstücke,

Du sagst es, ich habe auch diverse Ausbildungen hinter mir, ich kenne 
das.

>Sobald aber ein 'Kunde' im Spiel ist, sollte
>man schon einen gewissen Erfahrungsschatz haben.

Danke das ist klar. ich möchte ja meine "Uhr" nicht verkaufen...das ist 
nur für mich...oder eben die erwähnte Vitrine...den Schatz hab ich ja - 
nur (noch) nicht beim C-Programmieren

>Die ersten Übungsstücke in einer mechanischen Werkstatt sind
>Feilübungen, der klassische Winkel mit allem Drum und Dran.

musst Du mich daran erinnern ?! ;-D


Danke!

@peda

>Weil das den Leser irritiert. Er wird versuchen, Deine Absicht dahinter
>zu ergründen und wird sie nicht finden.

Ja ok, leuchtet ein wenn ichs hier im Forum poste...sonst ist mir das 
egal ob jemand anderes meinen Code lesen kann, den ich hier 
"dilettantisch" zur Übung schreibe oder nicht (Du verstehst was ich 
meine?)

>Einen Pointer nimmt man um Code und Zeit zu sparen. Statt 100 Variablen
>übergibt man nur den Pointer auf das Array mit den 100 Variablen.

So kenn ich das auch aus der Theorie


>Ansonsten bedeutet ein Pointer immer mehr Code, als die Variable direkt.

Aha...das hat mir bis jetzt keiner gesagt...wieder was gelernt!


Danke Dir!

von Peter D. (peda)


Lesenswert?

1
   4          void test( char x, char* y, char idata* z )
2
   5          {
3
   6   1        P0 = x;
4
   7   1        P1 = *y;
5
   8   1        P2 = *z;
6
   9   1      }
7
C51 COMPILER V5.02,  POINTER
8
            25/04/12  13:54:34  PAGE 2
9
10
ASSEMBLY LISTING OF GENERATED OBJECT CODE
11
12
13
             ; FUNCTION _test (BEGIN)
14
;---- Variable 'x' assigned to Register 'R7' ----
15
;---- Variable 'y' assigned to Register 'R1/R2/R3' ----
16
                                           ; SOURCE LINE # 4
17
                                           ; SOURCE LINE # 5
18
                                           ; SOURCE LINE # 6
19
0000 8F80          MOV     P0,R7
20
                                           ; SOURCE LINE # 7
21
0002 120000  E     LCALL   ?C?CLDPTR
22
0005 F590          MOV     P1,A
23
                                           ; SOURCE LINE # 8
24
0007 A800    R     MOV     R0,z
25
0009 E6            MOV     A,@R0
26
000A F5A0          MOV     P2,A
27
                                           ; SOURCE LINE # 9
28
000C 22            RET

1.
x als Wert: direkt R7 ausgeben

2.
y als generig Pointer: der Aufrufer muß 3 Register mit der 
Pointeradresse laden, Funktionsaufruf zum Pointer lesen, dann ausgeben

3.
z als memory specific Pointer:
nach R0 laden und indirekter Zugriff, dann ausgeben


Vermutlich hat durch den Funktionsaufruf Dein Multiplexen überhaupt erst 
funktioniert. Dessen Ausführungszeit bestimmt quasi die Leuchtdauer der 
LEDs. Der direkte Zugriff hätte nur ein ganz dunkles Glimmen bewirkt 
(1µs Leuchtdauer).


Peter

von Ulan (Gast)


Lesenswert?

@ Peda

Danke für Deine Antwort und entschuldige bitte meine späte Antwort...

hmm ASM hab ich leider keinen blassen Schimmer...

Das Thema hat sich sowieso erledigt. Die Uhr läuft ganz gut fürs erste 
(wenn auch nicht sonderlich genau) und ich befasse mich gerade mit 
timern und interrupts.


Danke nochmals an alle die mir hier so toll geholfen habe!
Echt stark hier!


beste Grüsse

Ulan

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.