Forum: Compiler & IDEs Funktionsaufruf Funktioniert nicht richtig..warum?


von Kay U. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Gemiende,

arbeite schon seit einer Weile an diesem Cod und haben für eine paar 
Tagen angefangen ihn zu optimieren. Doch leider Funktioniert das nicht 
ganz so wie ich mir das gedachte habe.
Mein Gedanke dabei war mehrere Kleine Funktionen zuschreiben und nur die 
Variablen zu ändern ohne jedes mal alles neu zuschreiben.. aber Seht 
selbst.

Wenn ich nun die Funktionen aufrufe Passiert nichts bzw. ändert sich 
nix.
Verstehen nur noch nicht ganz warum. Vielleicht könnt ihr mir ja helfen.

Grüße Kay

von Karl H. (kbuchegg)


Lesenswert?

Nochmal zurück zur letzten funktionierenden Version und dann nicht alles 
auf einmal umbauen, sondern in kleinen Schritten. Teil für Teil.

Sowas kommt vor, dass man sich bei zuvielen Änderungen auf einmal 
irgendwo ein Eigentor geschossen hat. Wohl dem, der dann ein 
Versionskontrollsystem hat, oder Sicherungen von funktionierenden 
Versionen, auf die er zurück gehen kann und von der ausgehend die 
Transformation, diesmal in kleineren Schritten nochmal gemacht werden 
kann.


Unabhängig davon: sag mal. Ist dir das nicht zu blöd, da 27 uint8_t 
Variablen zu haben, die alle bis auf eine angehängte Ziffer gleich 
heißen? Also mir wär das zu blöd, weil es den Code unsinnigerweise 
aufbläht. Das Array ist schon lange erfunden und deine init Funktion 
würde isch dann so lesen.
1
// im Header File ...
2
#define NR_LEDS 27
1
...
2
3
uint8_t LED[NR_LEDS ];
4
uint8_t LED_OUTPUT[ 1 + NR_LEDS / 8];
5
6
void Variablen_Init(void)
7
{
8
  uint8_t i;
9
10
  //Reg 0x01 = MODE2 - set to 0xFF - noninverted logic state, open-drain
11
  MODE2 = 0x02;  
12
  
13
  // Set all Output of 0x00(0)
14
  for( i = 0; i < NR_LEDS; i++ )
15
    LED[i] = 0x00;
16
  
17
  //LED_OFF:
18
  LED_OFF = 0x00;
19
20
  //Reg 0x12 - Group PWM - Variablen
21
  GROUP_PWM = 0x00;
22
23
  //Reg 0x13 - Group Freq - Variablen
24
  GROUP_FREQ = 0x00;
25
26
  //Reg 0x14-0x17 - LED Output State Control - Variablen
27
  for( i = 0; i < 1 + NR_LEDS / 8; i+
28
    LED_OUTPUT[i] = 0xAA;
29
}

wesentlich kürzer. Und vor allen Dingen viel leichter auf eine andere 
Anzahl an Leds umzustellen. Und das betrifft nicht nur die Init 
Funktion. Von deinem jetzigen Code würden über den Daumen gepeilt rund 
2/3 aller Code Zeilen wegfallen.

: Bearbeitet durch User
von Kay U. (Gast)


Lesenswert?

Hehe.. da hast du recht. Sicherungen hab ich auch noch aber wollte quasi 
so hin bekommen. Ach das gute alte array. das sollte der nächste schritt 
sein.. Irgendwie vermehre ich mich da immer und aus im Studium hab ich 
noch nicht viel programmiert. Also mühsam ernährt sich das Erdferkel ;).

Danke schon mal für die schnelle Antwort und den Tip. Sind sonst noch 
sachen aufgefallen oder meinst du ich sollte einfach schritt für schritt 
nochmal rann gehen?

von Karl H. (kbuchegg)


Lesenswert?

Kay Ulbricht schrieb:
> Hehe.. da hast du recht. Sicherungen hab ich auch noch aber wollte quasi
> so hin bekommen.

Das einzige was mir auf die Schnelle aufgefallen ist ist, dass es 
zwischen der Adressierung des ersten IC und dem Start des 2.ten IC 
keinen TWI_Stop gibt.

> Danke schon mal für die schnelle Antwort und den Tip. Sind sonst noch
> sachen aufgefallen oder meinst du ich sollte einfach schritt für schritt
> nochmal rann gehen?

Wenn die fehlende Stop-Bedingung nicht das Problem ist - ja, würde ich 
tun. Auf die Schnelle ist nichts offensichtliches zu sehen (bis auf ein 
paar technische Feinheiten im Header File. Bei den Deklarationen der 
Variablen fehlt ein extern. Aber das bügelt der GCC-Linker für dich aus 
und sollte momentan nicht das Problem sein)
Auch hast du viele Dinge im Header File, die da gar nicht rein gehören, 
weil sie nichts damit zu tun haben, was main() von deinen Funktionen 
wissen muss um sie bedienen zu können. Aber auch die sind erst mal nicht 
das Problem

