Phasenabschnitt_10.c


1
/*  Programm zur Ansteuerung eines Phasenabschnitts-Dimmers. 
2
  Der Dimmer ist somit auch für elektronische Halogentrafos geeignet; für Glühlampen und dergleichen ebenfalls
3
  
4
  Der Dimmer selbst wird in SERIE zur Phase und dem mit der Last verbundenen Nullleiter geschlossen. Es efolgt keine galvanische Trennung, daher kann
5
  eine Berührung des Dimmers während des Betriebes zum Tod führen! 
6
  Ist der MOSFET durchgeschlaten, so liegt der volle SINUS am Verbraucher an. In der jetzigen Version wird die Versorgungsspannung in der AUS-Zeit der
7
  Sinus-Periode in einem Kondensator zwischengespeichert. Folgedessen liegt bei voller Aussteuerung am Dimmer keine Spannung an!
8
  
9
  Der Nulldurchgang wird mit Hilfe einer Diodenschaltung detektiert. Es ist dabei aber zu beachten, dass nur EIN Nulldurchgang pro periode detektiert wird.
10
  Der Durchgang tritt bei einer Sinus-Spannung mit 50Hz ja zeitlich um 10ms versetzt auf, wonach die kein großes Problem darstellt.
11
  Dieser Durchgang wird dem µC durch seinen Int0-Eingang zugeführt. Der µCmuss für fallende Ints konfiguriert sein
12
  
13
  Programmablauf:
14
  - Int0 detektiert Nulldurchgang -> ISR
15
  - Der MOSFET schaltet durch zuweisen von LOW auf den Ausgangspin durch
16
  - Ein Timer beginnt zu zählen
17
  - Nach Erreichen des Ansteuerwinkels (EIN-Zeit) wird der Ausgang auf HIGH gesetzt
18
  - Nach Erreichen von 10msec wir der Ausgang für die zweite Halbwelle wieder auf LOW gesetzt
19
  - Es wird wieder mit dem Timer die EIN-Zeit abgewarten und der Ausgang auf HIGH gesetzt
20
  - Reti, warte auf nächste fallende Flanke...
21
  
22
  Prozessor:    ATMEGA8
23
  Takt:      3,2768MHz
24
  
25
  Tasten:      PB0 -> UP
26
*          PB1 -> DOWN
27
28
!!!!!!!!!!!Beschreibung nicht aktuell!!!!!!!!!!!
29
30
Interner Quarz, 8MHz, Timer 1 mit Vorgabe 4000
31
  
32
  
33
*/
34
35
#include <avr/io.h>
36
#include <avr/interrupt.h>
37
38
#define T_UP    PINB0
39
#define T_DOWN    PINB1
40
#define T_PIN    PINB
41
#define MOSFET_DDR  DDRD
42
#define MOSFET_PORT  PORTD
43
#define MOSFET_PX  PD3
44
45
#define SET_MOSFET_OUT  MOSFET_DDR|=(1<<MOSFET_PX)
46
#define MOSFET_EIN    MOSFET_PORT&=~(1<<MOSFET_PX)            //LOW -> Mosfet einschalten!
47
#define MOSFET_AUS    MOSFET_PORT|=(1<<MOSFET_PX)
48
49
#define TEILER      -4000
50
#define RETURN       100
51
52
void entprellen(void);
53
54
volatile unsigned char winkel=0;                      //Anstellwinkel, EIN-Zeit, max 64
55
volatile unsigned char takt;
56
volatile unsigned char flanke;                  //Flankenart, 0->steigend; 1->fallend
57
58
int main(void)
59
{  
60
  DDRD|=(1<<DDD3);
61
62
  MCUCR|=(1<<ISC01)|(1<<ISC00);                  //Int0 bei steigender Flanke
63
  GICR|=(1<<INT0);                        //Int0 ein
64
  flanke=0;
65
  
66
  TCCR1B|=(1<<CS10);                        //Teiler 1
67
  TCNT1  = TEILER;
68
  
69
  SET_MOSFET_OUT;
70
  MOSFET_AUS;                            //Erstmals gar nichts machen, Lampe aus
71
  
72
  winkel=5;
73
  takt=0;
74
  
75
  sei();
76
  
77
  for(;;)
78
  {  if(T_PIN&(1<<T_UP))
79
    {  entprellen();
80
      winkel+=1;
81
      if(winkel>10)  winkel=10;                //Für PLC mit FCPU=3,6864: winkel=74  Begrenz erstmals auf 62*2
82
    }
83
    
84
    if(T_PIN&(1<<T_DOWN))
85
    {  entprellen();
86
      winkel-=1;
87
      if(winkel<1)  winkel=1;
88
    }
89
    
90
    /*if(takt>=winkel)
91
    {  MOSFET_AUS;
92
    }
93
    if(takt>=20)                        //20*0,5ms=10ms
94
    {  MOSFET_EIN;
95
      if(takt>=winkel+20)
96
      {  MOSFET_AUS;
97
        TCNT0=0;
98
        takt=0;
99
        TIMSK&=~(1<<TOIE1);
100
      }
101
    }*/
102
  }
103
  
104
}
105
106
void entprellen(void)
107
{  unsigned char t=0xFF;
108
  //while( (T_PIN&(1<<T_UP)) || (T_PIN&(1<<T_DOWN)));
109
  while(t--);
110
}
111
112
ISR(INT0_vect)                            
113
{  char temp, sreg_temp, i;
114
115
  sei();
116
  
117
  if(flanke)                              //Für fallende Flanke
118
  {  /*Filter it to makes sure it was not only noise*/
119
    for (i=0; i<5; i++)                            //Five samples noise filter for LOW
120
    {  if(!(PIND & (1<<PD2)))    temp++;              //PD2 muss 5 Ticks LOW sein, dass gültig
121
      else            temp = RETURN;  
122
    }
123
    
124
    if(temp != RETURN)
125
    {  
126
      /*Place your zero cross action here*/
127
      
128
      MCUCR|=(1<<ISC01)|(1<<ISC00);                //Int0 auf steigende Flanke umschalten
129
      flanke = 0;
130
      
131
      MOSFET_EIN;
132
      TIMSK|=(1<<TOIE1);
133
      
134
      for(;;)
135
      {  if(takt>=winkel)
136
        {  MOSFET_AUS;
137
          takt=0;
138
          TCNT1=TEILER;
139
          TIMSK&=~(1<<TOIE1);
140
          break;
141
        }
142
      }
143
      
144
    }
145
  }
146
  
147
  if(flanke==0)                          //Für steigende Flanke
148
  {  /*Filter it to makes sure it was not only noise*/
149
    for (i=0; i<5; i++)                          //Five samples noise filter for LOW
150
    {  if(PIND&(1<<PD2))    temp++;              //PD2 muss 5 Ticks HIGH sein, dass gültig
151
      else          temp = RETURN;  
152
    }
153
    
154
    if(temp != RETURN)
155
    {  
156
      /*Place your zero cross action here*/
157
      
158
      MCUCR|=(1<<ISC01);                    //Int0 auf fallende Flanke umschalten
159
      flanke = 1;
160
      
161
      MOSFET_EIN;
162
      TIMSK|=(1<<TOIE1);
163
      
164
      for(;;)
165
      {  if(takt>=winkel)
166
        {  MOSFET_AUS;
167
          takt=0;
168
          TCNT1=TEILER;
169
          TIMSK&=~(1<<TOIE1);
170
          break;
171
        }
172
      }
173
      
174
    }
175
  }
176
177
}
178
179
ISR(TIMER1_OVF_vect)      //alle 0,5msec
180
{  takt++;
181
  TCNT1=TEILER;
182
}