Hallo, mein Atmega8(ohne quarz) beendet nach wenigen sec. seinen Programm. Wenn ich das Programm mittels Tastendruck start läuft es ganz normal los aber nach wenigen sec. stop es und läuft nicht weiter. Ich kann es dann neustarten über erneuten Tastendruck aber es passiert wieder das selbe nach wenigen sec. Wenn ich allerdings das Programmierttool AVR Dreagon angeschlossen habe dann läuft es ganz normal so wie es sollte. Gibt es hier für eine einfache erklärung oder ist das ein häuferes Problem? Wenn der schaltplan und Code benötigt wird, kann ich den gerne noch hinzufügen. Grüßle
Wie ist der Reset-Pin beschaltet? Wenn offen => versuch einen Pullup daran. Wie schaut die Stromversorgung aus? Hat der Chip noch seine 5V, wenn er "steht"?
@ Sören (Gast) >Wenn der schaltplan und Code benötigt wird, kann ich den gerne noch >hinzufügen. Dann tu das.
der Code ist etwas umfang reich. Also wäre gut wenn ihr mir sagen könntet welche stellen sinnvoll zu zeigen sind ;).
Hi Also, erst einmal, das Programm kann nicht nach ein paar Sekunden beendet werden. Ein Controller läuft immer. Nur eben nicht da, wo du glaubst. Ursachen gibt es dafür viele. Eine davon ist ein Interrupt mit einer nicht vorhandenen ISR. Ein Überlaufender Stack oder das Überschreiben des Stack durch indirekt adressierte Speicherzellen im SRAM. Finden tut man sowas, indem man den Code lesen kann und nicht einen Blick auf das Board wirft. Die Funktion oder Nichtfunktion liegt nun mal im Programm. Und wenn es ein paar Sekunden tut, was man erwartet, wird sich die Platine nicht umverdrahtet haben.... Deshalb, wenn du dein geheimes Programm nicht öffentlich stellen willst, wirst du wohl selber auf die Suche gehen müssen. Aber ein Tip: Wenn du schön modular programmiert hast, dann kannst du auch einzelne Funktionen nach und nach testen. Gruß oldmax
Kleb doch den Start-Knopf fest, dann müsste das Programm immer funktionieren.
Okay, dann stell ich die Frage dazu. Ist es ein Hardware oder ein Software Problem oder kann man das nicht so einfach sagen? Will ja nicht das ihr die arbeit für mich macht! Sonder wollte nur einen Tipp wie der von Linksammler.
Sören schrieb: > Okay, dann stell ich die Frage dazu. > > Ist es ein Hardware oder ein Software Problem oder kann man das nicht so > einfach sagen? Man kann es fast nie einfach so aus der hohlen Hand an irgendwas festmachen. Dazu sind die Möglichkeiten zu vielfältig. Da du aber scheinbar am Reset Pin nichts schlimmes veranstaltet hast, wird es wohl ein Software Problem sein. Kannst du ja mal ausprobieren. Lass einfach nur in einem Testprogramm eine LED blinken. Wenn die nach 2 Stunden immer noch vor sich hinblinkt, dann wird es wohl eher kein Hardware Problem sein. Dann könntest du mal dein Programm etwas "komplizierter" machen, indem du Teile von deinem Programm da reinpappst und vielleicht nur ein Subsystem aktivierst. Läuft der µC dann nach 20 Minuten noch? > der Code ist etwas umfang reich. wie kann der umfangreich sein und du erst jetzt drauf kommen, dass dein µC nach ein paar Minuten steht? Du solltest mal deine Entwicklungs- und Teststrategien überdenken.
:
Bearbeitet durch User
danke Oldmax, ich versuchs erstmal selber zu finden wenn ich gänzlich scheitere dann würde ich den Code mal rein geben oder zumindest teile davon. Geheim ist er nicht aber wollte euch nicht unnötig arbeit aufheimsen ;). Start-Knopf festkleben geht nicht hab ich schon versucht :D
@Sören (Gast) >Ist es ein Hardware oder ein Software Problem oder kann man das nicht so >einfach sagen? Du bist ein echter Schetzkekes! Wie soll man an hand deiner "Informationen" dazu eine gescheite Aussage machen? Wir können nicht hellsehen! >Will ja nicht das ihr die arbeit für mich macht! Sonder wollte nur einen >Tipp wie der von Linksammler. Siehe Fehlersuche.
Okay, hab das jetzt mit dem Blicken ausprobiert und siehe das selbst das will nicht mehr :/. Also nur wenn das Board mit der ISP verbunden ist gehts. Ich check jetzt nochmal das Board und den Code schritt für schritt und wenn ich nicht drauf komme würde ich ganz gerne nochmal auf euch zurück kommen und dann auch mit einer Ordentlichen fehler beschreiben mit Code, Schaltplan und vielleicht auch Schoki ;). Danke schon mal für die ersten Tipps!
Sören schrieb: > stop es und läuft nicht weiter Die Beschaltung sieht erstmal ok aus. Dann liegt es wohl am Programm. Also: Code zeigen. Was heisst läuft nicht weiter? Irgenwo ne Schleife die nicht abgebrochen wird?
Sören schrieb: > Okay, > > hab das jetzt mit dem Blicken ausprobiert und siehe das selbst das will > nicht mehr :/. Nur so als Sicherstellung. Mit: du ziehst den Programmer ab meinst du aber schon, dass du den Programmer vom Board abziehst und nicht einfach nur den Programmer vom PC abstöpselst aber ansonsten am Board lässt.
Ja genau ich lose das Flachbandkabel der ISP vom Board! Arbeite mich gerade durch. Hab jetzt alles auskommentiert und kommentiere es jetzt stück für stück wieder ein.
So jetzt hab ich es, hab gestern zum Spaß mal eine Funktion geschrieben mit zwei for schleifen (siehe unten). Die mag er scheinbar nicht so recht. Des weiteren hab ich noch die RS232 funktionen alle auskommentiert da ich sie der Zeit nicht benötige. Teste das ganze jetzt noch paar stunden und Optimieren den Code noch etwas und dann sollte das passen :)
1 | |
2 | void ALL_DIMM( void ) |
3 | {
|
4 | uint8_t i; |
5 | uint8_t j; |
6 | for ( i = 0x00; i <= 0xFF; i++ ) |
7 | {
|
8 | for ( j = 0; j <= 11; j++ ) |
9 | {
|
10 | Led[j] = i; |
11 | Led[j] = i; |
12 | Led[j] = i; |
13 | Led[j] = i; |
14 | Led[j] = i; |
15 | Led[j] = i; |
16 | Led[j] = i; |
17 | Led[j] = i; |
18 | Led[j] = i; |
19 | Led[j] = i; |
20 | Led[j] = i; |
21 | Led[j] = i; |
22 | |
23 | _delay_ms(50); |
24 | PCA9635(); |
25 | }
|
26 | }
|
27 | }
|
28 | void PCA9635( void ) |
29 | {
|
30 | uint8_t i; |
31 | |
32 | // First TLC59116 Chip:
|
33 | TWIM_Start( PCA9635_ADD1, TWIM_WRITE ); |
34 | // Autoincrement ALL registers, start at reg 0 - we're initting
|
35 | TWIM_Write( AUTO_INCREMENT_ALL_REGISTERS ); |
36 | // Reg 0x00 = MODE1 - set to 0x80 - autoincrement enabled (this is readonly?), do not respond to subaddresses or allcall
|
37 | TWIM_Write( Mode1 ); |
38 | //TWIM_Write( Mode1_1 );
|
39 | // Reg 0x01 = MODE2 - set to 0xFF - noninverted logic state, open-drain
|
40 | TWIM_Write( Mode2 ); |
41 | //TWIM_Write( Mode2_1 );
|
42 | |
43 | // output 0 - 5
|
44 | for( i = 0; i < 6; i++ ) |
45 | {
|
46 | TWIM_Write( Led[i] ); |
47 | }
|
48 | |
49 | // 2 not used outputs
|
50 | TWIM_Write( Led_off ); |
51 | TWIM_Write( Led_off ); |
52 | |
53 | // output 6 - 12
|
54 | for( i = 0; i < 6; i++ ) |
55 | {
|
56 | TWIM_Write( Led[6 + i] ); |
57 | }
|
58 | |
59 | // 2 not used outputs
|
60 | TWIM_Write( Led_off ); |
61 | TWIM_Write( Led_off ); |
62 | |
63 | // Reg 0x12 - Group PWM - should not matter
|
64 | TWIM_Write( Group_PWM ); |
65 | // Reg 0x13 - Group Freq - should not matter
|
66 | TWIM_Write( Group_Freq ); |
67 | |
68 | // Reg 0x14-0x17 - LED Output State Control - all 0xAA (output state for each LED = 0x2)
|
69 | for( i = 0; i < 4; i++ ) |
70 | {
|
71 | TWIM_Write( Led_output[i] ); |
72 | }
|
73 | TWIM_Stop(); |
74 | }
|
Sören schrieb: > Die mag er scheinbar nicht so recht. In welcher Form äussert sich das? > hab gestern zum Spaß mal eine Funktion geschrieben Diese zigmal wiederholte Zuweisung an Led[j] ist unnötig. Was wolltest du damit bezwecken?
Hast du ja völlig reicht :D. Hatte zuerst eine for schleife die nur den Hex wert geändert hat und da waren die zig aufrufe notwendig. Beim weiter rum spielen hab ich dann einfach nicht mehr nachgedacht würde ich sagen :D. Aber danke! Stimmt einfach die anderen Zuweisungen raus, das spart auch wieder was. Das äussert sich so das er nicht mehr reagiert. Bzw. der rest taster auch ohne funktiopn und wirkung ist. Das einzige was hilft ist Strom weg.
Sören schrieb: > Das äussert sich so das er nicht mehr reagiert. Bzw. der rest taster > auch ohne funktiopn und wirkung ist. Das einzige was hilft ist Strom > weg. Wieviel Strom verbraucht der Mega in diesem Zustand? Spannungsversorgung in der Strombegrenzung? Wird er evtl. Warm? => würde auf einen Latch-Up hinweisen. Da wäre der Rest der Schaltung dann interessant.
Sören schrieb: > Das äussert sich so das er nicht mehr reagiert. Wann werdet ihr endlich mal lernen, dass Variablendefinitionen bzw. die jeweiligen Datentypen integraler und wichtiger Bestandteil eines Programms ist.
@ Sören (Gast) >Teste das ganze jetzt noch paar stunden und Optimieren den Code noch >etwas und dann sollte das passen :) Jaja, klingt nach Berliner Flughafen . . . >void ALL_DIMM( void ) >{ > uint8_t i; > uint8_t j; > for ( i = 0x00; i <= 0xFF; i++ ) Das erzeugt eine Endlosschleife, denn die Laufbedingung ist IMMER wahr!
Sören schrieb: > uint8_t i; ... > for ( i = 0x00; i <= 0xFF; i++ ) Wann und wie wird diese Schleife wohl beendet?
> uint8_t i; > for ( i = 0x00; i <= 0xFF; i++ ) Da ein uint8_t unglaubliche Probleme damit hat, über 255 zu kommen, würde ich diese klassische Endlosschleife mal als Programmierfehler einstufen. Es darf nur eine Endlosschleife geben, und die sollte in main() sein, oder? Funktionen, die nie zurückkehren sind mir sehr suspekt..... In dem Schaltplan ist auch ein Bock Eine der LEDs wird wohl so nie leuchten. Edit: Viel zu spät abgesendet..... Aber besser spät, als gar nicht.
Karl Heinz schrieb: >Wann werdet ihr endlich mal lernen, dass Variablendefinitionen bzw. die >jeweiligen Datentypen integraler und wichtiger Bestandteil eines >Programms ist. Okay, gut kläre mich bitte auf wo mein fehler liegt. Falk Brunner schrieb: >Das erzeugt eine Endlosschleife, denn die Laufbedingung ist IMMER wahr! Hab jetzt geändert in for( i = 0x00; i < 0xFF; i++)... Aber jetzt hab ich doch das problem das ich nie die 0xFF erreiche. also mit anderen worten nie LED voll anschalte :/
Ulrich F. schrieb: >In dem Schaltplan ist auch ein Bock >Eine der LEDs wird wohl so nie leuchten. :D Du meinst die LED3? Da hast du in der tat recht. Auf der Platine ist sie richtig montiert ;).
Sören schrieb: > Hab jetzt geändert in for( i = 0x00; i < 0xFF; i++)... > Aber jetzt hab ich doch das problem das ich nie die 0xFF erreiche. http://www.c-howto.de/tutorial-schleifen-do.html
> Hab jetzt geändert in for( i = 0x00; i < 0xFF; i++)...
Vielleicht wäre eine Fußgesteuerte Schleife an der Stelle
praktischer....
Ulrich F. schrieb: > Ja, so ist das! > > Vielleicht der falsche Datentype? Und die Definition des Arrays würde ich auch gerne sehen. Wer sowas schreibt
1 | for ( j = 0; j <= 11; j++ ) |
dem traue ich nicht mehr über den Weg, bis ich mich davon überzeugt habe, dass in der Array-definition wirklich 12 und nicht 11 steht.
Ulrich F. schrieb: >Vielleicht der falsche Datentype? aber uint16_t dafür zu benutzen hab ich als bissel fett angesehen und dacht das von 0 ... 255 der uint8_t reicht. siehe auch: (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial)
Denk mal nach: Wie viele Werte kannst du mit dem uint8 darstellen. Und bei welchem (wievielten) Durchlauf soll die Abbruchbedingung wahr werden.
:
Bearbeitet durch User
Sören schrieb: > dacht das von 0 ... 255 der uint8_t reicht Dann muss du die Schleife aber z.B. so bauen:
1 | i = 0; |
2 | do
|
3 | {
|
4 | |
5 | }while(++i); |
Damit deine Abbruchbedingung erfüllt ist, muss i aber 256 annehmen.
:
Bearbeitet durch User
Karl Heinz schrieb: > Und die Definition des Arrays würde ich auch gerne sehen. > Wer sowas schreibt for ( j = 0; j <= 11; j++ ) > dem traue ich nicht mehr über den Weg, bis ich mich davon überzeugt > habe, dass in der Array-definition wirklich 12 und nicht 11 steht. Sören schrieb: > // output 0 - 5 > for( i = 0; i < 6; i++ ) > { > TWIM_Write( Led[i] ); > } und Sören schrieb: > // output 6 - 12 > for( i = 0; i < 6; i++ ) > { > TWIM_Write( Led[6 + i] ); > } spricht dafür, dass zumindest der Teil stimmt ;)
Okay, beim nächsten mal Lese ich mich nochmal richtig in die schleifen geschichte rein. Aber ich könnte auch mit dieser nicht wirklich gut geschriebenen schleife das rausbekommen was ich wollte und zwar ob man 255 Dimmstuffen hat und sieht. :D Danke für die Tipps und Hilfe!
Sorry, wenn ich jetzt mal in eine ganz andere Richtung denke: Der LED Driver hängt doch per I2C dran. Wahrscheinlich doch auch etwas weiter weg und per dünnen Äderchen verbunden? Kann es sein, dass der I2C Bus nicht sauber funktioniert. Wenn z.B. ein Acknowlegde nicht sauber kommt, kann es schon mal vorkommen, dass der Bus geklemmt bleibt und kann kommst Du nämlich auch nicht mehr per Prozessor-Reset raus ( weil ja der PCB9635 hängt und den I2C blockiert ). Dann musst Du nämlich den Strom abklemmen...
Pepe schrieb: > Der LED Driver hängt doch per I2C dran. Wahrscheinlich doch auch etwas > weiter weg und per dünnen Äderchen verbunden? > Kann es sein, dass der I2C Bus nicht sauber funktioniert. Wenn z.B. ein > Acknowlegde nicht sauber kommt, kann es schon mal vorkommen, dass der > Bus geklemmt bleibt und kann kommst Du nämlich auch nicht mehr per > Prozessor-Reset raus ( weil ja der PCB9635 hängt und den I2C blockiert > ). Dann musst Du nämlich den Strom abklemmen... Guter Gedanke, die Kabel sind recht "dick" und auch recht kurz also max. 6cm. Hab das signal amanfang mit dem Ozi überprüft da sah es sehr gut aus. :)
Sören schrieb: > ich wollte und zwar ob man > 255 Dimmstuffen hat und sieht. Eben sachtest du noch, dass dir 255 Stufen zu wenig sind.... Siehe: > Aber jetzt hab ich doch das problem das ich nie die 0xFF erreiche.
Ähh.. ich glaube das war etwas ungünstig ausgedrückt. Der PCA9635 hat 256 Stufen oder 8bit PWM und die würde ich ja schon gerne alle benutzen können :). Du meinst ich sehe der Zeit nur 254 Stuffen der Dimmung? Ja das stimmt! Aber ab einer gewissen Stufe sieht man mit dem Auge keine wirklichen unterschied mehr.
Bei PWM fehlt dir immer 1 Wert, je nach PWM Einstellung kannst du entweder ganz an also immer auf high aber dafür nie ganz auf low (bleibt immer ein Spike von einem Taktzyklus) oder eben ganz auf low aber dafür nie auf ganz high.
Felix C. schrieb: > Bei PWM fehlt dir immer 1 Wert, je nach PWM Einstellung kannst du > entweder ganz an also immer auf high aber dafür nie ganz auf low (bleibt > immer ein Spike von einem Taktzyklus) oder eben ganz auf low aber dafür > nie auf ganz high. Sachte. Das ist bei der im AVR implementierten PWM so. Beim PCA9635 (=LED Driver mit eingebauten PWM Stufen) ist das aber nicht so.
Karl Heinz schrieb: > Sachte. Das ist bei der im AVR implementierten PWM so. > Lies mal die Threadüberschrift...
:
Bearbeitet durch User
Felix C. schrieb: > Karl Heinz schrieb: >> Sachte. Das ist bei der im AVR implementierten PWM so. >> > Lies mal die Threadüberschrift... Der Atmega stoppt. Die PWM, um die es geht, kommt aber nicht von ihm, sondern von einem PCA, der per I2C angesteuert wird. Lies den Code.
:
Bearbeitet durch User
Sören schrieb: > Wenn ich allerdings das Programmierttool AVR Dreagon > angeschlossen habe dann läuft es ganz normal so wie es sollte. Wie ist der Drache angeschlossen? Versorgst du damit die Schaltung? Wenn ja, dann hast du ein Problem mit deiner Stromversorgung. Da tippe ich mal ganz fest drauf. Der Schaltplan sieht ja gut aus (bisschen dunkel ;-)), aber ist das auch wirklich so angeschlossen? Was ist das für eine Platine? Lochraster mit Fädeldraht? Such erstmal, wenn du vom Drachen den Strom nimmst und es damit funktioniert hat, nach dem Fehler in deiner Stromversorgung. Wenn nicht, dann guck mal, ob dein Reset Taster defekt ist.
Karl Heinz schrieb: > Felix C. schrieb: >> Karl Heinz schrieb: >>> Sachte. Das ist bei der im AVR implementierten PWM so. >>> >> Lies mal die Threadüberschrift... > > > Der Atmega stoppt. > Die PWM, um die es geht, kommt aber nicht von ihm, sondern von einem > PCA, der per I2C angesteuert wird. > Lies den Code. Wohl wahr, hätte ich machen sollen. Mein Fehler, sry!
Karl Heinz schrieb: > Sachte. Das ist bei der im AVR implementierten PWM so. und das auch nur, wenn man Fast PWM benutzt.
OK. Du hast oben geschrieben, dass es mit angestecktem Programmer durchläuft. Dann kannst Du ja nicht den Debugger anhalten, wenn's hängt. Aber Du kannst das Problem eingrenzen mit Deiner LED_MCU: ... Led[j] = i; Led[j] = i; _delay_ms(50); LEDEin(); PCA9635(); LEDAus(); } Dann kannst Du schon mal sagen, ob die I2C Ansteuerung hängt oder nicht. Ich würde auch auf Spannungsversorgung tippen. Vielleicht zieht Dein Programmer die VCC etwas nach oben und dann reicht der Pegel fürs I2C...
Noch was die zweite: Hast Du schon mal SDA bzw. SCL gemessen, wenn dein Programm hängt? Wenn eines der beiden auf LOW, treibt wohl einer den I2C. Du kannst in SDA / SCL jeweils einen 100R in Serie reinhängen. Dann kannst Du über den Spannungsabfall rausfinden, welcher der beiden I2C Partner den Bus klemmt.
So ich hab die LED im Schaltplan gedreht und alle andere sachen auch nochmal überarbeitet. Hier das abschliesende ergebnis. Tipps und Anregungen sind gerne gesehen :). Code: Main:
1 | #include <stdio.h> |
2 | #include <stdint.h> |
3 | #include <stdbool.h> // Variablentyp Bool |
4 | #include <avr/interrupt.h> // AVR Routinen for Interrupts |
5 | #include <avr/io.h> // AVR IO Header |
6 | |
7 | #include "General.h" |
8 | #include <util/delay.h> // AVR Timemanager |
9 | #include "TWI_Master.h" |
10 | #include "PCA9635.h" |
11 | #include "Taster.h" |
12 | |
13 | //#include "RS232.h"
|
14 | |
15 | //**************************
|
16 | //** Ports initialisieren **
|
17 | //**************************
|
18 | void port_init(void) |
19 | {
|
20 | // Pin 0 und 1 auf Eingang und andere im ursprünglichen Zustand belassen:
|
21 | DDRC = 0x03; //&= ~((1 << DDC0) | (1 << DDC1)); |
22 | // Pin 5 und 2 auf Ausgang und andere im ursprünglichen Zustand belassen:
|
23 | DDRD |= (1 << DDD5); |
24 | DDRC |= (1 << DDC2); |
25 | |
26 | // Pull Up von Pin 0 und Pin 1 setzen:
|
27 | PORTC = ( 1 << PC0 ) | ( 1 << PC1 ); |
28 | }
|
29 | //**********
|
30 | //** Main **
|
31 | //**********
|
32 | int main (void) |
33 | {
|
34 | cli(); |
35 | //
|
36 | /** Initzialisiere Ports **/
|
37 | |
38 | port_init(); |
39 | |
40 | /** Configure debouncing routines **/
|
41 | |
42 | KEY_DDR &= ~ALL_KEYS; // configure key port for input |
43 | KEY_PORT |= ALL_KEYS; // and turn on pull up resistors |
44 | |
45 | TCCR0 = (1<<CS02)|(1<<CS00); // divide by 1024 |
46 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms |
47 | TIMSK |= 1<<TOIE0; // enable timer interrupt |
48 | |
49 | /** Wait 1 second for POR **/
|
50 | |
51 | _delay_ms(1000); |
52 | |
53 | ///** Initzialisiere RS232 **/
|
54 | //
|
55 | //uart_init();
|
56 | //uart_puts("RS232 [OK]...");
|
57 | //
|
58 | /** Initzialisiere TWI Master Interface mit bitrate von 1000 Hz **/
|
59 | |
60 | TWIM_Init (1000); |
61 | |
62 | /** Wait 1 second for POR **/
|
63 | |
64 | _delay_ms(1000); |
65 | |
66 | if (!TWIM_Init (1000)) |
67 | {
|
68 | printf ("Error in initiating TWI interface\n"); |
69 | while (1); |
70 | }
|
71 | |
72 | /** Initzialisiere PCA9635 **/
|
73 | |
74 | Init_PCA9635(); |
75 | PCA9635(); |
76 | |
77 | sei(); |
78 | |
79 | ////uart_gets( Line, sizeof( Line ) );
|
80 | ////uart_puts( Line );
|
81 | ////uart_puts("Hello World");
|
82 | |
83 | |
84 | /** Endlosschleife **/
|
85 | |
86 | while(1) |
87 | {
|
88 | FullOn(); |
89 | PCA9635(); |
90 | _delay_ms(1000); |
91 | FullOff(); |
92 | PCA9635(); |
93 | _delay_ms(1000); |
94 | ALL_DIMM(); |
95 | _delay_ms(1000); |
96 | |
97 | /** Write byte(s) to the slave **/
|
98 | //
|
99 | if( get_key_press( 1<<KEY0 )) |
100 | {
|
101 | PORTD = PORTD | ( 1<<PD5 ); |
102 | //Led[9] = 0xFF;
|
103 | FullOn(); |
104 | PCA9635(); |
105 | //ALL_DIMM();
|
106 | /*
|
107 | for( i = 0; i < 16; i++ )
|
108 | {
|
109 | Led[i] = 0xFF;
|
110 | PCA9635();
|
111 | _delay_ms(3000);
|
112 | Led[i] = 0x00;
|
113 | }
|
114 | */
|
115 | }
|
116 | if ( get_key_press( 1<<KEY1 )) |
117 | {
|
118 | FullOff(); |
119 | PCA9635(); |
120 | PORTD &= ~( 1<<PD5 ); |
121 | }
|
122 | }
|
123 | return 0; |
124 | }
|
125 | |
126 | PCA9635.c: |
127 | #include <stdio.h> |
128 | #include <avr/interrupt.h> |
129 | |
130 | #include "General.h" |
131 | #include <util/delay.h> |
132 | #include "TWI_Master.h" |
133 | #include "PCA9635.h" |
134 | |
135 | void Init_PCA9635( void ) |
136 | {
|
137 | uint8_t i; |
138 | |
139 | // Reg 0x00 = MODE1 - set to 0x80 - autoincrement enabled (this is readonly?), do not respond to subaddresses or allcall
|
140 | Mode1 = 0b10000000; //Write 0x80 |
141 | |
142 | // Reg 0x01 = MODE2 - set to 0xFF - noninverted logic state, open-drain
|
143 | Mode2 = 0x1F; |
144 | |
145 | // LED_OFF:
|
146 | Led_off = 0x00; |
147 | |
148 | // Reg 0x12 - Group PWM - Variablen
|
149 | Group_PWM = 0xFF; |
150 | |
151 | // Reg 0x13 - Group Freq - Variablen
|
152 | Group_Freq = 0x00; |
153 | |
154 | // Reg 0x14-0x17 - LED Output State Control - Variablen
|
155 | for( i = 0; i < 4; i++ ) |
156 | {
|
157 | Led_output[i] = 0xAA; |
158 | }
|
159 | }
|
160 | |
161 | void FullOff( void ) |
162 | {
|
163 | uint8_t i; |
164 | // set all LEDs of 0x00 ( all off)
|
165 | for( i = 0; i < NR_LEDS; i++ ) |
166 | {
|
167 | Led[i] = 0x00; |
168 | }
|
169 | }
|
170 | |
171 | void FullOn( void ) |
172 | {
|
173 | uint8_t i; |
174 | // set all LEDs of 0xFF (Full On)
|
175 | for( i = 0; i < NR_LEDS; i++ ) |
176 | {
|
177 | Led[i] = 0xFF; |
178 | }
|
179 | }
|
180 | |
181 | void PCA9635( void ) |
182 | {
|
183 | uint8_t i; |
184 | |
185 | // First TLC59116 Chip:
|
186 | TWIM_Start( PCA9635_ADD1, TWIM_WRITE ); |
187 | // Autoincrement ALL registers, start at reg 0 - we're initting
|
188 | TWIM_Write( AUTO_INCREMENT_ALL_REGISTERS ); |
189 | // Reg 0x00 = MODE1 - set to 0x80 - autoincrement enabled (this is readonly?), do not respond to subaddresses or allcall
|
190 | TWIM_Write( Mode1 ); |
191 | //TWIM_Write( Mode1_1 );
|
192 | // Reg 0x01 = MODE2 - set to 0xFF - noninverted logic state, open-drain
|
193 | TWIM_Write( Mode2 ); |
194 | //TWIM_Write( Mode2_1 );
|
195 | |
196 | // output 0 - 14
|
197 | for( i = 0; i < NR_LEDS; i++ ) |
198 | {
|
199 | TWIM_Write( Led[i] ); |
200 | }
|
201 | |
202 | // 2 not used outputs
|
203 | TWIM_Write( Led_off ); |
204 | TWIM_Write( Led_off ); |
205 | |
206 | // Reg 0x12 - Group PWM - should not matter
|
207 | TWIM_Write( Group_PWM ); |
208 | // Reg 0x13 - Group Freq - should not matter
|
209 | TWIM_Write( Group_Freq ); |
210 | |
211 | // Reg 0x14-0x17 - LED Output State Control - all 0xAA (output state for each LED = 0x2)
|
212 | for( i = 0; i < 4; i++ ) |
213 | {
|
214 | TWIM_Write( Led_output[i] ); |
215 | }
|
216 | TWIM_Stop(); |
217 | }
|
218 | void ALL_DIMM( void ) |
219 | {
|
220 | uint16_t i; |
221 | uint16_t j; |
222 | for ( i = 0x00; i < 0xFF; i++ ) |
223 | {
|
224 | for ( j = 0; j < NR_LEDS; j++ ) |
225 | {
|
226 | Led[j] = i; |
227 | |
228 | _delay_ms(50); |
229 | PCA9635(); |
230 | }
|
231 | }
|
232 | }
|
233 | |
234 | PCA9635.h: |
235 | #ifndef PCA9635_H_
|
236 | #define PCA9635_H_
|
237 | |
238 | /**************************************
|
239 | ** TLC59116 device Address/Registers **
|
240 | ***************************************/
|
241 | |
242 | #define PCA9635_ADD1 0b0010101//0x60
|
243 | #define PCA9635_ADD2 0b0010111//0x61
|
244 | |
245 | |
246 | |
247 | // Control register (three MSB control auto-increment)
|
248 | #define NO_AUTO_INCREMENT 0x00
|
249 | #define AUTO_INCREMENT_ALL_REGISTERS 0x80
|
250 | #define AUTO_INCREMENT_BRIGHTNESS 0xA0
|
251 | #define AUTO_INCREMENT_CONTROL 0xC0
|
252 | #define AUTO_INCREMENT_BRIGHT_CONTROL 0xE0
|
253 | |
254 | // LED output state for LEDOUT0 to LEDOUT3
|
255 | #define LED_OUTPUT_OFF 0b00
|
256 | #define LED_OUTPUT_GROUP 0b11
|
257 | |
258 | #define NR_LEDS 14
|
259 | |
260 | /**************
|
261 | ** Variablen **
|
262 | ***************/
|
263 | |
264 | // Reg 0x00 = MODE1 - set to 0x80 - autoincrement enabled (this is readonly?), do not respond to subaddresses or allcall
|
265 | uint8_t Mode1; //Write 0x80 |
266 | // Reg 0x01 = MODE2 - set to 0xFF - noninverted logic state, open-drain
|
267 | uint8_t Mode2; |
268 | // LED_out_Variablen
|
269 | uint8_t Led[NR_LEDS]; |
270 | // LED_OFF:
|
271 | uint8_t Led_off; |
272 | // Reg 0x12 - Group PWM - Variablen
|
273 | uint8_t Group_PWM; |
274 | // Reg 0x13 - Group Freq - Variablen
|
275 | uint8_t Group_Freq; |
276 | // Reg 0x14-0x17 - LED Output State Control - Variablen
|
277 | uint8_t Led_output[4]; |
278 | |
279 | |
280 | /************************
|
281 | ** PCA9635 Funktionen **
|
282 | *************************/
|
283 | |
284 | void Init_PCA9635( void ); |
285 | void FullOff( void ); |
286 | void FullOn( void ); |
287 | void PCA9635( void ); |
288 | void ALL_DIMM( void ); |
289 | |
290 | #endif /* PCA9635_H_ */ |
@ Sören (Gast) >Anregungen sind gerne gesehen :). >/** Initzialisiere PCA9635 **/ > Init_PCA9635(); > PCA9635(); Doppelt gemoppelt. Der Kommentar ist hyperliquide. Strukturierte Programmierung auf Mikrocontrollern >void FullOff( void ) >{ > uint8_t i; > // set all LEDs of 0x00 ( all off) > for( i = 0; i < NR_LEDS; i++ ) > { > Led[i] = 0x00; > } >} >void FullOn( void ) >{ > uint8_t i; > // set all LEDs of 0xFF (Full On) > for( i = 0; i < NR_LEDS; i++ ) > { > Led[i] = 0xFF; > } >} Anstatt zwei Funktionen wäre eine einfacher und besser, der man einfach das Füllmuster als Parameter übergibt. >void PCA9635( void ) >{ > uint8_t i; > // First TLC59116 Chip: > TWIM_Start( PCA9635_ADD1, TWIM_WRITE ); > // Autoincrement ALL registers, start at reg 0 - we're initting Ja was denn nun? Ist es ein TLC59116 oder ein PCA9635? Das sind vollkommen verschiedene ICs! >PCA9635.h: >#ifndef PCA9635_H_ >#define PCA9635_H_ >/************************************** >** TLC59116 device Address/Registers ** >***************************************/ >#define PCA9635_ADD1 0b0010101//0x60 >#define PCA9635_ADD2 0b0010111//0x61 Hier das gleiche Problem! Ausserdem sind ZWEI Adressen ebenfalls hyperliquide und fehleranfällig! Man braucht nur EINE I2C Adresse, meistens die zum Schreiben (LSB = 0). Das Leseadresse ergibt sich durch eine Oder-Verknüpfung mit 0x01. Ausserdem schreibt kein Mensch das binär hin. >/************************ >** PCA9635 Funktionen ** >*************************/ >void Init_PCA9635( void ); >void FullOff( void ); >void FullOn( void ); >void PCA9635( void ); >void ALL_DIMM( void ); Eine sinnvolle Nomenklatur (Namensgebung) wäre TLC59116_Init() TLC59116_FullOn() TLC59116_FullOff() TLC59116_Update() TLC59116_Dimm() #endif /* PCA9635_H_ */
:
Bearbeitet durch User
Ups, hab die Schaltpläne vergessen :D. Okay Okay danke erstmal für die Tipps, den Zweiten Chips gibts schon nicht mehr. Ist quasi eine Codeleische. Das mit der Namensgeben ist ein guter einwand aber doch eigentlich meine sache oder spielt das wieder in die Code schreibweisen mit rein? Werdes berücksichtigen und ändern. Der TLC59116 ist der erste chip den ich benutz hab. Änder ich auch gleich. Sehe den Wald vor lauter Bäumen nicht :D
Hast Du die Schaltpläne in der Nachtschicht gezeichnet, so dunkel, wie sie sind? ;-) Ich habe ihn mal erhellt. MfG Paul
@ Paul Baumann (paul_baumann) > Schaltplan_aus_Forum.jpg >Ich habe ihn mal erhellt. Schön. Aber hier sieht man besonders gut, warum das Format JPG für Schaltpläne ungeeignet ist. Siehe Bildformate (jaja, du kennst den Artikel, der OP aber nicht)
Falk Brunner schrieb: > Aber hier sieht man besonders gut, warum das Format JPG für > Schaltpläne ungeeignet ist. Ich habe auch andere Formate ausprobiert (Irfanview kann in alles Mögliche wandeln). Besser als jetzt hat es aber auch nicht ausgesehen... MfG Paul
Wenn der Schaltplan zum PCA9635.jpg stimmt, dann musst Du auf alle Fälle noch einige Kondensatoren da mit rein nehmen. Ich würde 100nF direkt an den PCA, und nochmal 100nF || > 10uF über die 5V Versorgung (z.B. am Stecker). Sonst läuft das nicht wirklich stabil. Ist VSS wirklich nicht angeschlossen? Keine Ahnung ob dies trotzdem funktioniert, aber laut Datenblatt heißt es dort "Supply Ground" Außerdem hängt /OE in der Luft :-(
Paul Baumann schrieb: > Hast Du die Schaltpläne in der Nachtschicht gezeichnet, so dunkel, wie > sie > sind? > ;-) > > Ich habe ihn mal erhellt. Hab halt den Eagle Hintergrund auf Schwarz gestellt. Finde das angenehmer. Weiß nicht warum das hier öfter erwähnt wird. Sieht man da nicht genau so viel wie auf dem Hellen? Naja diese Diskussion muss man jetzt nicht auf machen. Nicht zielführend ;). Wenn man sich mühe gibt sieht man auch auf dem JPG alles :)
Okay, gut. Änder ich das noch auf dem Board. Vss ist auf GND und der /OE ist so eine komische sache. Lass ich ihn offen gehts. Verbinde ich in mit GND oder über einen 10k mit 5V geht nix mehr... Offene PINs finde ich auch immer nicht so super.
Laut Datenblatt "Active Low Output Enable". Also würde ich sagen auf LOW legen und die LED müssten leuchten (wenn vom Controller aktiviert). HIGH wird wohl die LEDs abschalten.
Sören schrieb: > Sieht man da > nicht genau so viel wie auf dem Hellen? Glaubst Du, daß ich das aus Langeweile gemacht habe? Sören schrieb: > Naja diese Diskussion muss man jetzt nicht auf machen. Nicht zielführend > ;). Spar Dir Dein neusprech -lade lesbare Pläne hoch! Paul
Pepe schrieb: > Wenn der Schaltplan zum PCA9635.jpg stimmt, dann musst Du auf alle Fälle > noch einige Kondensatoren da mit rein nehmen. Ich würde 100nF direkt an > den PCA, und nochmal 100nF || > 10uF über die 5V Versorgung (z.B. am > Stecker). Sonst läuft das nicht wirklich stabil. > > Ist VSS wirklich nicht angeschlossen? Keine Ahnung ob dies trotzdem > funktioniert, aber laut Datenblatt heißt es dort "Supply Ground" > > Außerdem hängt /OE in der Luft :-( So hab das gleich mal umgesetzt, das ganze sieht dann so aus. Danke für die Tipps!
Pepe schrieb: > Laut Datenblatt "Active Low Output Enable". Also würde ich sagen auf LOW > legen und die LED müssten leuchten (wenn vom Controller aktiviert). HIGH > wird wohl die LEDs abschalten. das hab ich getest aber irgendwie wollte es nicht. Als ich ihn dann offen gelassen hab gings.
Ich hoffe Du damit keine Platine fertigen (lassen) ? Dann würde ich an deiner Stelle noch einiges ausprobieren. Übrigens: Die 10uF hatte ich mit Absicht erwähnt... Sollen helfen die Versorgungsspannung auf der PCA-Platine stabil zu halten. Und den C1 solltest Du möglichst nah an die Versorgungspin des PCA bringen. G??gle mal nach "Blockkondensator" falls es Dich interessiert.
Pepe schrieb: > Übrigens: Die 10uF hatte ich mit Absicht erwähnt... Sollen helfen die > Versorgungsspannung auf der PCA-Platine stabil zu halten. Und den C1 > solltest Du möglichst nah an die Versorgungspin des PCA bringen. Die hab ich gerade etwas überlesen aber auf welcher Platine jetzt genau auf er vom PCA9635?
Strom funktioniert eigentlich ähnlich wie Wasser: Durch ne dünne Leitung kommt nur ne gewisse Menge. Wenn ich dann am Ende dieser Leitung ständig einen Eimer mit Wasser schöpfen möchte, brauch ich eine Wanne mit entsprechend Volumen, die ich vorher schon mal fülle. Sonst wackelt der Wasserstand in der Wanne zu stark. Ich würde sogar sagen auf beide Schaltungen.
kurze frage, also hat der erfinder dieser Schaltung. Ebenfalls ein Problem mit seiner Spannungs versorgung? http://www.tng-project.de/wordpress/wp-content/uploads/2013/10/pca96351.png Quelle: http://www.tng-project.de/2013/10/pca9635-i2c-pwm-led-driver/
Pepe schrieb:
> Ich würde sogar sagen auf beide Schaltungen.
Okay dann bring ich das noch ein. Danke!
Pauschal kann ich das nicht wirklich beantworten. Ich würde mich bei der Originalschaltung nicht wohl fühlen. Die Schaltung mag so schon funktionieren. Vielleicht hat er eine stabilere Spannung oder vielleicht hast Du eine kalte Lötstelle (wenn Du lötest). Es kann vielleicht nur ne Kleinigkeit sein. Aber professionell ist das Original auch nicht. ABER: Im Hobbybereich geht so einiges was nicht sauber ist... Hauptsache es läuft :-) Mir ist aber gerade was aufgefallen: Im Original sind Deine R11 & R12 nicht enthalten. (Die I2C PullUps) Hast Du eine Ahnung warum ? Oder warum hast Du welche rein ?
Kleine Verbesserung:
1 | // output 0 - 14
|
2 | for( i = 0; i < NR_LEDS; i++ ) |
3 | {
|
4 | TWIM_Write( Led[i] ); |
5 | }
|
6 | |
7 | // 2 not used outputs
|
8 | TWIM_Write( Led_off ); |
9 | TWIM_Write( Led_off ); |
Hier hast du zwar die Anzahl der LEDs in ein #define gepackt, aber wenn die Anzahl sich ändert, musst du immer noch den Code anfassen: nämlich die letzte 2 Zeilen. Besser wäre also:
1 | #define MAX_NR_LEDS 16
|
2 | |
3 | for(i = 0; i < NR_LEDS; i++) |
4 | {
|
5 | TWIM_Write(Led[i]); |
6 | }
|
7 | for( ; i < MAX__NR_LEDS; i++) |
8 | {
|
9 | TWIM_Write(Led_off); |
10 | }
|
Oder einfach auch die nicht benutzte LEDs in dein Led[] Array mitaufnehmen und auf Led_off stehen lassen.
@ Sören (Gast) >also hat der erfinder dieser Schaltung. Ebenfalls ein Problem mit seiner >Spannungs versorgung? >http://www.tng-project.de/wordpress/wp-content/upl... Ja. - es fehlen 100nF Keramk am LED-IC, welcher KEIN PCA9536 ist! - es fehlen 100-330uF an der 5V Leitung. Denn wenn die PWM mal loslegt, müssen die Pulsströme irgendwo herkommen, der Spannungsregler allein kann das nicht so gut. - es ist nicht sonderlich sinnvoll, einen TLC59116 mit nachgeschalteten ULN2003 zu verwenden. Ausserdem fehlt da an jedem Ausgang ein Pull-Up Widerstand. Warum nicht die LEDs direkt mit dem TLC treiben? Der kann das bis 80mA/Kanal
Pepe schrieb: > Mir ist aber gerade was aufgefallen: Im Original sind Deine R11 & R12 > nicht enthalten. (Die I2C PullUps) Hast Du eine Ahnung warum ? Oder > warum hast Du welche rein ? Ich hab den Plan nicht also vorlage benutzt, bin nur mal drüber gestollpert. Also ich mich rein gelesen hab in die I2C sache hab ich irgendwo mit aufgenommen das es quasi empfohlen wird PullUps an die I2C schnittstelle zuhängen. Fand das auch garnicht so unschlüssig definierter schaltzustand und so. Ausgeloggt schrieb: > Kleine Verbesserung: // output 0 - 14 > for( i = 0; i < NR_LEDS; i++ ) > { > TWIM_Write( Led[i] ); > } > > // 2 not used outputs > TWIM_Write( Led_off ); > TWIM_Write( Led_off ); > Hier hast du zwar die Anzahl der LEDs in ein #define gepackt, aber wenn > die Anzahl sich ändert, musst du immer noch den Code anfassen: > nämlich die letzte 2 Zeilen. > > Besser wäre also:#define MAX_NR_LEDS 16 > > for(i = 0; i < NR_LEDS; i++) > { > TWIM_Write(Led[i]); > } > for( ; i < MAX__NR_LEDS; i++) > { > TWIM_Write(Led_off); > } > Oder einfach auch die nicht benutzte LEDs in dein Led[] Array > mitaufnehmen und auf Led_off stehen lassen. Danke, schau ich mir gleich nochmnal an!
Falk Brunner schrieb: > welcher KEIN PCA9536 ist! Ich steig gerade nicht durch. Warum ist dies kein PCA9536?
Falk Brunner schrieb: > - es fehlen 100nF Keramk am LED-IC, welcher KEIN PCA9536 ist! > - es fehlen 100-330uF an der 5V Leitung. Denn wenn die PWM mal loslegt, > müssen die Pulsströme irgendwo herkommen, der Spannungsregler allein > kann das nicht so gut. > - es ist nicht sonderlich sinnvoll, einen TLC59116 mit nachgeschalteten > ULN2003 zu verwenden. Ausserdem fehlt da an jedem Ausgang ein Pull-Up > Widerstand. Warum nicht die LEDs direkt mit dem TLC treiben? Der kann > das bis 80mA/Kanal Ich denke schon das es ein PCA9635 ist aber selbst wenn nicht ist das nicht ganz so wild der TLC59116 ähnelt sich sehr. Warum er die ULN2003 verwendet kann ich dir auch nicht sagen aber ich hab da warscheinlich einähnliches problem wie er und zwas das ich LEDs ansteuere die 120mA brauchen. Ich hab das mit NPN-Transitor gelöst der als Schalter dient.
@ Sören: "Ich hab das mit NPN-Transitor gelöst" Kommt nach Deinem PCA wirklich noch ein NPN-Transistor pro Kanal? Dann sprechen wir ja von 12 x 120mA = 1,4A und nicht von 12 x 25mA. Dann ist die bisherige Beschaltung ja wohl nichts: Wie Falk schreibt größeren Elko auf beide Schaltungen. Und ich hoffe Du verwendest kein Steckernetzeil. Da kann es auch knapp werden...
@ Sören (Gast) >Ich denke schon das es ein PCA9635 ist OK, mein Fehler! Ich hatte einen Zahlendreher im Kopf! Ich dachte an den PCA9536! Weil der mich in dem Thread hier ziemlich beschäftigt hat! Beitrag "Denkfehler mit PCA9536 (Problem)" > Warum er die ULN2003 >verwendet kann ich dir auch nicht sagen aber ich hab da warscheinlich >einähnliches problem wie er und zwas das ich LEDs ansteuere die 120mA >brauchen. Und das kann der PC9635 nicht, er schafft nur max. 25mA. Ausserdem hat er normale Totem-Pole Ausgänge, man braucht also keinen Pull-Ups. Mein Fehler. > Ich hab das mit NPN-Transitor gelöst der als Schalter dient. Ist OK.
Pepe schrieb: > Kommt nach Deinem PCA wirklich noch ein NPN-Transistor pro Kanal? Dann > sprechen wir ja von 12 x 120mA = 1,4A und nicht von 12 x 25mA. Dann ist > die bisherige Beschaltung ja wohl nichts: Wie Falk schreibt größeren > Elko auf beide Schaltungen. Und ich hoffe Du verwendest kein > Steckernetzeil. Da kann es auch knapp werden... Ist nicht ganz so einfach zusagen. Ich verwende eine LED mit 120mA und 7 mit 30mA und 4 mit 20mA. Bezüglich des einheitlichem Bild und ich dachte mir um den PCA nicht ganz so zu belasten hab ich auch die 20mA Ausgang mit einem Transitor versehen. Aber alles im allem komme ich ja quasi so nur auf 410mA also nicht ganz so schlimm. Dazu muss ich sagen das der Probeaufbau auf einer Lochleiterplatte ist mit "Freiluft" verdrahtung und Spannungswandler die mit recht großen Elkos versehen sind 220µ. Nur der C am PCA direkt fehlt. In der schaltung hab ich recht viel weggelassen quasi vereinfacht. Da war ich wohl mit dem Radiere etwas zu radikal :D. Danke euch dann weiß ich jetzt was ich noch zutun hab. Aber zu viele C sind auch wieder nicht gut oder. Also nicht das ich jetzt anfange wie ein wilder Cs in die Schaltung so bauen :)
Cs gehören mindestens an folgende Stellen: - Stecker der Spannungsversorgung: Irgendwas 100nF + >100uF. - Spannungsversorgungspin der Chips: 100nF Block-C, wenn mehrere Spg.Pins dann an jedes "Paar" einen C. ( z.B. Prozessoren ) - "Übergang" zur nächsten PCB: Je nach Anwendung nur 100nF oder eben auch einen größeren C Was immer gut ist: Blick ins Datenblatt. Dort sind meistens Beispielschaltungen/Testschaltungen auch mit den Cs.
auf deinem Board fällt mir der fehlende Kerko zw. Reset und GND auf. Dann hast du für VCC und AVCC nur 1 Kerko genommen. Vor den Kerko für VCC vielleicht nochmal 10µF einfügen. Vielleicht ist deine Stromversorgung des Bords etwas schwachbrüstig und nicht stabil.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.