• 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.

More refined version of PWM receiver

    Blog entry posted in 'Uncategorised', September 22, 2009.

    I've gotten as far as making a motor move forward and reverse via remote. I got the PWM interpreter to work much more accuratly by using the CCP1 module, and configuring it to set to capture rising edges, then on that event record the time and switch to capture falling edges, then on that event it captures the time, subtracts for the width and switches back. I'll get into the circuitry that controls the motor later, for now, here's my code for PWM capture.

    Code:

    //Basic configureation of chip periferials
    #pragma config OSC = INTIO2, WDT = OFF, LVP = OFF
    #include <p18f1320.h>

    //setup pins for PWM input
    #define ReceiverPin PORTBbits.RB3
    #define ReceiverTris TRISBbits.TRISB3


    //PWM capture variables
    unsigned int PWM1RiseTime = 0; //timer value at rising edge capture
    unsigned int PWM1Width = 0; //calculated width
    char PWM1Edge = 1; //edge currently being monitored 1 = rising, 0 = falling

    //set up interrupt
    void low_ISR(void);//prototype
    #pragma code low_vector = 0x08
    void low_interrupt (void){
    _asm goto low_ISR _endasm
    }
    #pragma code
    #pragma interrupt low_ISR

    //debug stuff
    char test1 = 0;
    char test2 = 0;

    void main(void)
    {
    unsigned int MotorCount = 1;
    unsigned char MotorOn;

    OSCCON = 0x72; //8MHz clock
    while(!OSCCONbits.IOFS); //Wait for OSC to become stable

    //configure timer1
    OpenTimer1(0b10010101);
    PIE1bits.TMR1IE = 1; //periferial interupt register, 1 = timer 1 interupt enabled
    PIR1bits.TMR1IF = 0; //clears the timer 1 interupt flag

    //configure CCP1
    CCP1CON = 0b0000101; //configure CCP1 for capture, rising edge
    INTCONbits.PEIE=1; //enable peripheral interrupts
    PIE1bits.CCP1IE=1; //enabled CCP1 interrupt
    INTCONbits.GIE=1; //enable branching to interrupt

    ReceiverTris = 1; //set RB3 for input so the capture can work.

    //configure ports
    ADCON1 = 0xff; //all digital
    INTCON2bits.RBPU = 0; //port b weak pullups on

    //configure control bits for output
    TRISBbits.TRISB1 = 0;
    TRISBbits.TRISB4 = 0;
    TRISAbits.TRISA4 = 0;
    //enable bit
    LATAbits.LATA4 = 1; //Enable bit


    while(1)
    {


    }
    }


    void low_ISR(void)
    {

    test1 = 1;
    //ccp interrupt
    if(PIR1bits.CCP1IF == 1)
    {
    PIR1bits.CCP1IF = 0; //clear the flag
    if(PWM1Edge == 1)//if detecting rising
    {

    PWM1RiseTime = CCPR1;//save the low timer value for the rise time
    CCP1CON = 0b0000100;//switch to detect falling edge
    PWM1Edge = 0;//switch to indicate falling edge is next
    }
    else //detecting falling
    {

    PWM1Width = CCPR1 - PWM1RiseTime;
    CCP1CON = 0b0000101;//switch to detect rising edge
    PWM1Edge = 1;//switch to indicate rising edge is next
    }

    if(PWM1Width > 1800)
    {
    LATBbits.LATB4 = 0;
    LATBbits.LATB1 = 1;
    }

    if(PWM1Width < 1400)
    {
    LATBbits.LATB4 = 1;
    LATBbits.LATB1 = 0;
    }

    if(PWM1Width > 1400 && PWM1Width < 1800)
    {
    LATBbits.LATB4 = 0;
    LATBbits.LATB1 = 0;
    }

    }
    }



    the part at the end with the latches is just to test it out on a small motor controlled through an L298n h-bridge chip, I have B4 and B1 connected to the control pins, and A4 is on the enable pin. The code is currently getting around 1650 for pwm width in the middle position of the controller, and 1200 and 2200 at the ends respectivly.

    Comments
 

EE World Online Articles

Loading

 
Top