0% found this document useful (0 votes)
131 views5 pages

#Include #Include #Include #Include

This document describes a program to control AC current in a load using a hysteresis controller. It uses a microcontroller with an ADC to measure the reference and actual currents, and generates PWM signals using MCPWM to control an inverter with two legs. The program implements a hysteresis controller that compares the current error to a band and switches the inverter states if it exceeds the band to regulate the current.

Uploaded by

Ferry aditya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
131 views5 pages

#Include #Include #Include #Include

This document describes a program to control AC current in a load using a hysteresis controller. It uses a microcontroller with an ADC to measure the reference and actual currents, and generates PWM signals using MCPWM to control an inverter with two legs. The program implements a hysteresis controller that compares the current error to a band and switches the inverter states if it exceeds the band to regulate the current.

Uploaded by

Ferry aditya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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

You might also like