⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwm.c

📁 dc servo using dspic30f
💻 C
字号:
//---------------------------------------------------------------------
//	File:		pwm.c
//
//	Written By:	Lawrence Glaister
//
// Purpose: This set of routines to run pwn output
//      // 
//---------------------------------------------------------------------
//
// Revision History
//
// Nov 21 2005 --    first version Lawrence Glaister// Mar 18 2006 --    stripped to single output for servo card
//---------------------------------------------------------------------- #include "dspicservo.h"#include <pwm.h>
#include <stdio.h>


/*********************************************************************
  Function:        void __attribute__((__interrupt__)) _PWMInterrupt(void)

  PreCondition:    None.
 
  Input:           None

  Output:          None.

  Side Effects:    None.

  Overview:        handles pwm interrupts 

  Note:            None.
********************************************************************/
void __attribute__((__interrupt__)) _PWMInterrupt(void)
{
    IFS2bits.PWMIF =0;
}

/*********************************************************************
  Function:        void setupPWM(void)

  PreCondition:    None.
 
  Input:           None

  Output:          None.

  Side Effects:    None.

  Overview:        port setup with deadtime, 
                   fault input disables pwm outputs on a per cycle basis

  Note:            None.
********************************************************************/void setup_pwm(void)
{
    /* Holds the PWM interrupt configuration value*/
    unsigned int config;
    /* Configure pwm interrupt enable/disable and set interrupt priorties */
    config = (PWM_INT_DIS & PWM_FLTA_DIS_INT & PWM_INT_PR1 & PWM_FLTA_INT_PR0);

    /* clear the Interrupt flags */
    IFS2bits.PWMIF = 0;	
    IFS2bits.FLTAIF = 0;	

    /* Set priority for the period match */
    IPC9bits.PWMIP      = (0x0007 & config);

    /* Set priority for the Fault A */
    IPC10bits.FLTAIP    = (0x0070 & config)>> 4;

    /* enable /disable of interrupt Period match */
    IEC2bits.PWMIE      = (0x0008 & config) >> 3;

    /* enable /disable of interrupt Fault A.*/
    IEC2bits.FLTAIE     = (0x0080 & config) >> 7;


    /* Configure PWM to generate 0 current*/
    PWMCON2bits.UDIS = 0;
    PDC1 = (FCY/FPWM - 1);

    PTPER = (FCY/FPWM/2 - 1);      // set the pwm period register(/2 for cnt up/dwn)
    SEVTCMP = 0x00;
    /* 1 output is independant and enabled */
    PWMCON1 = (PWM_MOD1_IND & PWM_MOD2_IND & PWM_MOD3_IND &  /* independant i/o */
				PWM_PEN1L  & PWM_PDIS1H &                    /* use 1L as pwm, */
				PWM_PDIS2L & PWM_PDIS2H &					 /* rest as I/O */
				PWM_PDIS3L & PWM_PDIS3H 
				);
    /* set dead time options, scale = 1, 10*FCY (about 625ns) */
    DTCON1 = PWM_DTAPS1 & PWM_DTA10;
  
    /* set up the fault mode override bits and mode */
    FLTACON = PWM_FLTA_MODE_CYCLE &
              PWM_FLTA1_DIS &
              PWM_FLTA2_DIS &
              PWM_FLTA3_DIS &
              PWM_OVA1L_INACTIVE &
              PWM_OVA1H_INACTIVE &
              PWM_OVA2L_INACTIVE &
              PWM_OVA2H_INACTIVE &
              PWM_OVA3L_INACTIVE &
              PWM_OVA3H_INACTIVE ;

    /* set special event post scaler, output override sync select and pwm update enable */
    PWMCON2 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN);
    PTCON   = (PWM_EN & PWM_IDLE_CON & PWM_OP_SCALE1 & PWM_IPCLK_SCALE1 & PWM_MOD_UPDN);

}


/*********************************************************************
  Function:        void set_pwm(float amps)

  PreCondition:    None.
 
  Input:           current value in amps
				   (calculation specific to dspic-servo with 3.3k resistor
				   on current limit pin of the OPA549)

  Output:          None.

  Side Effects:    None.

  Overview:        This routine accepts an an amplitude value to
				   of -6.949 to + 6.949 amps. From this value,
                   the pwm channel is set as required.

  Note:            None.
********************************************************************/void set_pwm(float amps){
	// driving the opa549, 4.75 volts is 0 current and 0 volts is 6.949 (by r12)
	// to tune this number... enable the call to pwmtest routine in main.c
    // put a low value resistor in place of the motor ( ie 1ohm 50w )
    // look at triangle waveform on scope, paying attention to the 0 crossover point
    // if you get a horizontal glitch in the waveform, slightly decrease the numerator
    // if you get a vertical glitch, slightly increase the numerator
    // make sure the fudge factor doesnt go over 1.0
    const long pwm_max = (FCY/FPWM)*(4.85/5.0) - 1;      // 95% pwm count ( gives 4.75v output )
    short temp_dir;
    static short last_dir = 0;
    long temp;

	// the direction of the current is controlled by a pic output pin
	if ( amps >= 0.0 )
        temp_dir = 1;
	else
	{
        temp_dir = 0;
		amps = -amps;		// flip minus values to an amplitude
	}
	// this limit is set by R12 on the dspic servo board
	if ( amps > 6.949 ) amps = 6.949;
	
	temp = (long)(((float)pwm_max * amps)/6.949);

    /* compute value for pwm register */
    temp = pwm_max - temp;


    /* limit inputs to expected ranges */ 
    if ( temp > pwm_max ) temp = pwm_max;
    if ( temp < 1 ) temp = 1;

//	printf("pwm amps cmd= %f maxcnt= %ld, writing %ld\r\n",
//			(double)amps,pwm_max,temp);

	// test code to see if we can reduce spiking at 0 drive position on direction changes
    if ( temp_dir != last_dir )
    {
        temp = pwm_max;		// force output to 0 for 1 cycle on dir change
    }
	last_dir = temp_dir;

    PDC1 = temp;
    SVO_DIR = temp_dir;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -