Forum: Mikrocontroller und Digitale Elektronik Avr Dimmer 230V


von Niclas (Gast)


Lesenswert?

Hi Leute,
ich habe vor über meinen Atmega8 230 Volt zu dimmen. Die 
Nulldurchgangserkennung wird mit einem Optokoppler (4N33) + Widerstand 
direkt am Netz angeschlossen. Somit sollte ich am Ausgang ein 
Rechtecksignal erhalten. Das erzeugte Signal geht dann in den AVR an den 
Interrupt-Pin 1.
Hier wird ein Zähler zurückgesetzt. Der Timer löst nach 39µs aus, somit 
wird dieser aufruf ca. 256 mal pro Halbwelle ausgelöst. Wenn der Timer 
also auflöst wird geguckt, ob der aktuelle Zählerstand dem vorgegeben 
Wert entspricht.

Ist das hier von der Idee her richtig?
Oder ist das komplett der falsche Ansatz?
1
#define F_CPU 16000000
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
uint8_t counter, val1, val2;
6
7
#define timerpreload_1 178
8
9
#define Tri1_OUT DDRD |= (1<<PD7);
10
#define Tri2_OUT DDRD |= (1<<PD6);
11
12
13
#define Tri1_ON    PORTD |= (1<<PD7);
14
#define Tri1_OFF  PORTD &= ~(1<<PD7);
15
#define Tri2_ON    PORTD |= (1<<PD6);
16
#define Tri2_OFF  PORTD &= ~(1<<PD6);
17
18
19
ISR(TIMER2_OVF_vect)
20
{
21
  TCNT2 = timerpreload_1; 
22
  if (counter < 254)
23
  {
24
    counter++;
25
  }
26
  if(counter==val1)
27
  {
28
    Tri1_ON
29
  }
30
  else
31
  {
32
    Tri1_OFF
33
  }
34
  if(counter==val2)
35
  {
36
    Tri2_ON
37
  }
38
  else
39
  {
40
    Tri2_OFF
41
  }
42
  
43
44
45
}
46
47
/
48
ISR (INT1_vect)
49
{
50
  Tri1_OFF
51
  Tri2_OFF
52
  TCNT2 = timerpreload_1;
53
  counter = 0;
54
  if (val1 == 0)
55
  {
56
    Tri1_ON
57
  }
58
  if (val2 == 2)
59
  {
60
    Tri2_ON
61
  }
62
}
63
  
64
65
int main(void)
66
{
67
  //Timer für die Phasenanschnittberechnung ( alle 39usec )
68
  TCNT2 = timerpreload_1;
69
  TCCR2 |= (1<<CS21);
70
  TIMSK |= (1<<TOIE2);  
71
  //Timer Ende
72
  //INT1 ON PHASE SYNC
73
  MCUCR |= (1<<ISC10); //Fallend / Steigend
74
  GICR |= (1<<INT1); //Interrupt aktivieren
75
  //Int1 Ende
76
  sei();
77
78
    while(1)
79
    {
80
        
81
    }
82
}
Somit sollte für val=255 die Lampe aus und für 0 an sein.

MfG Niclas

von Niclas (Gast)


Lesenswert?

Oh Fehler
1
ISR (INT1_vect)
2
{
3
  Tri1_OFF
4
  Tri2_OFF
5
  TCNT2 = timerpreload_1;
6
  counter = 0;
7
  if (val1 == 0)
8
  {
9
    Tri1_ON
10
  }
11
  if (val2 == 0)
12
  {
13
    Tri2_ON
14
  }
15
}
Bei val2==2 musste ne 0 hin.

von Stefan (Gast)


Lesenswert?

Sieht in meine Augen soweit gut aus. Allerdings komme ich bei dem Timer 
auf 89 us Periode. Kann mich aber auch verrechnet haben.
Variablen, die du in ISRs und main() verwendest, solltest du als 
volatile markieren, damit sie bei jedem Zugriff aus dem RAM gelesen / 
ins RAM geschrieben werden und vom Optimizer nicht in Register gepackt 
werden.

von Niclas (Gast)


Lesenswert?

Stefan schrieb:
> 89 us Periode

Ich denke du hast folgenedes gerechnet 1/(16.000.000*8*178) oder?
Man muss aber glaube ich 1/(16.000.000*8*(255-178)) rechnen, weil er ja 
von 178 bis 255 zählt.

Niclas

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.