Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Has anybody done this ? (AC >DC >AC converter)

Status
Not open for further replies.
I think TBL_POINTER_OLD and TBL_POINTER_NEW should be reset after every 10mS i.e. on overflow of 16 bit register like this.

Code:
void interrupt() {     
     if((TMR2IE_bit) && (TMR2IF_bit)) { 
        //Enter your code here
        
        //SET_FREQ = 65536 / (64 * 2) = 512
        //Required AC Frequency = 50 Hz
        //PWM Freq = 12821 Hz
        //Tpwm = 1/12.821 KHz = 78 us  (Timer2 Interrupt Period)
        //78 us * 64 * 2 = 9984 = 9.984 ms (for 180 degrees)
        //9.984 * 2 = 19.968 ms
        //AC freq = 1/19.968 ms = 50.08 Hz      
              
        TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        
        if(TBL_POINTER_NEW < TBL_POINTER_OLD) {
           CCP1CON.P1M1 = ~CCP1CON.P1M1;      //Reverse direction of full-bridge   
        [COLOR="#FF0000"]TBL_POINTER_NEW = 0;
        TBL_POINTER_OLD = 0;[/COLOR]
        
        }
        
        TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 10;
        DUTY_CYCLE = TBL_POINTER_SHIFT + adder;               
        
        //Assign PWM duty 10 bit        
        CCPR1L = (sine_table[DUTY_CYCLE] & 0x3FC) >> 2;
        CCP1CON.DC1B1 = (sine_table[DUTY_CYCLE] & 0x02) >> 1;
        CCP1CON.DC1B0 = (sine_table[DUTY_CYCLE] & 0x01);       
                       
        TBL_POINTER_OLD = TBL_POINTER_NEW; 
        
        TMR2IF_bit = 0;
 

@FvM

No, 4 MHz is enough because if Feedback value is > 512 then I am getting sinewave. I will try with 8 MHz and see what happens.

@swapan

No, ISR code is correct. The PWM direction is changed by toggling CCP1CON.P1M1 pin once every 10 ms that is every 180 degrees. Sine table is for 180 degrees.

@FvM

I debugged ISR code and it is taking 0.5 us.

Edit: Yes, Problem is with Oscillator frequency. Will see which frequency works fine.

When TBL_POINTER_NEW overflows it automatically becomes 0. No need to make it 0.

SET_FREQ is 512.
 
Last edited:

Hi,

I debugged ISR code and it is taking 0.5 us.
I doubt this. This are just 2 clock cycles of 4MHz.

Klaus
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

I think TBL_POINTER_OLD and TBL_POINTER_NEW should be reset after every 10mS i.e. on overflow of 16 bit register like this.
No, otherwise you'll loose the feature of varying the output frequency continuously. Overflow is intentional in a DDS generator.

The code isn't well considered, a 16-bit assignment isn't an "atomic" instruction with 8-bit processors. When
Code:
adder = FB_Step << 6
is interrupted in the middle of execution, an inconsistent adder value is used in the interrupt routine. Needs to be enclosed by interrupt disable/enable sequence.

- - - Updated - - -

Yes, Problem is with Oscillator frequency. Will see which frequency works fine.
Or clean up interrupt code. Table operations are long winded in 8-bit PIC. You shouldn't have three where one does it.
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
Re: Has anybody done this ? (AC &amp;gt;DC &amp;gt;AC converter)

Yes, you are write KlausST.

Here is the new code. I have changed the Timer2 Initialization code but problem still remains. Now Sinewave frequency is 100 Hz. Changed clock to 16 MHz Internal Oscillator. OSCCON and OSCTUNE are configured properly and also project settings are correct.

Yesterday without feedback code it was working fine and I was getting 50 Hz.

I have used mikroe Timer Calculator tool to generate Timer2 Initialization code.

When adc value is > 512 again there is Sinewave and for adc value < 512 signal is distorted but improved a little. I have to try FvM's method.

@swapan.

Made the changes you mentioned but no changes seen.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
 
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
 
#define MAX_DEMO_LIMIT 20
#define MAX_DEMO_LIMIT_ADDRESS 0x20
 
#define FBCh 0
 
unsigned char demo_limit = 0;
char msg[17];
unsigned char FB_Step = 0;
unsigned int FBV = 0, adder = 0;
 
const char msg1[] = "   Stabilizer   ";
const char msg2[] = "    Inverter    ";
const char msg3[] = "";
const char msg4[] = "";
 
const unsigned char sine_table[960] = {
    0,0,2,4,6,10,14,18,
    24,30,36,43,50,58,66,74,
    82,89,97,105,113,120,127,133,
    139,145,149,153,157,159,161,163,
    163,163,161,159,157,153,149,145,
    139,133,127,120,113,105,97,89,
    82,74,66,58,50,43,36,30,
    24,18,14,10,6,4,2,0,
    
    0,0,2,4,6,10,14,19,
    25,31,38,45,52,60,68,76,
    85,93,101,109,117,124,131,138,
    144,150,155,159,163,165,167,169,
    169,169,167,165,163,159,155,150,
    144,138,131,124,117,109,101,93,
    85,76,68,60,52,45,38,31,
    25,19,14,10,6,4,2,0,    
 
    0,0,2,4,7,10,15,20,
    26,32,39,46,54,62,70,79,
    88,96,105,113,121,129,136,143,
    149,155,160,165,168,171,173,175,
    175,175,173,171,168,165,160,155,
    149,143,136,129,121,113,105,96,
    88,79,70,62,54,46,39,32,
    26,20,15,10,7,4,2,0,
    
    0,0,2,4,7,11,15,21,
    27,33,40,48,56,64,73,82,
    91,99,108,117,125,133,141,148,
    154,160,166,170,174,177,179,181,
    181,181,179,177,174,170,166,160,
    154,148,141,133,125,117,108,99,
    91,82,73,64,56,48,40,33,
    27,21,15,11,7,4,2,0,
    
    0,0,2,4,7,11,16,21,
    28,34,42,50,58,67,76,85,
    94,103,112,121,130,138,146,154,
    160,167,172,177,181,184,186,188,
    188,188,186,184,181,177,172,167,
    160,154,146,138,130,121,112,103,
    94,85,76,67,58,50,42,34,
    28,21,16,11,7,4,2,0,
    
    0,0,2,4,7,11,16,22,
    28,35,43,51,60,69,78,87,
    97,107,116,125,134,143,151,159,
    166,172,178,183,187,190,192,194,
    194,194,192,190,187,183,178,172,
    166,159,151,143,134,125,116,107,
    97,87,78,69,60,51,43,35,
    28,22,16,11,7,4,2,0,
    
    0,0,2,4,8,12,17,23,
    29,37,44,53,62,71,80,90,
    100,110,120,129,138,147,156,163,
    171,177,183,188,192,196,198,200,
    200,200,198,196,192,188,183,177,
    171,163,156,147,138,129,120,110,
    100,90,80,71,62,53,44,37,
    29,23,17,12,8,4,2,0,
    
    0,0,2,4,8,12,17,23,
    30,38,46,54,64,73,83,93,
    103,113,123,133,142,152,160,168,
    176,183,189,194,198,202,204,206,
    206,206,204,202,198,194,189,183,
    176,168,160,152,142,133,123,113,
    103,93,83,73,64,54,46,38,
    30,23,17,12,8,4,2,0,
    
    0,1,2,5,8,13,18,24,
    31,39,47,56,66,76,86,96,
    107,117,127,137,147,157,166,174,
    182,189,195,200,205,208,211,212,
    213,212,211,208,205,200,195,189,
    182,174,166,157,147,137,127,117,
    107,96,86,76,66,56,47,39,
    31,24,18,13,8,5,2,1,
    
    0,1,2,5,8,13,18,25,
    32,40,49,58,68,78,88,99,
    110,120,131,141,151,161,170,179,
    187,194,201,206,211,214,217,218,
    219,218,217,214,211,206,201,194,
    187,179,170,161,151,141,131,120,
    110,99,88,78,68,58,49,40,
    32,25,18,13,8,5,2,1,
    
    0,1,2,5,9,13,19,26,
    33,41,50,59,69,80,91,101,
    113,124,134,145,156,166,175,184,
    192,199,206,212,216,220,223,224,
    225,224,223,220,216,212,206,199,
    192,184,175,166,156,145,134,124,
    113,101,91,80,69,59,50,41,
    33,26,19,13,9,5,2,1,
    
    0,1,2,5,9,14,19,26,
    34,42,51,61,71,82,93,104,
    116,127,138,149,160,170,180,189,
    197,205,212,217,222,226,229,230,
    231,230,229,226,222,217,212,205,
    197,189,180,170,160,149,138,127,
    116,104,93,82,71,61,51,42,
    34,26,19,14,9,5,2,1,
    
    0,1,2,5,9,14,20,27,
    35,44,53,63,73,84,96,107,
    119,131,142,154,165,175,185,194,
    203,211,218,224,229,233,236,237,
    238,237,236,233,229,224,218,211,
    203,194,185,175,165,154,142,131,
    119,107,96,84,73,63,53,44,
    35,27,20,14,9,5,2,1,
    
    0,1,2,5,9,14,21,28,
    36,45,54,64,75,87,98,110,
    122,134,146,157,169,180,190,199,
    208,216,223,230,235,239,242,243,
    244,243,242,239,235,230,223,216,
    208,199,190,180,169,157,146,134,
    122,110,98,87,75,64,54,45,
    36,28,21,14,9,5,2,1,
    
    0,1,2,5,10,15,21,28,
    37,46,56,66,77,89,101,113,
    125,137,149,161,173,184,194,204,
    213,222,229,235,240,245,248,249,
    250,249,248,245,240,235,229,222,
    213,204,194,184,173,161,149,137,
    125,113,101,89,77,66,56,46,
    37,28,21,15,10,5,2,1            
};
 
unsigned int TBL_POINTER_NEW = 0, TBL_POINTER_OLD = 0, TBL_POINTER_SHIFT = 0, DUTY_CYCLE = 0, SET_FREQ = 512;
 
//Timer2
//Prescaler 1:1; Postscaler 1:2; TMR2 Preload = 155; Actual Interrupt Time : 78 us
//Place/Copy this part in declaration section
void InitTimer2() {
    T2CON = 0x0C;
    TMR2IE_bit = 1;
    PR2 = 155;
    INTCON = 0xC0;
} 
 
void interrupt() {     
     if((TMR2IE_bit) && (TMR2IF_bit)) { 
        //Enter your code here
        
        //SET_FREQ = 65536 / (64 * 2) = 512
        //Required AC Frequency = 50 Hz
        //PWM Freq = 12821 Hz
        //Tpwm = 1/12.821 KHz = 78 us  (Timer2 Interrupt Period)
        //78 us * 64 * 2 = 9984 = 9.984 ms (for 180 degrees)
        //9.984 * 2 = 19.968 ms
        //AC freq = 1/19.968 ms = 50.08 Hz      
              
        TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        
        if(TBL_POINTER_NEW < TBL_POINTER_OLD) {
           CCP1CON.P1M1 = ~CCP1CON.P1M1;      //Reverse direction of full-bridge
           TBL_POINTER_NEW = 0;
           TBL_POINTER_OLD = 0;
                      
        }
        
        TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 10;
        DUTY_CYCLE = TBL_POINTER_SHIFT + adder;               
        
        //Assign PWM duty 10 bit        
        CCPR1L = (sine_table[DUTY_CYCLE] & 0x3FC) >> 2;
        CCP1CON.DC1B1 = (sine_table[DUTY_CYCLE] & 0x02) >> 1;
        CCP1CON.DC1B0 = (sine_table[DUTY_CYCLE] & 0x01);       
                       
        TBL_POINTER_OLD = TBL_POINTER_NEW; 
        
        TMR2IF_bit = 0;        
     }    
}
 
char *CopyConst2Ram(char *dest, const code char *src) {
    char *d;
 
    d = dest;
    
    for(;*dest++ = *src++;)asm clrwdt;
 
    return d;
}
 
void main() {
     
     asm clrwdt
     
     OSCCON = 0x77;
     OSCTUNE = 0x00;
                      
     /*
     demo_limit = EEPROM_Read(MAX_DEMO_LIMIT_ADDRESS);
     Delay_ms(20);
     
     if(demo_limit <= MAX_DEMO_LIMIT) {
        demo_limit++;
        EEPROM_Write(MAX_DEMO_LIMIT_ADDRESS, demo_limit);
        Delay_ms(20);
     }
     */
           
     CM1CON0 = 0x00;
     CM2CON0 = 0x00;
 
     SLRCON = 0x00;
 
     ADCON1 = 0x80;
     ADCON2 = 0b10110101;
     
     ANSELA = 0x01;
     ANSELB = 0x00;
     ANSELC = 0x00;
     ANSELD = 0x00;
     ANSELE = 0x00;
               
     TRISA = 0xC1;
     TRISB = 0x00;
     TRISC = 0x06;
     TRISD = 0xE0;
     TRISE = 0x00;
 
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     PORTE = 0x00;
 
     LATA = 0x00;
     LATB = 0x00;
     LATC = 0x00;
     LATD = 0x00;
     LATE = 0x00;
          
     //PWM4_Init(12821);
     //PWM4_Set_Duty(127);      //FAN
     //PWM4_Stop();
     //PWM4_Start();
 
     PWM3_Init(12821);
     PWM3_Set_Duty(0);
 
     CCP1CON.CCP1M3 = 1;
     CCP1CON.CCP1M2 = 1;
     CCP1CON.CCP1M1 = 0;
     CCP1CON.CCP1M0 = 0;
              
     CCP1CON.P1M0 = 1;
     CCP1CON.P1M1 = 0;
     
     Delay_ms(200);
     
     // Lcd code doesn't work if called after InitTimer2()
     // as ISR will be called every 78 us
          
     LCD_Init();                        
     LCD_Cmd(_LCD_CURSOR_OFF);
     LCD_Cmd(_LCD_CLEAR);
          
     LCD_Out(1,1,CopyConst2Ram(msg, msg1));
     
     InitTimer2();
         
     TRISC = 0x00;
     TRISD = 0x00;
        
     PWM3_Start();
                       
     while(1) {     
          
          asm clrwdt
          
          //if(demo_limit < MAX_DEMO_LIMIT) {
          
          //}
          
          FBV = ADC_Read(FBCh);
          
          if(FBV < 512) {
             if(++FB_Step > 14) {     // eg: 14 = (0 to 14) no. of pwm duty sets in the array
                FB_Step = 14;         // example if FB_Step = 15 then (see last line)
             }
          }
          else{
               if(FB_Step > 0) {
                  FB_Step--;
               }
          }
          
          adder = FB_Step << 6;      // << 6 because I have 2^6 = 64 entries in each pwm duty set
                                     // 14 << 6 =  896
                                     
                                     /* ********** code from ISR ***********
                                     TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        
                                     if(TBL_POINTER_NEW < TBL_POINTER_OLD) {
                                     CCP1CON.P1M1 = ~CCP1CON.P1M1;      //Reverse direction of full-bridge           
                                     }
        
                                     TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 10;
                                     DUTY_CYCLE = TBL_POINTER_SHIFT + adder;
                                     
                                     /* *************************************
                                     
                                     Eg: TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                         TBL_POINTER_NEW = 0 + 512;   //512
                                     
                                         TBL_POINTER_SHIFT = 512 >> 10; // 0
                                         
                                         DUTY_CYCLE = TBL_POINTER_SHIFT + adder;  //adder = 896, FB_Step = 14
                                         
                                         DUTY_CYCLE = 0 + 896;
                                         
                                     // In the 64 pwm duties (of each pwm duty set), each duty is called twice
                                     // to get 50 Hz
                                     
                                     TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                     // So, (SET_FREQ * 64 * 2) = 512 * 64 * 2 = 65536
                                     
                                     //So,
                                     
                                     Eg: TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                         TBL_POINTER_NEW = (65536 - 512) + 512;   //65536
                                     
                                         TBL_POINTER_SHIFT = 65536 >> 10; // 64
                                         
                                         DUTY_CYCLE = TBL_POINTER_SHIFT + adder;  //adder = 896, FB_Step = 14 
                                         
                                         DUTY_CYCLE = 64 + 896; //960 (last entry of the array that is 1) 
                                         
                                     */
                                           
                                      
     }
}



- - - Updated - - -

@FvM

Will this solve the problem you mentioned ?

Code:
switch(DUTY_CYCLE) {
             case 63*0x01:
             case 63*0x02:
             case 63*0x03:
             case 63*0x04:
             case 63*0x05:
             case 63*0x06:
             case 63*0x07:
             case 63*0x08:
             case 63*0x09:
             case 63*0x0A:
             case 63*0x0B:
             case 63*0x0C:
             case 63*0x0D:
             case 63*0x0E:
             case 63*0x0F:
             
		...

	     case 63*0x40:

                       adder = FB_Step << 6;
                       break;
};
 

Attachments

  • DS1Z_QuickPrint10.png
    DS1Z_QuickPrint10.png
    47.6 KB · Views: 72
  • DS1Z_QuickPrint11.png
    48.7 KB · Views: 74
  • Pure Sinewave Stabilizer Cum Inverter #2.rar
    85.8 KB · Views: 73

Re: Has anybody done this ? (AC &amp;amp;gt;DC &amp;amp;gt;AC converter)

Yes, it solved the problem of distorted signal. Here is the new code but is there a better and simpler way to do it ? I just added the switch statement.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
 
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
 
#define MAX_DEMO_LIMIT 20
#define MAX_DEMO_LIMIT_ADDRESS 0x20
 
#define FBCh 0
 
unsigned char demo_limit = 0;
char msg[17];
unsigned char FB_Step = 0;
unsigned int FBV = 0, adder = 0, previous_adder = 0; 
 
const char msg1[] = "   Stabilizer   ";
const char msg2[] = "    Inverter    ";
const char msg3[] = "";
const char msg4[] = "";
 
const unsigned char sine_table[960] = {
    0,0,2,4,6,10,14,18,
    24,30,36,43,50,58,66,74,
    82,89,97,105,113,120,127,133,
    139,145,149,153,157,159,161,163,
    163,163,161,159,157,153,149,145,
    139,133,127,120,113,105,97,89,
    82,74,66,58,50,43,36,30,
    24,18,14,10,6,4,2,0,
    
    0,0,2,4,6,10,14,19,
    25,31,38,45,52,60,68,76,
    85,93,101,109,117,124,131,138,
    144,150,155,159,163,165,167,169,
    169,169,167,165,163,159,155,150,
    144,138,131,124,117,109,101,93,
    85,76,68,60,52,45,38,31,
    25,19,14,10,6,4,2,0,    
 
    0,0,2,4,7,10,15,20,
    26,32,39,46,54,62,70,79,
    88,96,105,113,121,129,136,143,
    149,155,160,165,168,171,173,175,
    175,175,173,171,168,165,160,155,
    149,143,136,129,121,113,105,96,
    88,79,70,62,54,46,39,32,
    26,20,15,10,7,4,2,0,
    
    0,0,2,4,7,11,15,21,
    27,33,40,48,56,64,73,82,
    91,99,108,117,125,133,141,148,
    154,160,166,170,174,177,179,181,
    181,181,179,177,174,170,166,160,
    154,148,141,133,125,117,108,99,
    91,82,73,64,56,48,40,33,
    27,21,15,11,7,4,2,0,
    
    0,0,2,4,7,11,16,21,
    28,34,42,50,58,67,76,85,
    94,103,112,121,130,138,146,154,
    160,167,172,177,181,184,186,188,
    188,188,186,184,181,177,172,167,
    160,154,146,138,130,121,112,103,
    94,85,76,67,58,50,42,34,
    28,21,16,11,7,4,2,0,
    
    0,0,2,4,7,11,16,22,
    28,35,43,51,60,69,78,87,
    97,107,116,125,134,143,151,159,
    166,172,178,183,187,190,192,194,
    194,194,192,190,187,183,178,172,
    166,159,151,143,134,125,116,107,
    97,87,78,69,60,51,43,35,
    28,22,16,11,7,4,2,0,
    
    0,0,2,4,8,12,17,23,
    29,37,44,53,62,71,80,90,
    100,110,120,129,138,147,156,163,
    171,177,183,188,192,196,198,200,
    200,200,198,196,192,188,183,177,
    171,163,156,147,138,129,120,110,
    100,90,80,71,62,53,44,37,
    29,23,17,12,8,4,2,0,
    
    0,0,2,4,8,12,17,23,
    30,38,46,54,64,73,83,93,
    103,113,123,133,142,152,160,168,
    176,183,189,194,198,202,204,206,
    206,206,204,202,198,194,189,183,
    176,168,160,152,142,133,123,113,
    103,93,83,73,64,54,46,38,
    30,23,17,12,8,4,2,0,
    
    0,1,2,5,8,13,18,24,
    31,39,47,56,66,76,86,96,
    107,117,127,137,147,157,166,174,
    182,189,195,200,205,208,211,212,
    213,212,211,208,205,200,195,189,
    182,174,166,157,147,137,127,117,
    107,96,86,76,66,56,47,39,
    31,24,18,13,8,5,2,1,
    
    0,1,2,5,8,13,18,25,
    32,40,49,58,68,78,88,99,
    110,120,131,141,151,161,170,179,
    187,194,201,206,211,214,217,218,
    219,218,217,214,211,206,201,194,
    187,179,170,161,151,141,131,120,
    110,99,88,78,68,58,49,40,
    32,25,18,13,8,5,2,1,
    
    0,1,2,5,9,13,19,26,
    33,41,50,59,69,80,91,101,
    113,124,134,145,156,166,175,184,
    192,199,206,212,216,220,223,224,
    225,224,223,220,216,212,206,199,
    192,184,175,166,156,145,134,124,
    113,101,91,80,69,59,50,41,
    33,26,19,13,9,5,2,1,
    
    0,1,2,5,9,14,19,26,
    34,42,51,61,71,82,93,104,
    116,127,138,149,160,170,180,189,
    197,205,212,217,222,226,229,230,
    231,230,229,226,222,217,212,205,
    197,189,180,170,160,149,138,127,
    116,104,93,82,71,61,51,42,
    34,26,19,14,9,5,2,1,
    
    0,1,2,5,9,14,20,27,
    35,44,53,63,73,84,96,107,
    119,131,142,154,165,175,185,194,
    203,211,218,224,229,233,236,237,
    238,237,236,233,229,224,218,211,
    203,194,185,175,165,154,142,131,
    119,107,96,84,73,63,53,44,
    35,27,20,14,9,5,2,1,
    
    0,1,2,5,9,14,21,28,
    36,45,54,64,75,87,98,110,
    122,134,146,157,169,180,190,199,
    208,216,223,230,235,239,242,243,
    244,243,242,239,235,230,223,216,
    208,199,190,180,169,157,146,134,
    122,110,98,87,75,64,54,45,
    36,28,21,14,9,5,2,1,
    
    0,1,2,5,10,15,21,28,
    37,46,56,66,77,89,101,113,
    125,137,149,161,173,184,194,204,
    213,222,229,235,240,245,248,249,
    250,249,248,245,240,235,229,222,
    213,204,194,184,173,161,149,137,
    125,113,101,89,77,66,56,46,
    37,28,21,15,10,5,2,1            
};
 
unsigned int TBL_POINTER_NEW = 0, TBL_POINTER_OLD = 0, TBL_POINTER_SHIFT = 0, DUTY_CYCLE = 0, SET_FREQ = 512;
 
//Timer2
//Prescaler 1:1; Postscaler 1:2; TMR2 Preload = 155; Actual Interrupt Time : 78 us
//Place/Copy this part in declaration section
void InitTimer2() {
    T2CON = 0x0C;
    TMR2IE_bit = 1;
    PR2        = 155;
    INTCON = 0xC0;
} 
 
void interrupt() {     
     if((TMR2IE_bit) && (TMR2IF_bit)) { 
        //Enter your code here
        
        //SET_FREQ = 65536 / (64 * 2) = 512
        //Required AC Frequency = 50 Hz
        //PWM Freq = 12821 Hz
        //Tpwm = 1/12.821 KHz = 78 us  (Timer2 Interrupt Period)
        //78 us * 64 * 2 = 9984 = 9.984 ms (for 180 degrees)
        //9.984 * 2 = 19.968 ms
        //AC freq = 1/19.968 ms = 50.08 Hz      
              
        TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        
        if(TBL_POINTER_NEW < TBL_POINTER_OLD) {
           CCP1CON.P1M1 = ~CCP1CON.P1M1;      //Reverse direction of full-bridge
           TBL_POINTER_NEW = 0;
           TBL_POINTER_OLD = 0;
                      
        }
        
        TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 10;
        DUTY_CYCLE = TBL_POINTER_SHIFT + adder;               
        
        //Assign PWM duty 10 bit        
        CCPR1L = (sine_table[DUTY_CYCLE] & 0x3FC) >> 2;
        CCP1CON.DC1B1 = (sine_table[DUTY_CYCLE] & 0x02) >> 1;
        CCP1CON.DC1B0 = (sine_table[DUTY_CYCLE] & 0x01);       
                       
        TBL_POINTER_OLD = TBL_POINTER_NEW; 
        
        TMR2IF_bit = 0;        
     }    
}
 
char *CopyConst2Ram(char *dest, const code char *src) {
    char *d;
 
    d = dest;
    
    for(;*dest++ = *src++;)asm clrwdt;
 
    return d;
}
 
void main() {
     
     asm clrwdt
     
     OSCCON = 0x77;
     OSCTUNE = 0x00;
                      
     /*
     demo_limit = EEPROM_Read(MAX_DEMO_LIMIT_ADDRESS);
     Delay_ms(20);
     
     if(demo_limit <= MAX_DEMO_LIMIT) {
        demo_limit++;
        
        EEPROM_Write(MAX_DEMO_LIMIT_ADDRESS, demo_limit);
        Delay_ms(20);
     }
     */
           
     CM1CON0 = 0x00;
     CM2CON0 = 0x00;
 
     SLRCON = 0x00;
 
     ADCON1 = 0x80;
     ADCON2 = 0b10110101;
     
     ANSELA = 0x01;
     ANSELB = 0x00;
     ANSELC = 0x00;
     ANSELD = 0x00;
     ANSELE = 0x00;
               
     TRISA = 0xC1;
     TRISB = 0x00;
     TRISC = 0x06;
     TRISD = 0xE0;
     TRISE = 0x00;
 
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
     PORTD = 0x00;
     PORTE = 0x00;
 
     LATA = 0x00;
     LATB = 0x00;
     LATC = 0x00;
     LATD = 0x00;
     LATE = 0x00;
          
     //PWM4_Init(12821);
     //PWM4_Set_Duty(127);      //FAN
     //PWM4_Stop();
     //PWM4_Start();
 
     PWM3_Init(12821);
     PWM3_Set_Duty(0);
 
     CCP1CON.CCP1M3 = 1;
     CCP1CON.CCP1M2 = 1;
     CCP1CON.CCP1M1 = 0;
     CCP1CON.CCP1M0 = 0;
              
     CCP1CON.P1M0 = 1;
     CCP1CON.P1M1 = 0;
     
     Delay_ms(200);
     
     // Lcd code doesn't work if called after InitTimer2()
     // as ISR will be called every 78 us
          
     LCD_Init();                        
     LCD_Cmd(_LCD_CURSOR_OFF);
     LCD_Cmd(_LCD_CLEAR);
          
     LCD_Out(1,1,CopyConst2Ram(msg, msg1));
     
     InitTimer2();
         
     TRISC = 0x00;
     TRISD = 0x00;
        
     PWM3_Start();
                       
     while(1) {     
          
          asm clrwdt
          
          //if(demo_limit < MAX_DEMO_LIMIT) {
          
          //}
          
          FBV = ADC_Read(FBCh);
          
          if(FBV < 512) {
             if(++FB_Step > 14) {     // eg: 14 = (0 to 14) no. of pwm duty sets in the array
                FB_Step = 14;         // example if FB_Step = 15 then (see last line)
             }
          }
          else{
               if(FB_Step > 0) {
                  FB_Step--;
               }
          }
          
          switch(DUTY_CYCLE) {
             case 63*0x01:
             case 63*0x02:
             case 63*0x03:
             case 63*0x04:
             case 63*0x05:
             case 63*0x06:
             case 63*0x07:
             case 63*0x08:
             case 63*0x09:
             case 63*0x0A:
             case 63*0x0B:
             case 63*0x0C:
             case 63*0x0D:
             case 63*0x0E:
             case 63*0x0F:
             
             case 63*0x11:
             case 63*0x12:
             case 63*0x13:
             case 63*0x14:
             case 63*0x15:
             case 63*0x16:
             case 63*0x17:
             case 63*0x18:
             case 63*0x19:
             case 63*0x1A:
             case 63*0x1B:
             case 63*0x1C:
             case 63*0x1D:
             case 63*0x1E:
             case 63*0x1F:
             
             case 63*0x21:
             case 63*0x22:
             case 63*0x23:
             case 63*0x24:
             case 63*0x25:
             case 63*0x26:
             case 63*0x27:
             case 63*0x28:
             case 63*0x29:
             case 63*0x2A:
             case 63*0x2B:
             case 63*0x2C:
             case 63*0x2D:
             case 63*0x2E:
             case 63*0x2F:
             
             case 63*0x31:
             case 63*0x32:
             case 63*0x33:
             case 63*0x34:
             case 63*0x35:
             case 63*0x36:
             case 63*0x37:
             case 63*0x38:
             case 63*0x39:
             case 63*0x3A:
             case 63*0x3B:
             case 63*0x3C:
             case 63*0x3D:
             case 63*0x3E:
             case 63*0x3F:             
             
                       adder = FB_Step << 6;
                       break;             
          }
                    
                // << 6 because I have 2^6 = 64 entries in each pwm duty set
                                     // 14 << 6 =  896
                                     
                                     /* ********** code from ISR ***********
                                     TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
        
                                     if(TBL_POINTER_NEW < TBL_POINTER_OLD) {
                                     CCP1CON.P1M1 = ~CCP1CON.P1M1;      //Reverse direction of full-bridge           
                                     }
        
                                     TBL_POINTER_SHIFT = TBL_POINTER_NEW >> 10;
                                     DUTY_CYCLE = TBL_POINTER_SHIFT + adder;
                                     
                                     /* *************************************
                                     
                                     Eg: TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                         TBL_POINTER_NEW = 0 + 512;   //512
                                     
                                         TBL_POINTER_SHIFT = 512 >> 10; // 0
                                         
                                         DUTY_CYCLE = TBL_POINTER_SHIFT + adder;  //adder = 896, FB_Step = 14
                                         
                                         DUTY_CYCLE = 0 + 896;
                                         
                                     // In the 64 pwm duties (of each pwm duty set), each duty is called twice
                                     // to get 50 Hz
                                     
                                     TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                     // So, (SET_FREQ * 64 * 2) = 512 * 64 * 2 = 65536
                                     
                                     //So,
                                     
                                     Eg: TBL_POINTER_NEW = TBL_POINTER_OLD + SET_FREQ;
                                     
                                         TBL_POINTER_NEW = (65536 - 512) + 512;   //65536
                                     
                                         TBL_POINTER_SHIFT = 65536 >> 10; // 64
                                         
                                         DUTY_CYCLE = TBL_POINTER_SHIFT + adder;  //adder = 896, FB_Step = 14 
                                         
                                         DUTY_CYCLE = 64 + 896; //960 (last entry of the array that is 1) 
                                         
                                     */
                                           
                                      
     }
}



134506d1481732093-ds1z_quickprint12.png


- - - Updated - - -

Edit:

Changed SET_FREQ value and got 50 Hz.

Code:
SET_FREQ = 256;

Have to do the calculation and cross check it once again.

You can see in picture13 that frequency is 50 Hz.


134507d1481734379-ds1z_quickprint13.png
 

Attachments

  • DS1Z_QuickPrint12.png
    47 KB · Views: 165
  • DS1Z_QuickPrint13.png
    49.8 KB · Views: 159

Re: Has anybody done this ? (AC &amp;amp;gt;DC &amp;amp;gt;AC converter)

@FvM

Or clean up interrupt code. Table operations are long winded in 8-bit PIC. You shouldn't have three where one does it.

What do you mean by this ?

Which three instructions I have to replace by one ? Assigning sine_table[] values to CCPR1L ?


I decided to use SPI communication between the 5 PICs on the 5 boards.

See attached files and tell me whether the PCB layout is OK for 230V 50Hz AC input and 325V DC output. This circuit is for getting 325V VBUS Voltage just for testing the Full-Bridge board on hardware. I just need to get 230V Constant AC from constant 325V DC for different loads. I also need to check if feedback works fine on hardware to give constant 230V AC output. The Bottom Layer Mirror PDF shows the actual size of the PCB. Is track clearance Ok ?


For PCB track width I used this calculator

https://www.4pcb.com/trace-width-calculator.html

with

10 Amps
2 oz/ft^2
30 degree C rise in temperature
25 degree ambient temperature

Results for external layer in Air 72.7 mils

I will put upto 4A load for testing the Full-Bridge Driver board. I have 10x probe which can measure 300V rms. Do I need 100x probe for safe measuring the output of Full-Bridge.

Also what multimeter I have to use to measure 325V DC ?


I had designed the RC filer for 50 Hz. When frequency was 100 Hz how it passed through filter ?
 

Attachments

  • VBUS Board Bottom 3D View.pdf
    362.9 KB · Views: 115
  • VBUS Board Bottom Layer Mirror.pdf
    4.3 KB · Views: 81
  • VBUS Board Top 3D View.pdf
    343.7 KB · Views: 84
  • VBUS Voltage Generation.PDF
    20.9 KB · Views: 71
Last edited:

I was particularly referring to this code lines.
Code:
CCPR1L = (sine_table[DUTY_CYCLE] & 0x3FC) >> 2;
CCP1CON.DC1B1 = (sine_table[DUTY_CYCLE] & 0x02) >> 1;
CCP1CON.DC1B0 = (sine_table[DUTY_CYCLE] & 0x01);
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

I was particularly referring to this code lines.

There was a issue regarding that and still it exists. Maybe it is mikroC PRO PIC problem. Actually I am using ECCP 10-bit but you can see that my pwm duty values are 8-bit. If I use 10-bit pwm duty then I was not getting Sinewave. Till now I am not able to find a work around for that. I had just experimented and the above code had worked in obtaining Sinewave.

Referring the Littlefuse document I calculated this

Po(stabilizer/inverter) = 800w

Ipk = (800W/230V) * 1.4142 = 5A

Ideal Fuse Rating = Normal Operating Current / (Temp rerating factor * 0.75)

= 5A / (0.88 * 0.75) = 7.575 = ~ 7.6A

Should I use a >= 7.6A Fast-blow fuse ? Fuses shown in attached circuit.


Regarding NTC Thermistor I referred this document.

**broken link removed**

I need NTC for the VBUS generation test circuit mentioned in post #47,

Can I safely use this document for NTC calculation ?

See attached circuit. Do I need any resistors on the SPI lines ? I think SPI is better for communicating with other micrcontrollers on other boards. I2C needs Interrupt and Full-Bridge board PIC will be executing ISR once every 78 us and the code inside ISR takes 48us and it won't get much time to do other things. UART also need ISR.

- - - Updated - - -

Edit:

@FvM

As I mentioned in post #49, if I use 10-bit duty values then I get this signal. I had earlier tested this in Proteus. Till now I have not found solution for it and that's why I used 8-bit duty values with ECCP.


Code C - [expand]
1
2
3
4
5
6
const code unsigned int sine_table[64] = {
    0,2,10,22,38,59,85,114,147,183,223,265,310,356,404,452,
    502,551,599,647,693,738,780,820,856,889,918,944,965,981,993,1001,
    1003,1001,993,981,965,944,918,889,856,820,780,738,693,647,599,551,
    502,452,404,356,310,265,223,183,147,114,85,59,38,22,10,2    
};



Tested this code without feedback code.


134526d1481754593-ds1z_quickprint14.png
 

Attachments

  • Littelfuse_Application Note Slow vs Fast Auto Fuses.pdf
    184.1 KB · Views: 90
  • Full-Bridge Board.PDF
    48.4 KB · Views: 63
  • DS1Z_QuickPrint14.png
    44.4 KB · Views: 146

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

Updated Full-Bridge Driver Board (not yet complete).



In this page see what McChalium says

**broken link removed**

According to this I need another LM35DZ sticked to NTC to monitor its temperature and control the Full-Bridge.
 

Attachments

  • Full-Bridge Board.PDF
    61.7 KB · Views: 87
Last edited:

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

mikroC PRO PIC projects which uses 8-bit and 10-bit pwm duties. Proteus simulation shows distorted signal for 10-bit pwm duty same as mentioned in previous post. Proteus file included if anybody needs to simulate.

Edit:

PIC18F46K22 Rev F datasheet page 188. I got this value

PWM Resolution = log[4 * (PRx + 1)] / log(2)

= log10[4 * (155 + 1)] / log10(2)

= log10(624) / log10(2)

= 2.795 / 0.3

= 9.316

Have to try 9-bit pwm duty and see if it gives Sinewave.
 

Attachments

  • Edaboard #1.rar
    144.3 KB · Views: 74
  • 8-Bit PWM Duty.png
    8-Bit PWM Duty.png
    130.6 KB · Views: 63
  • 10-Bit PWM Duty.png
    10-Bit PWM Duty.png
    131.2 KB · Views: 70
Last edited:

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

Edit:

It worked. 9-bit pwm duty works.
 

Attachments

  • 9-Bit PWM Duty.png
    9-Bit PWM Duty.png
    130.1 KB · Views: 69
  • Pure Sinewave Stabilizer Cum Inverter -9-Bit PWM Duty.rar
    51.6 KB · Views: 67

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

No body mentioned the mistake in the circuit of post #50 and others. Actually I am using Full-Bridge signals from PIC and I simply cannot use IR2184. I have to use IR2112 or similar FET drivers. I have attached the fixed schematic.
 

Attachments

  • Full-Bridge Driver Board.PDF
    48.5 KB · Views: 92

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

PCB layout is being designed for this project.

I want to know how to place the Full-Bridge mosfets on Heatsinks ? Do I need 2 Heat-sinks or 4 ?
 

Re: Has anybody done this ? (AC &gt;DC &gt;AC converter)

For testing purpse I will be using this mosfet as it is cheaper

https://www.mouser.in/ProductDetail...ptY3T%2bp3PYvxzHQFFcRBhA9uNt/dy88mbFAUjfgSA==

and for final production I will be using

https://www.mouser.in/ProductDetail...tt%2b8fK0YFwXF6PRfCFBOBjLqwPpJv/QZK9oInU1Tg==

If I use STW56N60DM2 then power dissipated in each mosfet is 0.06 * 36A^2 = 2.16W. I have total of 8 Mosfets in the Stabilizer part of the circuit (4 for Buck-Boost Converter and 4 for Full-Bridge Driver).

Approx 16W power is disspated in total in mosfets.

For 2.16W (when full load for 800W Stabilizer) do I need a heatsink. I have fans but do I still need heatsinks ?

What is the value of 2.16W in degree C ?
 

Hi,

What is the value of 2.16W in degree C ?

...simply multiply: P_d x R_th to get the temperature rise.

Klaus
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top