Problems generating PWM signal with dsPIC30F3014

Discussion in 'Programmer's Corner' started by alexsoad, Apr 16, 2011.

  1. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    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:
    _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.
     
  2. mik3

    Senior Member

    Feb 4, 2008
    4,846
    63
    You have the OC1CON register equal to 0x0007 which means that the OC1 output pin is enabled for PWM and it is also controlled by the FAULT pin. IF you don't need the FAULT pin set OC1CON=0x0006.

    Also, you don't need to use PORTx=LATx. Just set LATx=value.
     
    alexsoad likes this.
  3. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    it worked. 110 instead of 111 for selecting the mode of OC is the solution. the pwm is generated, but i cannot control it. i cannot make the motor go faster or slower, even if i change the period and the duty cycle.
    i tried on a servo motor, and it works only for a few mili seconds.
     
  4. mik3

    Senior Member

    Feb 4, 2008
    4,846
    63
    You have to find the required pulse width range and the pulse repetition rate of the servo.
     
  5. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    problem solved. motors work at desired speed.
    now i just want to generate 2 pwm pulses with 2 different timers ( T2 and T3). is there any special thing i should know?
    the timers are able to work in the same time?
    is it ok to set them with the same priorities?
     
  6. mik3

    Senior Member

    Feb 4, 2008
    4,846
    63
    Code ( (Unknown Language)):
    1. problem solved. motors work at desired speed.
    2. now i just want to generate 2 pwm pulses with 2 different timers ( T2 and T3). is there any special thing i should know?
    Code ( (Unknown Language)):
    1. the timers are able to work in the same time?
    Yes, the timers can work at the same time.

    Code ( (Unknown Language)):
    1. is it ok to set them with the same priorities?
    Priorities are used for interrupts. You can set both timers with the same priority. If you do this, timer 2 will have higher priority than timer 3 since it is located in a lower number position in the interrupt table (have a look in the interrupts manual if you want).

    If you want timer 2 to have higher priority than timer3, you have to set it a higher priority number. However, this is only useful when you are using the interrupts generated by these timers. For PWM generation, the PWM is generated at the same time without affected by priorities since it is done in hardware.
     
    alexsoad likes this.
  7. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    Ok. thank you very much.
    i apreaciate.
     
  8. mik3

    Senior Member

    Feb 4, 2008
    4,846
    63
    You are welcome ;).
     
  9. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    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...
     
  10. alexsoad

    Thread Starter New Member

    Apr 3, 2011
    14
    0
    mik3 any solution now for me ? :p
     
Loading...