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.

pic18f4431continues pwm generation without delays.

Status
Not open for further replies.

bilal_sheikh

Junior Member level 1
Joined
Oct 15, 2014
Messages
17
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
155
hello all, recently i am working on a project that is variable frequency drive. i have to control the speed of a single phase AC induction motor. inverter design which i am following in a full H-bridge circuit containing power mosfets. now i have to generate variable frequency PWM signles using MCU, for that purpose i am using pic18f4431. here is the result of simulation which i am also getting on hardware.
Screenshot (46).png

now, have a look at the 10ms delay, during which both the channels are off (which i cant bear when actually driving a motor). the 10ms delay is due to the fact that i am checking adc value every now and than to varry the frequency, if the user wants.
any solutions ? so that i am unable to check the adc value as well as both the pwm channels operate without delay (continuesly) . comments are appreciated :)
 

Even if you were polling the adc channels, why would the pwm channels turn off? Are you disabling them? If it was me, I would use a timer interrupt to periodically reconfigure the pwm module and sample the adc in the main loop. Post your code here so others will have a better idea of what is causing the 10ms delay.
 

ok sir, i will post the code after inserting comments in the code so that others can understand.

- - - Updated - - -

sir, i am trying to obtain sine pwm using sine look up table. for each and every frequency, sine look up table is generated during runtime. my code is given. i have checked it on hardware, its not continuously running.



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
#include<p18f4431.h>
#include <math.h>
#pragma config LVP =OFF
#pragma config WDTEN = OFF
#pragma config OSC=HS
#include <math.h>
unsigned char p=0;
unsigned char q=0;
unsigned char r=0;
unsigned char x=0;
float f1=96.66;
unsigned char sinee [64];
float factor;
float frequency,val,pr2;
unsigned char sine [64]={0, 4, 8, 13, 17, 21, 25, 29, 33, 37, 41, 44, 48, 51, 55, 58, 61, 64, 66, 69, 72, 74, 76, 78, 79, 81, 82, 83, 84, 85, 86, 86, 86, 86, 86, 85, 84, 83, 82, 81, 79, 78, 76, 74, 72, 69, 66, 64, 61, 58, 55, 51, 48, 44, 41, 37, 33, 29, 25, 21, 17, 13, 8, 4};
float factor;
void deadtime (unsigned char d) // function for dead time
{
unsigned char t=0;
while(t<d)
{
t=t+1;
}
} 
void pwm (void)
{
for( p=0; p<64; p=p+1) //loop for implementing look-up table, writing duty cycle value to CCPR1L register which is copied in CCPR1H on each interupt
//i.e when a match between TMR2 & PR2 occura
{
CCPR1L=sinee[p];
PIR1bits.TMR2IF=0;
while(PIR1bits.TMR2IF==0); //when interupt occurs TMR2IF bit sets to 1, showing that inerupt has occured
}
//CCPR1L=0; //after the above loop executed 64 times i.e for 10ms, square waves are inverted
//deadtime(50); // insertion of dead time between two PWM channels
 
for( q=0; q<64; q=q+1) //loop for implementing look-up table, writing duty cycle value to CCPR1L register which is copied in CCPR1H on each interupt
{ //i.e when a match between TMR2 & PR2 occur
CCPR2L=sinee[q];
PIR1bits.TMR2IF=0;
while( PIR1bits.TMR2IF==0);
}
 
}
void setup(void) //function for adc setup
{
 
//ADCON0bits.ACONV=1; // contineous mode
ADCON0bits.ACONV=0; // single shoot mode
ADCON0bits.ACSCH=0; 
ADCON0bits.ACMOD0=0; //sequential mode
ADCON0bits.ACMOD1=0;
//ADCON0bits.ACMOD0=0; //contineous mode single channel mode
//ADCON0bits.ACMOD1=0;
ADCON1bits.VCFG0=0;
ADCON1bits.VCFG1=0;
ADCON2bits.ADFM=0; // left justified
ADCON2bits.ACQT0=1; // aquction time=2*tad
ADCON2bits.ACQT1=0;
ADCON2bits.ACQT2=0;
ADCON2bits.ACQT3=0;
ADCON2bits.ADCS0=0; // tad=32tosc
ADCON2bits.ADCS1=1;
ADCON2bits.ADCS2=0;
ADCHSbits.GASEL0=0;
ADCHSbits.GASEL1=0;
ANSEL0=1;
 
TRISC=0x00; //pwm setup
CCP1CON=0x00; 
CCP2CON=0x00; 
CCPR1L=0; 
// CCPR2L=0; / 
CCP1CON=0xC;
CCP2CON=0xC; 
T2CON=6; 
}
int ADCRead(unsigned char ch)
{
 
ADCON0bits.ADON=1; //switch on the adc module
ADCON0bits.GO=1; //Start conversion
while(ADCON0bits.GO); //wait for the conversion to finish
ADCON0bits.ADON=0; //switch off adc
frequency=0.1953125*ADRESH; //0-5Volts of adc ----> 0---->50Hz output, using 8 MSB's of adc
 
pr2 =( 2456 *(pow(frequency,-1.002)))-0.888; // period register calculation formula
 
factor=pr2/f1; //contant factor that should be multiplied with basic sine lookup table to get the table for desired frequency
PR2=pr2;
for (r=0;r<64;r=r+1)
{
sinee[r]=factor*sine[r];
 
}
return PR2;
}
 
void main()
{
setup(); 
ADCRead(0);
pwm();
deadtime(50000000);
 
 
}



kindly help if u can. thanks
 
Last edited by a moderator:

While you may be using the overflow flag for the timer, it doesn't seem like you are using ISRs and the interrupt vector. I suggest you read up on those and use them. Your mcu seems to have deadtime features and is geared for motor control (perfect for your h bridge). You shouldn't have to write code for deadtime (but looking at you code, are you only using deadtime as a delay function?). Btw, how are you polling your adc pin when it seems like you don't have an infinite loop in your main() function? Those are some things I'd like to point out.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top