Forum: Mikrocontroller und Digitale Elektronik LED-Treiber Ansteuern Software


von Peter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche gerade folgenden FAN5626 LED-Treiber Bausteil mit einem 
XMEGA8E5 anzusteuern.

Die Hardware an sich funktioniert soweit nur komme ich mit der 
Programmierung nicht weiter:


Ich möchte mit einem Taster (an PIN7 PORTA) 3 Dimmstufen erreichen d.h 
drücke ich die Taste 1x 75% Lichtintensität 2x 50% 3x 25%

Habe folgende Funktion geschrieben die aber leider nicht funktioniert:
1
void tasten_abfrage (void)
2
{
3
  uint8_t tasterwert_vorher = 1, tasterwert_jetzt = 0, anzahl = 0, i;
4
  
5
  tasterwert_jetzt = PORTA.IN & PIN7_bm; /*aktueller Tasterwert wird eingelesen*/
6
  _delay_ms(20);
7
  
8
  if(!(PORTA.IN & PIN6_bm))
9
  {
10
    PORTC.OUT = 0x10; /*Taste UV 1 mal gedrückt -> UV an*/
11
    PORTC.OUTCLR = 0x0C; /*POL-Beleuchtung aus*/
12
    PORTR.OUTCLR = PIN0_bm; /*Status-LED blau an*/
13
    PORTD.OUTSET = PIN6_bm;  /*Status-LED grün aus*/
14
  }
15
  
16
  if(tasterwert_jetzt != tasterwert_vorher)
17
  {
18
    if(tasterwert_jetzt == 0)
19
    {
20
      anzahl++;
21
    }
22
    
23
    switch (anzahl)
24
    {
25
      case 1: for(i=0;i<=25;i++)
26
          {        
27
            PORTC.OUTCLR = 0x10; /*UV-Beleuchtung aus*/
28
            PORTD.OUTCLR = PIN6_bm; /*Status-LED grün an*/
29
            PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/
30
            _delay_ms(200);
31
            PORTC.OUTTGL = 0x0C; /*Taste POL 1 mal gedrückt -> POL an 76% */        
32
            break;
33
          }
34
          
35
      
36
      case 2: for(i=0;i<=17;i++)
37
          {
38
            PORTC.OUTCLR = 0x10; /*UV-Beleuchtung aus*/
39
            PORTD.OUTCLR = PIN6_bm; /*Status-LED grün an*/
40
            PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/
41
            _delay_ms(200);
42
            PORTC.OUTTGL = 0x0C; /*Taste POL 1 mal gedrückt -> POL an 50%*/
43
            break;  
44
          }  
45
      
46
      case 3: for(i=0;i<=10;i++)
47
          {
48
            PORTC.OUTCLR = 0x10; /*UV-Beleuchtung aus*/
49
            PORTD.OUTCLR = PIN6_bm; /*Status-LED grün an*/
50
            PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/
51
            _delay_ms(200);
52
            PORTC.OUTTGL = 0x0C; /*Taste POL 1 mal gedrückt -> POL an 26%*/
53
            break;
54
          }       
55
      
56
      default: anzahl = 0;
57
    }
58
  }
59
  tasterwert_vorher=tasterwert_jetzt; /* aktuellen Tasterwert merken und wieder vergleichen */
60
}


kann mir bitte einer weiterhelfen?

von Peter II (Gast)


Lesenswert?

uint8_t tasterwert_vorher = 1, tasterwert_jetzt = 0, anzahl = 0, i;

wenn du das jedes mal ausführst, dann kannst du dir ja überhaupt keine 
alten Status merken. Bei jedem funktionaufruf fängst du wieder bei 0 an.

mach sie mal static.

Warum debugs/simulierst du das Programm nicht einfach, dann sollte so 
etwas sehr schnell auffallen?

von Peter (Gast)


Lesenswert?

Peter II schrieb:
> uint8_t tasterwert_vorher = 1, tasterwert_jetzt = 0, anzahl = 0,
> i;
>
> wenn du das jedes mal ausführst, dann kannst du dir ja überhaupt keine
> alten Status merken. Bei jedem funktionaufruf fängst du wieder bei 0 an.
>
> mach sie mal static.

ok is jetzt static
>
> Warum debugs/simulierst du das Programm nicht einfach, dann sollte so
> etwas sehr schnell auffallen?

die Abfrage der Taster funktioniert soweit....
wo ich mir nicht sicher bin ist das Erzeugen von dem Takt für den CTRL 
pin von dem FAN5626.

Ich verstehe das so:  Zuerst muss CTRL high sein dann low/high 
abwechseln und die anzahl des wechsels bestimmt die Helligkeit 
proportional.

