Microcontroller › PIC › pwm with pic 16f877a › hi, i m able to make pwm
hi,
i m able to make pwm but i can not change duty cycle of it using ADC module of 18f2431.
Can u help me?
I want that if my ADC of PIC18F2431 reading one variable pot. when i chage that pot, i should change the duty cycle of my pwm signals….
the code is : i m using MPLAB
#include<P18F2431.h>
#define MAX_DUTY_CYCLE 100 // 100% DUTY CYCLE PDC1=PDC2=PDC=499
#define MIN_DUTY_CYCLE 25 // 2.4% DUTY CYCLE PDC1=PDC2=PDC=499
//#define mydata2 ADRESH
void msdelay(unsigned int);
void chk_isr(void);
void AD_ISR();
#pragma code My_HiPrio_Int=0x0008 // high-priority interrupt
void My_HiPrio_Int(void)
{
// _asm
chk_isr();
// _endasm
}
#pragma code //end high-priority interrupt
#pragma interrupt chk_isr // which interrup?
void chk_isr(void)
{
if (PIR1bits.ADIF==1) //a/d cause interrupt?
AD_ISR(); // Yes, Execute INTO program
}
unsigned char DesiredPWMDutyCycle_low_byte;
unsigned char DesiredPWMDutyCycle_high_byte;
unsigned char CurrentPWMDutyCycle_low_byte;
unsigned char CurrentPWMDutyCycle_high_byte;
unsigned int digital_outl[8];
unsigned int digital_outh[8];
unsigned int i=0;
unsigned char data[20]=”ADC OUTPUT=”;
unsigned int avg_outputl=0;
unsigned int avg_outputh=0;
unsigned int templ;
unsigned int temph;
void main ( )
{
while(1)
{
/* ADC intinliazaione start */
TRISC=0; // MAKE PROT C OUTPUT
TRISB=0; // MAKE PORT B OUTPUT
TRISAbits.TRISA0=0; // Ra0 in for analog port
ADCON0 = 0x23; // cont. loop mode, auto conv,a/d on
ADCON1 = 0xDC; // an3 as vref+,buffer empty
ADCON2 = 0x89; // RIGHT justifed, 2Adc aquistion time, Fosx/32 used
ADCON3 = 0x10; // pwm triger
ADCHS = 0x00; //
ANSEL0 = 0xFF; // AN0-7 analog input
// ANSEL1 = 0x01; // analog input pin enable
PIR1bits.ADIF=0; // CLEAR A/D INTERRUPT FLAG
PIE1bits.ADIE=1; // enble a/d interrupt
INTCONbits.PEIE=1; // enable peripheral interupts
INTCONbits.GIE=1; // enable all interup globaly
/* ADC intinliazaione end */
/* pwm internalization start*/
PTCON0=0x00; // free runing mode, no pre post scalers
PTCON1=0x80; // up counting, time base on
PWMCON0=0x47; //all pwm 0 to 5 output, indepedent mode not complimentry
PWMCON1=0x03; // 1:1 postscare, o/p override snch on
// PTMRL=0x00;
// PTMRH=0x04;
_asm
MOVLW B’01100100′ ;
MOVWF PTPERL
_end
PTPERL= B’01100100′;//100;//0xFF; // Fpwm=2.4khz, Fosc=40Mhz, PTMRPS0.97
//PTPERH=100;//0x0F;
/* pwm intinliazaione end*/
/* start code*/
// PDC0L= MIN_DUTY_CYCLE;//25; //ADRESL; //current duty cyle
// PDC0H= MIN_DUTY_CYCLE;//25; //ADRESH; // current duty cyle
// PORTC=ADRESL;
PDC1L= 40; //urrent duty cyle
PDC1H= 40; // current duty cyle
PDC2L= 55; //cADRESL; //urrent duty cyle
PDC2H= 55; //ADRESH; // current duty cyle
OVDCOND=0xFF; // pwm control by duty cycle
// OVDCONS=0xDE; // PWM 0 & 5 ON
// msdelay(5);
// OVDCONS=0xDB; // PWM 2 & 5 ON
// msdelay(5);
// OVDCONS=0XF9; // PWM 2 & 1 ON
// msdelay(5);
// OVDCONS=0xED; // PWM 1 & 4 ON
// msdelay(5);
// OVDCONS=0XE7; // PWM 4 & 3 ON
// msdelay(5);
// OVDCONS=0xF6; // PWM 3 & 0 ON
// msdelay(5);
PTCON1bits.PTEN=1; // start pulse
PIR3bits.PTIF=0; //clear flag
while(PIR3bits.PTIF==0); //wait for period
msdelay(50);
PTCON1bits.PTEN=0x00;
}// while loop over
}// main loop over
//
A/D ISR
void AD_ISR(void)
{
PORTC=ADRESL; // DISPLY LOW BYTE ON PORT C
templ=0;
temph=0;
for(i=0;i<8;i++)
{
// ADCON0|=(1<<GO); // Start A/D conversion
ADCON0bits.GO = 1; // START CONVERTING
while(ADCON0bits.DONE == 1); // Wait until conversion gets over
// digital_out(ADRESL)|(ADRESH<<); // Store 10-bit output into a 16-bit variable
digital_outl[8]=ADRESL;
digital_outh[8]=ADRESH;
msdelay(20);
templ=templ+digital_outl;
temph=temph+digital_outh;
}
avg_outputl=templ/8; // Take average of ten digital values for stablity
avg_outputh=temph/8;
PDC0L= avg_outputl; //ADRESL; //current duty cyle
PDC0H= avg_outputh; //50; // current duty cyle
//
// PORTB=ADRESH; // DISTPLAY HIGH BYTE ON PORT D*/
msdelay(1); // WAIT
PIR1bits.ADIF=0; // CLEAR A/D INTERRUPT FLAG
}
void msdelay(unsigned int itime)
{
unsigned int i;
unsigned char j;
for ( i=0; i<itime;i++);
for(j=0;j<1; j++);
}