Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problems generating PWM signal with dsPIC30F3014

Status
Not open for further replies.

alexsoad

New Member
I need to generate a PWM signal to command a DC motor via L298N driver.
I user dsPIC30F3014 to do this, but i cannot generate it and i need some help from you.
I user C programming language.
So:
Code:
_FOSC(CSW_FSCM_OFF & FRC_PLL16); //using internal oscillator 
//this is for an external interrupt INT0, from a button, to switch on/off the motors.
int activ;
void __attribute__ ((interrupt, no_auto_psv)) _INT0Interrupt(void)
{
   if( activ == 1)
   activ = 0;
   else
   activ = 1;
   IFS0bits.INT0IF = 0
}

//this is the interrupt from Timer 2
void __attribute__((interrupt, no_auto_psv)) _T2Interrupt (void)
{
IFS0bits.T2IF = 0;
}

// the function to enable the PWM, from OC1  pin
void enable_pwm()
{
    PR2=0x0F90;            // pwm period
    OC1CON=0x0007;     // seting OC1 to "simple PWM" mode
    OC1RS=0x07C8;       // duty cycle
    T2CONbits.TON=1;   // starting the timer 2
    
}

// main

int main(void)
{
    RCONbits.SWDTEN = 0;     //disable WDT
   T2CON=0x0000;                //set the presclare to 1:1
   TRISB = 0x000000;            //portB as output
   TRISD=0x0000;                 //portd as output
   IFS0bits.INT0IF = 0;           //reset the flag from INT0
   IFS0bits.T2IF = 0;              //reset the flag from T2
   IEC0bits.INT0IE = 1;           //enable INT0
   IEC0bits.T2IE = 1;             //enable T2 interrupt
   INTCON2 = 0x0001;           //enable INT0 from global interrupts
   activ = 0;                        //setting activ to 0 , => motors don't start at reset
   while(1)
   {
   if (activ==1)
    {
    enable_pwm();     //enables the PWM
    LATB=0x0033;     //settings extra bits from port B to 1
    PORTB=LATB;
    }
   else
    {
    LATB=0x0030;
    PORTB=LATB;
    }
}
}
The motor is controller via L298N. This driver needs 3 pins for a motor. 2 for direction (1 logic and 0 logic: i take them from PORTB). The last pin is for enable. If i take it from a 1 logic pin, the motor does works. If i take it from PWM pin, it doesn't works. So, the PWM isn't generated corretly.

Alex.
 
Last edited by a moderator:
I think you need to brake this into 2 pieces.

Can you make portB = 1 and 0? Can you see that the PWM pin is working? Set to 50% is it at 50%.

Remove dsPIC30F3014, Set direction to 1,0. Set enable to on. Is there voltage across the motor?
 
You should use the **broken link removed** to initialise your PWM.

Here's the example from the 16-bit peripheral libraries PWM help page:
Code:
#define __dsPIC30F6010__

#include <p30fxxxx.h>

#include<pwm.h>

void __attribute__((__interrupt__)) _PWMInterrupt(void)

{

   IFS2bits.PWMIF = 0;

}

int main()

{

/* Holds the  PWM interrupt configuration value*/

    unsigned int config;

/* Holds the value to be loaded into dutycycle register */

    unsigned int period;

/* Holds the value to be loaded into special event compare register */

    unsigned int sptime;

/* Holds PWM configuration value  */

    unsigned int config1;

/* Holds the value be loaded into PWMCON1 register */

    unsigned int config2;

/* Holds the value to configure the special event trigger

   postscale and dutycycle */

    unsigned int config3;

/* The value of ‘dutycyclereg’ determines the duty cycle

   register(PDCx) to be written */

    unsigned int dutycyclereg;

    unsigned int dutycycle;

    unsigned char updatedisable;

 

/* Configure pwm interrupt enable/disable and set interrupt

   priorties */

    config = (PWM_INT_EN & PWM_FLTA_DIS_INT & PWM_INT_PR1

             & PWM_FLTA_INT_PR0

             & PWM_FLTB_DIS_INT & PWM_FLTB_INT_PR0);

    ConfigIntMCPWM( config );

/* Configure PWM to generate square wave of 50% duty  cycle */

    dutycyclereg  = 1;

    dutycycle     = 0x3FFF;

    updatedisable = 0;

 

    SetDCMCPWM(dutycyclereg,dutycycle,updatedisable);

    period = 0x7fff;

    sptime = 0x0;

    config1 = (PWM_EN & PWM_PTSIDL_DIS & PWM_OP_SCALE16

               & PWM_IPCLK_SCALE16 &

                 PWM_MOD_UPDN);

    config2 = (PWM_MOD1_COMP & PWM_PDIS4H & PWM_PDIS3H &

               PWM_PDIS2H & PWM_PEN1H & PWM_PDIS4L &

               PWM_PDIS3L & PWM_PDIS2L & PWM_PEN1L);

    config3  = (PWM_SEVOPS1 & PWM_OSYNC_PWM &  PWM_UEN);

    OpenMCPWM(period,sptime,config1,config2,config3);

    while(1);

}

If you have the latest version of C30 installed you will have a htm page located at:

"mplabc30/v3.25/docs/periph_lib/dsPIC30F_dsPIC33F_MCPWM_Library_Help.htm"
 
Last edited:
Hello again,
I do have another problem....I have generated 2 PWM signals and i have controled 2 DC motors, with 2 different timers. So i can control the motors independently.
Now, after my IR sensor array is done, i tried to put them together, but there are some problems.
I have made a simple program to test the sensors. If i put a white paper in front of the sensor i test, a led from board lights up. If i put a black paper in front of the sensor, the led turns off. I am very please with the response time of the sensor and also with the perturbation that occur when 'neigbour' sensors are emitting.

But, the problem occurs when i want to control motors by reading with sensors black or white. The motors do work, but they do not respect the speed from PWM signal. Sometimes, when i make some modifications in configuration of AD, they change the speed a little bit when different values are red from IR sensor, but the speeds are not OK, they do not follow my PWM signal....

This is the code for my ADC config:

void init_adc()
{
ADCON1bits.FORM = 0;
ADCON1bits.SSRC = 7;
ADCON1bits.ASAM = 1;
ADCON2bits.CSCNA = 1;

// ADCON2bits.CHSP = 0;
ADCON2bits.SMPI = 0;
ADCON3bits.ADRC = 0;
ADCON3bits.ADCS = 31;

ADCSSLbits.CSSL9 = 1;
ADPCFG=0x0000;
//IFS0bits.ADIF = 0;
IPC2bits.ADIP =7;
IEC0bits.ADIE = 1;
ADCON1bits.ADON = 1;

}





void __attribute__((interrupt, no_auto_psv)) _ADCInterrupt(void)
{
ain4Buff[sampleCounter++]=ADCBUF0;
if(sampleCounter==SAMP_BUFF_SIZE)
sampleCounter=0;
if (ADCBUF0>0x0090)
activ=1;
else
activ =0;

IFS0bits.ADIF = 0;
}

When activ==0, the motor should have a speed, and when activ==1 the motor must have another speed....

dsPic30F3014 has 3 timers, timer 2 and timer 3 are used to generate PWM signals via OC channels. I cannot use timer 3 for ADC.
I selected : ADCON1bits.SSRC = 7; as ADC source. In datasheet says from internal counter, it does work with the test i have made with led, but i do not know who is the internal counter....

So, i need some help with this issue. I do not know why the PWM signals are perturbed by the ADC module. Mabye the AD interrupt occurs too often? or... i don't know... please help me...
 
Status
Not open for further replies.

Latest threads

Back
Top