daher mache ich das in der for-schleife wo ich den pin toggel jedoch 
weiß ich nicht wie schnell bzw. langsam ich das machen darf. Zudem muss 
der letzte takt high sein damit die Beleuchtungsintensität auf dem Level 
bleibt.



Auszug aus dem Datenblatt:
"The FAN5622, FAN5624, and FAN5626 implement a simple
single-wire digital interface to program the LED brightness to
one of thirty two (32) levels spaced in linear steps. To maintain
the brightness of the LEDs at a specific dimming level, the
digital pulse signal to the CTRL pin should be held HIGH for
that last pulse. It is held HIGH for as long as desired to keep
the LEDs illuminated at that specific brightness level"


oder versteh ich das falsch?

von Peter II (Gast)


Lesenswert?

Peter schrieb:
> wo ich mir nicht sicher bin ist das Erzeugen von dem Takt für den CTRL
> pin von dem FAN5626.

da ein Takt aus 2 Teilen besteht (low/high) und du nur ein delay hast, 
kann das kein wirklicher takt werden.

von Peter (Gast)


Lesenswert?

Peter II schrieb:
> Peter schrieb:
>> wo ich mir nicht sicher bin ist das Erzeugen von dem Takt für den CTRL
>> pin von dem FAN5626.
>
> da ein Takt aus 2 Teilen besteht (low/high) und du nur ein delay hast,
> kann das kein wirklicher takt werden.

da ich den toggle befehl nutze brauche ich nur ein delay

[c]
_delay_ms(200);
PORTC.OUTTGL = 0x0C; /*Taste POL 1 mal gedrückt -> POL an 50%*/
[/]

mir geht es ehr um die Grundidee kann man das mit einer for-schleife 
realisieren so wie ich mir das oben gedacht habe, sodass ich ein Signal 
wie im Datenblatt auf Seite 7 Figure. 16 erhalte?

oder wie müsste ich da vom C-code rangehen?

von Peter (Gast)


Lesenswert?

Hallo,

habe leider immer noch das Problem mit der Helligkeitsreglung über den 
LED-Treiber FAN5626 ich möchte folgendes Erreichen beim starten von dem 
Gerät sollen die LEDs bei 80% Helligkeit an sein.

Drücke ich die Taste an PIN7 dann soll 100% Helligkeit der LEDs sich 
einstellen.


Dazu zwei Fragen:
1
case 1: while(1)
2
              {
3
                
4
              
5
              for (i=0;i<=15;i++)
6
              {
7
                _delay_us(200);
8
                PORTC.OUTTGL = 0x0C;
9
              }  
10
              PORTD.OUTSET = PIN6_bm;  /*Status-LED grün aus*/
11
              PORTD.OUTCLR = PIN7_bm; /*Status-LED Rot an*/
12
              PORTC.OUT = 0x0C; /*KW & WW Level high*/        
13
              }
14
              break;

In meinem Quellcode mache ich im case1 über die for-schleife die 
entsprechenden PINs 16 mal high/low und setzte dann auf high.

Damit werden die LEDs auf ca. 80% gedimmt.


aber durch die while(1)schleife werden meine tasten nicht mehr abgefragt 
und ich kommen aus dem Fall gar nicht mehr raus... nehme ich while(1) 
weg funktioniert die Helligkeitsreglung nur kurz weil nach 16 mal 
Durchlauf rausgesprungen wird.


Wie kann ich das anders lösen, sodass taster immer abgefragt werden und 
die Helligkeit auch geregelt werden kann stehe auf dem Schlauch.