: Bearbeitet durch User
von Stefan E. (sternst)


Lesenswert?

Ein weiteres Problem ist das hier:
1
  while(1)
2
    {
3
      Variablen_Init();
4
      PCA9635();
5
...
6
    {
7
      ...
8
      LED0 = 0x20;
9
      LED1 = 0x33;
10
      LED2 = 0x20;
11
      LED11 = 0x42;
12
      PCA9635();
13
    }
14
...                
15
  }

von Kay U. (Gast)


Lesenswert?

In der tat ist das fehlende TWI_Stop nicht ganz so schlimm. Ja ist mir 
auch schon aufgefallen das ich recht viel im Header weglassen bzw anders 
schreiben kann. Das ist noch vom C Programmieren drin... Okay dann 
arbeite ich das ganze nochmal durch und schau mal obs dann will.

von Kay U. (Gast)


Lesenswert?

Ich glaube ich weiß was du meinst.. aber eine passende lösung hab ich 
grade nicht auf lagen.. :D

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Ein weiteres Problem ist das hier:


Umpf.
Da hast du recht. Das hab ich nicht gesehen bzw. bedacht.
Er verwendet ja get_keyshort (wahrscheinlich aus den PeDa Routinen)

D.h. die Outputs werden ganz kurz und einmalig bei Tastendruck gesetzt 
und im nächsten Schleifendurchlauf wieder gelöscht. Jep. da wird man 
nichts sehen. Das geht viel zu schnell, dass die LED kurz aufleuchten 
und wieder verlöschen.

von Karl H. (kbuchegg)


Lesenswert?

Kay Ulbricht schrieb:
> Ich glaube ich weiß was du meinst.. aber eine passende lösung hab ich
> grade nicht auf lagen.. :D

Na komm.
Das liegt doch auf der Hand. Die Initialisierung der Variablen aus der 
Hauptschleife raus.
Das solltest du dir sowieso angewöhnen. Eine normale Programmstruktur 
sieht so aus
1
void main
2
{
3
4
   Alle Initialisierungen
5
   dazu gehört die Initialisierung aller Port Register
6
   aber auch das einmalige Setzen von globalen Variablen
7
   auf ihre Erst-Werte
8
9
   sei();  // falls Interrupts benötigt werden
10
11
   while( 1 ) {
12
13
     Logik der Hauptschleife, wie zb Feststellung von Tastendrücken
14
     und entsprechende Reaktion darauf.
15
16
   }
17
}

alles was nach Initialisierung stinkt, findet VOR der Hauptschleife 
statt und nicht in ihr.

: Bearbeitet durch User
von Kay U. (Gast)


Lesenswert?

Ahh.. da muss ich zugeben das das mit den Tasten wir so oder so nach 
nicht wirklich geheuer ist.. Also da muss ich eh noch mal rann.. Die 
machen eher was sie wollen. Bin für Tipps dankbar :)

von Karl H. (kbuchegg)


Lesenswert?

Kay Ulbricht schrieb:
> Ahh.. da muss ich zugeben das das mit den Tasten wir so oder so nach
> nicht wirklich geheuer ist.. Also da muss ich eh noch mal rann.. Die
> machen eher was sie wollen.

Dann hast du zu viele Baustellen auf einmal.
Eins nach dem anderen.
Das ist einer der meist gemachten Fehler aller Anfänger: zu viele offene 
Baustellen. NIchts funktioniert und wenn die Baustellen dann immer mehr 
werden, dann verliert man den Überblick, welches Problem auf wessen 
Konto geht.

von Kay U. (Gast)


Lesenswert?

Quasi so:
1
...
2
/** Initzialisiere PCA9635 **/
3
4
    Variablen_Init();
5
    PCA9635();
6
    
7
    
8
/** Endlosschleife **/
9
10
  while(1)
11
  {
12
      
13
        
14
/** Write byte(s) to the slave **/
15
16
    if( get_key_short( 1<<KEY0 ))
17
    {
18
      PORTD = PORTD | ( 1<<PD5 );
19
      PCA9635();
20
    }
21
    if ( get_key_long( 1<<KEY0 ))
22
    {
23
      Variablen_Init();
24
      PCA9635();
25
      PORTD &= ~( 1<<PD5 );
26
    }
27
                
28
  }

?

von Karl H. (kbuchegg)


Lesenswert?

Kay Ulbricht schrieb:

> ?

genau


Wobei ich persönlich kein Freund von Short und Long-Tastendrücken bin. 
Ich hab lieber 2 getrennte Tasten. Da gibt es dann auch keine 
Diskrepanzen mit dem Thema "Wie lange muss ich eigentlich drücken, damit 
aus einem Short ein Long wird"

