×
单片机 > 单片机程序设计 > 详情

直流有刷伺服控制系统(pic单片机,pid控制)

发布时间:2020-06-18 发布时间:
|

基于PIC18系列单片机的直流有刷伺控制系统:(来处于国外贴)
1:原理图(PDF)
2:原理图及PCB图(EAGLE)
3:带pid + 编码器的控制程序。main.c


电路原理图如下:

 

单片机源程序如下:

// Vertical motor driver code 

// Oringially made by Kevin Wolfe 2009-2011

// Modified by Matt Moses 2010-2011

// 


#include

//#include

//#include

//#include



#define counterToSpeedScalar 150

#define numCountsPerStep 1

#define maxSpeed 255

#define Kp 35.0

#define Kd 0.0

#define Ki 0.0

#define dt 0.01

#define speedStep 1

#define errorTol 1

#define tempADSpeed 255

#define stepHomeThreshold 500

#define upTorqueLimit 150

#define downTorqueLimit -120


#pragma config IESO = ON

#pragma config FSCM = ON

#pragma config OSC = INTIO2        

#pragma config PWRT = OFF

#pragma config BOR = OFF

#pragma config WDT = OFF

#pragma config MCLRE = OFF


/****** DISABLE LVP (LOW-VOLTAGE Programming) ******/

/* This allows RB5 to operate as an interuppt on change I/O pin */

#pragma config LVP = OFF

/***************************************************/


void low_isr (void);

void high_isr (void);

void set_motor_output (unsigned char desiredPWM, unsigned char desiredDirection);


#pragma code high_vector_section=0x8

void high_vector (void)

{

_asm GOTO high_isr _endasm

}

#pragma code


#pragma code low_vector_section=0x18

void low_vector (void)

{

_asm GOTO low_isr _endasm

}

#pragma code


volatile int stepHighCounter = 0;


volatile char stepPulses = 0;

//volatile int stepCounts;

volatile int currentCounter = 0;

//volatile unsigned char currentADvalue;

volatile unsigned char trigger = 0;

//volatile structPrevStates prevStates;

//volatile enum { DIR_CW = 0, DIR_CCW = 1 } direction;

volatile enum { LOW = 0, HIGH = 1} prevA = LOW;


// changeToggle is a varb used for debugging

volatile enum {LOW = 0, HIGH = 1} changeToggle;


#pragma interrupt high_isr

void high_isr(void)

{

        if ( INTCONbits.INT0IF ) //step pulse flag 

        {


                // reset stepTimerFoo

                stepHighCounter = 1;


                // do important stuff

                if ( PORTBbits.RB1 )    //Check direction pin

                {

                        stepPulses++;

                }

                else

                {

                        stepPulses--;

                }

        

                INTCONbits.INT0IF = 0; //reset step flag

        }


        if ( INTCONbits.RBIF ) //PORTB change interrupt

        {


//                // This is a little block for debugging - toggles A every time a change on PORTB

//        

//                if (changeToggle) {

//                        changeToggle = 0;

//                        PORTAbits.RA1 = 0;

//                }

//                else {

//                        changeToggle = 1;

//                        PORTAbits.RA1 = 1;

//                } 


                if ( PORTBbits.RB5^prevA )          //CW Rotation

                {

                        currentCounter++;

                        //PORTAbits.RA1 = 0;

                }

                else                                                //CCW Rotation

                {

                        currentCounter--;

                        //PORTAbits.RA1 = 1;

//                        if (changeToggle) {

//                                changeToggle = 0;

//                                PORTAbits.RA1 = 0;

//                        }

//                        else {

//                                changeToggle = 1;

//                                PORTAbits.RA1 = 1;

//                        } 

                }



                prevA = PORTBbits.RB4;

                PORTAbits.RA1 = PORTBbits.RB5;


                INTCONbits.RBIF = 0; //resetQuadFlag

        }

}


#pragma interruptlow low_isr

void low_isr(void)  //timer interupt

{

        trigger = 1;

        INTCONbits.TMR0IF = 0;                         // reset TMR0 interrupt flag

}



void set_motor_output(unsigned char desiredPWM, unsigned char desiredDirection)

{

        if ( desiredDirection )

        {

                PORTBbits.RB2 = 0;

                CCPR1L = desiredPWM;                          // This is the register for the 8 MSB of the PWM pin RB3.

        }

        else

        {

                PORTBbits.RB2 = 1;

                CCPR1L = (desiredPWM );          // This is the register for the 8 MSB of the PWM pin RB3.

        }

}


long abs(long i) 

        if (i < 0) 

                return -i; 

        else 

                return i; 


char sgn(long i)

{

        if (i < 0)

                return -1;

        else if (i > 0)

                return 1;

        else

                return 0;

}



void main (void)

{

        long prevCounter = 0;

        unsigned char tempTrigger = 0; 

        char tempStepPulses = 0;

        long tempCurrentCounter = 0;

        

        unsigned char currentADvalue = tempADSpeed;

        long desiredCounter = 0;

        long error = 0;

        long prevError = 0;


        long velocity = 0;


        float integral = 0.0;

        float derivative = 0.0;


        long output = 0;


        char testState = 0;

        long testCounter = 0;




        char homeFlag = 0;

    enum { LOW = 0, HIGH = 1} homeDir = LOW;


        /*************** SETUP INTERRUPTS ******************/

        INTCONbits.GIEH = 0;                 // Temporarily disable global interrupts

        INTCONbits.GIEL = 0;                 // Temporarily disable peripheral interrupts

        INTCONbits.TMR0IE = 1;                 // Enable TMR0 Overflow interrupt

        INTCONbits.INT0IE = 1;                 // Enable external interrupt on INT0/RB0

        INTCONbits.RBIE = 1;                 // Enable Port B change interrupt


        //INTCON2bits.RBPU = 0;                 // Enable Port B pull-ups

        INTCON2bits.RBPU = 1;                 // Disable Port B pull-ups

        INTCON2bits.INTEDG0 = 1;         // Interrupt on rising edge for INT0

INTCON2bits.TMR0IP = 0; // Set TMR0



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项