Hier ist der gesamte Quellcode:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 8000000UL
4
#include <util/delay.h>
5
6
void clock_init (void)
7
{
8
  OSC.CTRL |= OSC_RC8MEN_bm; /*Oszillator auf 8 Mhz einstellen*/
9
  while(!(OSC.STATUS & OSC_RC8MRDY_bm)); /*Warten bis der Oszillator
10
  bereit ist*/
11
  CCP = CCP_IOREG_gc; /*Schützt I/O Register, Interrupts werden
12
  ignoriert*/
13
  CLK.CTRL = (CLK.CTRL &~ CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC8M_gc;
14
  /*aktiviert den internen Oszillator*/
15
}
16
17
18
void port_init (void)
19
{
20
  /*Charge_Voltage*/
21
  PORTA.DIR &= ~PIN1_bm; /*PORTA.1 als Eingang definiert (0,93V-1,4V)*/
22
  
23
  /*Charge_Current*/
24
  PORTA.DIR &= ~PIN0_bm; /*PORTA.0 als Eingang definiert (1.5V = 1.2A)*/
25
  
26
  /*Reedkontakt init*/
27
  PORTC.DIR &= ~ PIN5_bm; /*PORTC.5 auf Eingang Reedkontakt*/
28
  PORTC.PIN5CTRL |= PORT_OPC_PULLUP_gc; /*Pull-Up Widerstand am PORTC.5 aktiv (Reedkontakt)*/
29
  
30
  /*LEDs init*/
31
  PORTC.OUT &= ~ PIN4_bm; /*PORTC.4 auf low UV-LEDs->aus*/
32
  //PORTC.OUT &= ~ PIN3_bm; /*PORTC.3 auf high WW-LEDs->aus*/
33
  //PORTC.OUT &= ~ PIN2_bm; /*PORTC.2 auf high KW-LEDs->aus*/
34
  PORTC.OUT |= PIN3_bm; /*PORTC.3 auf high WW-LEDs->an 100%*/
35
  PORTC.OUT |= PIN2_bm; /*PORTC.2 auf high KW-LEDs->an 100%*/
36
  PORTC.DIR = 0x1C;      /*PORTC auf Ausgang LEDs*/
37
  
38
  /*System ON/OFF*/
39
  PORTC.DIR |= PIN1_bm; /*PORTC.1 auf Ausgang ON/OFF*/
40
  PORTC.OUT &= ~PIN1_bm; /*PORTC.1 auf low*/
41
  
42
  /*Status LED Init*/
43
  PORTD.DIR |= PIN6_bm; /*LED Grün*/
44
  //PORTD.OUT |= PIN6_bm;
45
  
46
  PORTD.DIR |= PIN7_bm; /*LED Rot*/
47
  PORTD.OUT |= PIN7_bm;  
48
  
49
  PORTR.DIR |= PIN0_bm; /*LED Blau*/
50
  PORTR.OUT |= PIN0_bm;
51
  
52
  /*Charger Fault*/
53
  PORTD.DIR &= ~PIN5_bm; /*PORTD.5 als Eingang definiert*/
54
  
55
  /*DC-Power OK*/
56
  PORTD.DIR &= ~PIN4_bm; /*PORTD.4 als Eingang definiert*/
57
  
58
  /*Charger ON/OFF*/
59
  PORTD.DIR |= PIN3_bm;
60
  PORTD.OUT &= ~ PIN3_bm; /*Laden an*/
61
  //PORTD.OUT |=  PIN3_bm;
62
  
63
  /*Charger Indikator*/
64
  PORTD.DIR &= ~PIN2_bm; /*PORTD.2 als Eingang definiert*/
65
  
66
  /*USB-Power OK*/
67
  PORTD.DIR &= ~PIN1_bm; /*PORTD.1 als Eingang definiert*/
68
  
69
  /*Taster Init*/
70
  PORTA.DIR &= ~PIN7_bm; /*PORTA7 als Eingang definieren (Taster POL)*/
71
  PORTA.PIN7CTRL |= PORT_OPC_PULLUP_gc; /*Pull-Up Widerstand am PORTA7 aktiv (Taster POL)*/
72
  
73
  PORTA.DIR &= ~PIN6_bm; /*PORTA6 als Eingang definieren (Taster UV) */
74
  PORTA.PIN6CTRL |= PORT_OPC_PULLUP_gc; /*Pull-Up Widerstand am PORTA6 aktiv (Taster UV)*/
75
  
76
  //PORTA.DIR &= ~PIN5_bm; /*PORTA5 als Eingang definieren (Taster Reserved)*/
77
  //PORTA.PIN5CTRL |= PORT_OPC_PULLDOWN_gc; /*Pull-Up Widerstand am PORTA7 aktiv (Taster3)*/
78
}
79
80
81
void interrupt_init (void)
82
{
83
  PMIC.CTRL |= PMIC_LOLVLEN_bm; /*Interrupt eingeschaltet*/
84
  sei(); /*Interrupt freischalten*/
85
}
86
87
88
void timer4_init (void)
89
{
90
  TCC4.CTRLA = TC45_CLKSEL_DIV256_gc; /*Vorteiler auf 8 eingestellt*/
91
  TCC4.CTRLB = TC45_WGMODE_NORMAL_gc; /* Timer auf normal Mode (hochzählend) eingestellt */
92
  TCC4.PER = 5000; /*Timer vorladen 65436*/
93
  TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc; /*Interrupt Modus aktiv*/
94
  TCC4.INTFLAGS = TC4_OVFIF_bm;
95
}
96
97
98
void tasten_abfrage (void)
99
{
100
  static uint8_t tasterwert_vorher = 1, tasterwert1_vorher = 1, tasterwert_jetzt = 0, tasterwert1_jetzt = 0, anzahl = 0, anzahl1 = 0, i;    
101
  
102
    tasterwert_jetzt = PORTA.IN & PIN7_bm; /*aktueller Tasterwert POL wird eingelesen*/  
103
    tasterwert1_jetzt = PORTA.IN & PIN6_bm; /*aktueller Tasterwert UV wird eingelesen*/
104
    _delay_ms(20);
105
    
106
    if(tasterwert1_jetzt != tasterwert1_vorher)
107
    {
108
      if(tasterwert1_jetzt == 0)
109
      {
110
        anzahl1++;
111
      }
112
    
113
      switch (anzahl)
114
      {
115
        case 1:  PORTC.OUT = 0x10; /*Taste UV 1 mal gedrückt -> UV an*/
116
            PORTC.OUTCLR = 0x0C; /*POL-Beleuchtung aus*/
117
            PORTR.OUTCLR = PIN0_bm; /*Status-LED blau an*/
118
            PORTD.OUTSET = PIN6_bm;  /*Status-LED grün aus*/
119
            break;
120
            
121
            default: anzahl1 = 1;
122
      }    
123
    }
124
    tasterwert1_vorher=tasterwert1_jetzt; /* aktuellen Tasterwert merken und wieder vergleichen */    
125
      
126
      
127
      
128
      if(tasterwert_jetzt != tasterwert_vorher)  
129
      {
130
        if(tasterwert_jetzt == 0)  
131
        {
132
          anzahl++;
133
        }
134
      
135
        switch (anzahl)
136
        {
137
          //case 1: PORTC.OUT = 0x0C; /*Taste POL 1 mal gedrückt -> POL an*/
138
              //PORTC.OUTCLR = 0x10; /*UV-Beleuchtung aus*/
139
              //PORTD.OUTCLR = PIN6_bm; /*Status-LED grün an*/
140
              //PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/             
141
              //break;            
142
          
143
              
144
          case 1: while(1)
145
              {
146
                
147
              
148
              for (i=0;i<=15;i++)
149
              {
150
                _delay_us(200);
151
                PORTC.OUTTGL = 0x0C;
152
              }  
153
              PORTD.OUTSET = PIN6_bm;  /*Status-LED grün aus*/
154
              PORTD.OUTCLR = PIN7_bm; /*Status-LED Rot an*/
155
              PORTC.OUT = 0x0C; /*KW & WW Level high*/        
156
              }
157
              break;  
158
          
159
                    default: anzahl = 1;
160
        }
161
      }
162
        tasterwert_vorher=tasterwert_jetzt; /* aktuellen Tasterwert merken und wieder vergleichen */    
163
}
164
165
166
void laden_DC (void)
167
{  
168
  if((PORTC.IN & PIN5_bm) && (!(PORTD.IN & PIN4_bm)) && (!(PORTD.IN & PIN2_bm))) /*Reedkontakt OK (high) & DC-PWR OK (low) & Charge Indicator (low)*/
169
  {
170
    PORTC.OUTCLR = 0x1C; /*Beleuchtung aus*/
171
    PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/
172
    _delay_ms(250);
173
    PORTD.OUTTGL = 0x40; /*grüne Status LED toggeln*/
174
  }
175
  else
176
  {
177
    if((PORTD.IN & PIN2_bm) && (PORTC.IN & PIN5_bm)) /*Charge Indicator (high) & Reedkontakt OK (low)*/
178
    {
179
      PORTC.OUT = 0x1C;
180
      PORTD.OUT &= ~ PIN6_bm; /*grüne Status LED an*/
181
    }
182
  }
183
}
184
185
186
void laden_USB (void)
187
{
188
  if(!(PORTD.IN & PIN1_bm) && (!(PORTD.IN & PIN2_bm))) /*USB-Power OK low & Charge_Indicator low*/
189
  {
190
    PORTC.OUTCLR = 0x1C; /*Beleuchtung aus*/
191
    PORTR.OUTSET = PIN0_bm;  /*Status-LED blau aus*/
192
    _delay_ms(500);
193
    PORTD.OUTTGL = 0x40; /*Status-LED grün toggeln*/
194
  }
195
  else
196
  {
197
    if((PORTD.IN & PIN1_bm) && (!(PORTD.IN & PIN2_bm))) /*USB-Power OK low & Charge_Indicator low*/
198
    {
199
      PORTD.OUTCLR = PIN6_bm; /*Status-LED grün an*/
200
    }
201
  }
202
}
203
204
205
void start_init (void)
206
{
207
  uint8_t i;
208
  
209
  while(1)
210
  {
211
    
212
    
213
    for (i=0;i<=15;i++)
214
    {
215
      _delay_us(200);
216
      PORTC.OUTTGL = 0x0C;
217
    }
218
    PORTD.OUTSET = PIN6_bm;  /*Status-LED grün aus*/
219
    PORTD.OUTCLR = PIN7_bm; /*Status-LED Rot an*/
220
    PORTC.OUT = 0x0C; /*KW & WW Level high*/
221
  }
222
}
223
224
int main(void)
225
{
226
    
227
  clock_init ();
228
  port_init();
229
  timer4_init();
230
  interrupt_init();  
231
  //start_init();
232
  while(1)
233
    {
234
    
235
    tasten_abfrage();
236
    laden_USB(); 
237
  }
238
}
239
240
241
ISR(TCC4_OVF_vect)
242
{
243
  TCC4.INTFLAGS = TC4_OVFIF_bm;  
244
  laden_DC();
245
}

von Peter (Gast)


Lesenswert?

Hat keiner Rat?

komme immer noch nicht weiter :-(

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> Hat keiner Rat?
>
> komme immer noch nicht weiter :-(

 Die eine Möglichkeit ist, dass du diesen Pin (ungewollt) irgendwo
 anders wieder auf Null ziehst. Ansonsten bleibt die Helligkeit, einmal
 eingestellt und mit CTRL pin auf HIGH unverändert.

 Eine andere Möglichkeit wäre, dass du CTRL-Pin beim Tasterabfragen
 als Eingang schaltest. Das sieht der FAN als offenen Eingang und das
 darf nicht passieren.
 Sorry, hab keine Lust durch diesen ganzen Code zu gehen, aber eins von
 beiden ist es bestimmt.

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Marc Vesely schrieb:
> Peter schrieb:
>> Hat keiner Rat?
>>
>> komme immer noch nicht weiter :-(
>
>  Die eine Möglichkeit ist, dass du diesen Pin (ungewollt) irgendwo
>  anders wieder auf Null ziehst. Ansonsten bleibt die Helligkeit, einmal
>  eingestellt und mit CTRL pin auf HIGH unverändert.
heißt das wenn das in der for-schleife durch gelaufen ist und ich z.B. 
17 low impulse erzeugt habe dann brauche ich das nicht zu wiederholen 
mit der while schleife?

>
>  Eine andere Möglichkeit wäre, dass du CTRL-Pin beim Tasterabfragen
>  als Eingang schaltest. Das sieht der FAN als offenen Eingang und das
>  darf nicht passieren.
>  Sorry, hab keine Lust durch diesen ganzen Code zu gehen, aber eins von
>  beiden ist es bestimmt.

kann mir einer das Prinzip von der Dimming-Funktion von dem FAN5626 
erklären blicke da noch nicht ganz durch.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> heißt das wenn das in der for-schleife durch gelaufen ist und ich z.B.
> 17 low impulse erzeugt habe dann brauche ich das nicht zu wiederholen
> mit der while schleife?

 Toggle ist manchmal ganz nützlich, aber manchmal auch sehr störend,
 weil man nicht immer sicher ist auf welchem Level die Ausgänge gerade
 sind.
 Deswegen schaltet man bei so etwas LOW und HIGH in einem Durchlauf, da
 kann man mit Schleifenzähler die Zahl der Takte einstellen.
 Jetzt musste ich einfach FAN56xx DaBla suchen.

 Also, wenn ich das richtig verstehe, fängt der FAN nach Shutdown mit
 100% an, jeder Takt dimmt runter um 3,33%.

 Beim takten ist:
   LOW  MIN. 0,5us   MAX 300us
   HIGH MIN. 0,5us   MAX 999us

 CTRL auf LOW  für 1ms oder länger ist SHUTDOWN.
 CTRL auf HIGH für 250us oder länger heisst, den eingetakteten Wert
 anzeigen.

 Also um auf 75% (76,67%, um genau zu sein) zu kommen, muss man:
 CTRL auf LOW  für mind. 1 ms.
 CTRL auf HIGH für mind. 250us

 CTRL 8 mal TAKTEN ( aber richtig mit LOW zuerst, dann HIGH
   - und Zeiten einhalten).

 CTRL auf HIGH lassen (Beim normalen takten ist die das schon).

 Und das wars dann auch.

 EDIT:
 Um von 76,67% auf 50% zu kommen, taktet man CTRL weitere 8 mal.

: Bearbeitet durch User
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.