Sie sind auf Seite 1von 5

1 /*

2 PROGRAM untuk mengontrol arus AC pada beban dengan metode Hysterisis controller
3 frequency kerja=50 Hz
4 referensi arus diatur lewat potensio, pin AN0 (CH1)
5 arus aktual diakses sensor yang terkoneksi pin AN7 (CH0)
6
7 Peripheral yang digunakan
8
9 MCPWM:
10 1. FPWM = 10.000 hz (10kHz)
11 2. Complementary PWMs with center aligned
12 3. Set ADC to be triggered by PWM special trigger with 5 KHz
(postscaler=2)
13 4. Set deadtime to be 20 us
14 5. Polarity PWM output: Active LOW
15 6. Koneksi Output : Two legs Inverter
16 PWM1L (RE0)
17 PWM1H (RE1)
18 PWM2L (RE2)
19 PWM2H (RE3)
20
21
22 ADC:
23 1. Format data : signed fraction
24 2. sampling : simultan ( CH0=AN7, CH1=AN0, CH2=AN1, CH3=AN2)
25 3. konversi : auto dipicu oleh PWM dg rate 5 Khz (0.0002 detik)
26 4. ADC interupsi : On ( pengolahan data ditempatkan di vektor
interupsi ADC)
27 5. Koneksi input (default)
28 POTENSIO untuk mengubah magnitude arus sinusoidal (0-1)
: pin AN7 (CH0) :ADCBUF0
29 sensor arus
: pin AN0 (CH1) :ADCBUF1
30
31
32 PROGRAMED BY : IWAN SETIAWAN
33 TEKNIK ELEKTRO UNDIP
34 */
35
36 #include <p30F4011.h>
37 #include <libpic30.h>
38 #include <dsp.h>
39 #include <libq.h>
40
41
42 /*INSTRUKSI KONVIGURASI*/
43 //Device Configuration : Fcy dll
44 // Primary Oscillator Mode = XT 10 Mhz with PLL 8x.
45 // clock kristal= XTL 80000000UL //clock kristal 10 MHz x PLL8 //Fcy =20 MIPs (XTL/4)
46
47 _FOSC(CSW_FSCM_OFF & XT_PLL8);
48 _FWDT(WDT_OFF);
49 _FBORPOR(PBOR_OFF & PWRT_64 & MCLR_EN & PWMxH_ACT_LO & PWMxL_ACT_LO); //pwm active
LOW (active HIGH:PWMxH_ACT_HI& PWMxL_ACT_HI)
50
51
52 void InitMCPWM(void);
53 void InitADC10Simultan(void);
54 void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt (void);
55
56 const int SIN_TABLE[256] =
57 {
58 0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179, 7962, 8739, 9512, 10278,
11039, 11793, 12539, 13279, 14010, 14732,
59 15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594,
23170, 23731, 24279, 24811, 25329, 25832,
60 26319, 26790, 27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956, 30273, 30571,
30852, 31113, 31356, 31580, 31785, 31971,
61 32137, 32285, 32412, 32521, 32609, 32678, 32728, 32757, 32767, 32757, 32728, 32678,
32609, 32521, 32412, 32285, 32137, 31971,
62 31785, 31580, 31356, 31113, 30852, 30571, 30273, 29956, 29621, 29268, 28898, 28510,
28105, 27683, 27245, 26790, 26319, 25832,
63 25329, 24811, 24279, 23731, 23170, 22594, 22005, 21403, 20787, 20159, 19519, 18868,
18204, 17530, 16846, 16151, 15446, 14732,
64 14010, 13279, 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179, 6393, 5602, 4808,
4011, 3212, 2410, 1608, 804, 0, -804, -1608,
65 -2410, -3212, -4011, -4808, -5602, -6393, -7179, -7962, -8739, -9512, -10278,
-11039, -11793, -12539, -13279, -14010, -14732, -15446,
66 -16151, -16846, -17530, -18204, -18868, -19519, -20159, -20787, -21403, -22005,
-22594, -23170, -23731, -24279, -24811, -25329, -25832,
67 -26319, -26790, -27245, -27683, -28105, -28510, -28898, -29268, -29621, -29956,
-30273, -30571, -30852, -31113, -31356, -31580, -31785,
68 -31971, -32137, -32285, -32412, -32521, -32609, -32678, -32728, -32757, -32767,
-32757, -32728, -32678, -32609, -32521, -32412, -32285,
69 -32137, -31971, -31785, -31580, -31356, -31113, -30852, -30571, -30273, -29956,
-29621, -29268, -28898, -28510, -28105, -27683, -27245,
70 -26790, -26319, -25832, -25329, -24811, -24279, -23731, -23170, -22594, -22005,
-21403, -20787, -20159, -19519, -18868, -18204, -17530,
71 -16846, -16151, -15446, -14732, -14010, -13279, -12539, -11793, -11039, -10278,
-9512, -8739, -7962, -7179, -6393, -5602, -4808, -4011,
72 -3212, -2410, -1608, -804
73 };
74
75 #define FCY 20000000 // xtal = 10Mhz; PLLx8 -> 20 MIPS
76 #define FPWM 10000 // 10 kHz,
77 #define DEADTIME (unsigned int)(0.000002 * FCY) //~2 us of dead time @ 20 MIPS and
1:1 Prescaler
78 #define UI_PTPER (FCY/FPWM - 1) >> 1 // UI_PTPER=999 untk fpwm=10khz
79
80 #define SI_Kp Q15(0.9999)
81
82 #define MIDLE 32768
83
84 //BASE_OMEGA= 2*pi*50 rad/s (=50Hz)
85 //BASE_THETA =2*pi
86 //Ts=0.0002 s (0.2ms)
87 #define UI_DELTA_THETA 655 // untuk updating theta ->
K_D_THETA=(Ts*BASE_OMEGA/BASE_THETA)=0.01=655(2^-16)
88
89 //define nilai hysterisis band 0.05
90 #define HYS Q15(0.05)
91
92 //deklarasi variable global
93 unsigned int UI_mag_current_ref_pu;
94 unsigned int UI_theta_index; //pointer ke tabel sinus 8 bit (perlu digeser 8 bit)
95 unsigned char UC_indexA;
96 int SI_sin_theta_A; //nilai fraction :-1->0.99999(1)
97 int SI_current_ref_pu, SI_current_actual_pu, SI_current_error_pu,
SI_current_negerror_pu;
98 int SI_outP_pu,SI_outP_neg_pu;
99
100 //untuk variabel lokal
101 unsigned int UI_delta_theta;
102 signed int SI_dumy1,SI_dumy2;
103 enum {WAIT, HIGH, LOW};
104 unsigned char state_leg1, state_leg2;
105 unsigned char control_1, control_2;
106
107 int main()
108 {
109 //Init
110 InitMCPWM();
111 InitADC10Simultan();
112 OVDCON=0b0000000000000000;
113 state_leg1=WAIT; //inisialisasi leg 1 standby state
114 state_leg2=WAIT; //inisialisasi leg 2 standby state
115 UI_theta_index=0; //inisialisasi indek tabel sinus
116 IEC0bits.ADIE=1; //A/D Conversion Complete Interrupt Enable bit
117 while(1)
118 {
119
120 }
121 return 0;
122 }
123
124
125 //rutin pembangkitan sinyal SPWM dieksekusi dengan frekuensi 5Kh (setiap 0.0002 S)
126 void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt (void)
127 {
128
129
130 IFS0bits.ADIF = 0; // Clear ADC interrupt flag
131
132 //baca nilai ADC dan lakukan normalisasi sehingga nilai magnitude dan frekuensi
selalu bernilai positive
133 UI_mag_current_ref_pu = ADCBUF0+MIDLE; //normalisasi pembacaan ADC-> -1:1
(SI)--->0->1(UI)
134 SI_current_actual_pu = ADCBUF1;
135
136 //update index 0:1
137 UI_theta_index=UI_theta_index+UI_DELTA_THETA;
138 UC_indexA=(unsigned char)(UI_theta_index>>8);
139 //hitung sin dari tabel 8 bit
140 SI_sin_theta_A=SIN_TABLE[UC_indexA]; //=>range -1:1
141
142 //update sinyal referensi sinusoidal,
143 SI_current_ref_pu=__builtin_mulus(UI_mag_current_ref_pu,SI_sin_theta_A)>>16;
//(UIxSI)=Signed long Int (32 bit) =>range -1:1
144
145 //hitung error
146 SI_current_error_pu= _Q15sub(SI_current_ref_pu,SI_current_actual_pu);//range:
-1:1
147 SI_current_negerror_pu=_Q15neg(SI_current_error_pu);
148
149 //hysterisis leg 1
150 switch(state_leg1)
151 {
152 case WAIT: if(SI_current_error_pu > HYS)
153 {
154 control_1=OVDCON|0b0000000000000010;
155 state_leg1=HIGH;
156 }
157 if (SI_current_error_pu < -HYS)
158 {
159 control_1=OVDCON|0b0000000000000001;
160 state_leg1=LOW;
161 }
162 break;
163
164 case HIGH: if(SI_current_error_pu < -HYS)
165 {
166 control_1=control_1^0b0000000000000011;
167 state_leg1=LOW;
168 }
169 break;
170
171 case LOW: if(SI_current_error_pu > HYS)
172 {
173 control_1=control_1^0b0000000000000011;
174 state_leg1=HIGH;
175 }
176 break;
177 }
178
179 //hysterisis leg 2
180 switch(state_leg2)
181 {
182 case WAIT: if(SI_current_negerror_pu > HYS)
183 {
184 control_2=OVDCON|0b0000000000001000;
185 state_leg2=HIGH;
186 }
187 if (SI_current_negerror_pu < -HYS)
188 {
189 control_2=OVDCON|0b0000000000000100;
190 state_leg2=LOW;
191 }
192 break;
193
194 case HIGH: if(SI_current_negerror_pu < -HYS)
195 {
196 control_2=control_2^0b0000000000001100;
197 state_leg2=LOW;
198 }
199 break;
200
201 case LOW: if(SI_current_negerror_pu > HYS)
202 {
203 control_2=control_2^0b0000000000001100;
204 state_leg2=HIGH;
205 }
206 break;
207 }
208
209 //update sinyal kontrol
210 OVDCON=control_1|control_2;
211
212 SI_outP_pu=__builtin_mulss(SI_Kp,SI_current_error_pu)>>15;
213 SI_outP_neg_pu=_Q15neg(SI_outP_pu);
214
215 //sinyal sinus dinormaslisasi menjadi -PTPER(-999):PTPER(999)
216 SI_dumy1=__builtin_mulus(UI_PTPER,SI_outP_pu)>>15; // (UIxSI)=Signed long Int
(32 bit)
217 SI_dumy2=__builtin_mulus(UI_PTPER,SI_outP_neg_pu)>>15; //
218
219
220 //tambahkan offset sebesar PTPER
221 PDC1 = SI_dumy1+PTPER; //range (0-2PTPER)= 0-2*999
222 PDC2 = SI_dumy2+PTPER;
223 return;
224 }
225
226 // inisialisasi PWM
227 //
228 void InitMCPWM(void)
229 {
230 TRISE = 0x0100; // PWM pins as outputs, and FLTA as input
231 PTPER = UI_PTPER; // Compute Period based on CPU speed and
232 // required PWM frequency (see defines)
233 //PTPER=999
234
235 DTCON1 = DEADTIME; // lihat #define
236 PWMCON1 = 0x0077; // Enable PWM output pins and configure them as
237 // complementary mode
238 PDC1 = UI_PTPER; // Initialize as 0 average: Duty Cycle=50%
239 PDC2 = UI_PTPER; // Initialize as 0
240 PDC3 = UI_PTPER; // Initialize as 0
241 SEVTCMP = 1; // Enable triggering for ADC
242 PWMCON2 = 0x0102; // 2 postscale values, PWMCON2=0x0102: 2 postscale for
interupt adc 10/2=5 KHz
243 PTCON = 0x8002; // start PWM as center aligned mode;prescaler=1:1
244 OVDCON = 0x0F00; // enable PWM0-3: Configure PWM0-3 to be governed by PWM
module
245 return;
246 }
247
248 //********************************************************************
249 //inisialisasi ADC
250 // sampling dilakukan secara simultan
251 //konversi Analog to digital dipicu oleh PWM dg frekuensi 5Khz
252 //FORMAT data signed fraction
253 void InitADC10Simultan(void)
254 {
255 ADCON1 = 0;
256 // Signed fractional (DOUT = sddd dddd dd00 0000)
257 ADCON1bits.FORM = 3;
258 // Motor Control PWM interval ends sampling and starts conversion
259 ADCON1bits.SSRC = 3;
260 // Simultaneous Sample Select bit (only applicable when CHPS = 01 or 1x)
261 // Samples CH0, CH1, CH2, CH3 simultaneously (when CHPS = 1x)
262 // Samples CH0 and CH1 simultaneously (when CHPS = 01)
263 ADCON1bits.SIMSAM = 1;
264 // Sampling begins immediately after last conversion completes.
265 // SAMP bit is auto set.
266 ADCON1bits.ASAM = 1;
267 ADCON2 = 0;
268 // Samples CH0, CH1, CH2, CH3 simultaneously (when CHPS = 1x)
269 ADCON2bits.CHPS = 2;
270 ADCON3 = 0;
271 // A/D Conversion Clock Select bits = 8 * Tcy
272 ADCON3bits.ADCS = 15;
273 /* ADCHS: ADC Input Channel Select Register */
274 ADCHS = 0;
275 // CH0 is AN7
276 ADCHSbits.CH0SA = 7;
277 // CH1 positive input is AN0, CH2 positive input is AN1, CH3 positive input is AN2
278 ADCHSbits.CH123SA = 0;
279 /* ADPCFG: ADC Port Configuration Register */
280 // Set all ports digital
281 ADPCFG = 0xFFFF;
282 ADPCFGbits.PCFG0 = 0; // AN0 analog
283 ADPCFGbits.PCFG1 = 0; // AN1 analog
284 ADPCFGbits.PCFG2 = 0; // AN2 analog
285 ADPCFGbits.PCFG7 = 0; // AN7 analog
286 /* ADCSSL: ADC Input Scan Select Register */
287 ADCSSL = 0;
288
289 // Turn on A/D module
290 ADCON1bits.ADON = 1;
291 return;
292 }
293

Das könnte Ihnen auch gefallen