2 tasten, normales get_key_press und die Sache ist erst mal vom Tisch. 
Auf 1-Knopf Bedienung kann man immer noch umstellen, wenn alles fertig 
ist.


(und iirgendwo in deinen Init Funktionen muss sich noch ein sei() 
verstecken. Denn so wie es jetzt ist, ist die letzte Aktion in main() 
diesbezüglich ein cli(). Damit sind die Interrupts aber gesperrt.
Persönlich halte ich ebenfalls nicht viel davon, in den diversen xxxInit 
Funktionen einen sei() zu verstecken. Der darf ruhig und prominent die 
letzte Aktion in main() vor der Hauptschleife sein, wo ihn jeder sieht
1
void main()
2
{
3
   DDR.....
4
   init_xyz():
5
   init_abc();
6
7
8
   // jetzt gilts.
9
   // Alle Interrupts: Feuer frei
10
   sei();
11
12
   while( 1 ) {
13
14
     und arbeiten, arbeiten, arbeiten
15
     was so anliegt und was uns die Interrupts so zutragen
16
   }
17
}

Den sei() kann ich nicht übersehen und er steht an genau der einzig 
sinnvollen Stelle. Nämlich als letzte Aktion der Initialisierung, bevor 
die Hauptschleife beginnt.

von Kay U. (Gast)


Lesenswert?

Okay.. hab jetzt alles nochmal durch geschaut und umgebaut:
1
...
2
int main (void)
3
{
4
  cli();
5
  
6
/** Initzialisiere Ports **/
7
  
8
  port_init();
9
    
10
/** Configure debouncing routines **/
11
12
  KEY_DDR &= ~ALL_KEYS;                    // configure key port for input
13
  KEY_PORT |= ALL_KEYS;                    // and turn on pull up resistors
14
    
15
  TCCR0 = (1<<CS02)|(1<<CS00);                // divide by 1024
16
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms
17
  TIMSK |= 1<<TOIE0;                      // enable timer interrupt
18
    
19
/** Wait 1 second for POR **/
20
21
  _delay_ms(1000);
22
23
/** Initzialisiere RS232 **/
24
  
25
  uart_init();
26
27
/** Initzialisiere TWI Master Interface mit bitrate von 1000 Hz **/
28
29
  if (!TWIM_Init (1000))
30
    {
31
    printf ("Error in initiating TWI interface\n");
32
    while (1);
33
    }
34
    
35
/** Initzialisiere PCA9635 **/
36
37
    Variablen_Init();
38
    PCA9635();
39
    
40
    sei();
41
    
42
/** Endlosschleife **/
43
44
  while(1)
45
  {  
46
        
47
/** Write byte(s) to the slave **/
48
49
    if( get_key_press( 1<<KEY0 ))
50
    {
51
      PORTD = PORTD | ( 1<<PD5 );
52
      Full_Output();
53
      PCA9635();
54
    }
55
    if ( get_key_press( 1<<KEY1 ))
56
    {
57
      Variablen_Init();
58
      PCA9635();
59
      PORTD &= ~( 1<<PD5 );
60
    }
61
                
62
  }
63
return 0;
64
}

Die tasten sache Funktioniert jetzt nur leider nicht das die LEDs alle 
angehen.. :/

von Karl H. (kbuchegg)


Lesenswert?

Kay Ulbricht schrieb:

> Die tasten sache Funktioniert jetzt nur leider nicht das die LEDs alle
> angehen.. :/

Gegenfrage: hat das schon mal funktioniert?

Hintergrund: Ich kenn den PCA_irgendwas nicht. Von daher kann ich nicht 
sagen, ob dein rausschreiben von Bytes Sinn macht oder nicht.

von Karl H. (kbuchegg)


Lesenswert?

Moment
1
  //Erster TLC59116 Chip:
2
  TWIM_Start (PCA9635_ADD1, TWIM_WRITE);
3
4
  //Autoincrement ALL registers, start at reg 0 - we're initting
5
  TWIM_Write(AUTO_INCREMENT_ALL_REGISTERS);    //Write 0x80
6
7
  //Reg 0x00 = MODE1 - set to 0x80 - autoincrement enabled (this is readonly?), do not respond to subaddresses or allcall
8
  TWIM_Write(AUTO_INCREMENT_ALL_REGISTERS);    //Write 0x80

2 mal AUTO_INCREMENT setzen?
Das ist nicht logisch. Sicher, dass das stimmt?

: Bearbeitet durch User
von Kay U. (Gast)


Lesenswert?

Verstehe was du meinst.. aber vor dem Umbau hat das alles Funktioniert. 
Also mit Tasten lang und kurz drücken usw... Das sollte also stimmten 
aber ja der gedanke kam mir auch und ist auch mehr eine Lösung durchs 
testen entstanden...

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.