MSP430F5529PID算法闭环控制电机转速

代码

#include "driverlib.h"
#include "stdio.h"
#include <string.h>
#include <stdarg.h>

static int capz=0;
static int capy=0;
static int error=0;
static int aim=40;
static int allerr=0;
static int previouserr=0;
static int altererr=0;
static int output=0;
static float kp=4.0;
static float ki=0.1;
static float kd=2.0;

void uartinit1()
{

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,GPIO_PIN5);
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);
    USCI_A_UART_initParam param1 = {0};
    param1.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
    param1.clockPrescalar = 6;
    param1.firstModReg = 13;
    param1.secondModReg = 0;
    param1.parity = USCI_A_UART_NO_PARITY;
    param1.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    param1.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
    param1.uartMode = USCI_A_UART_MODE;
    param1.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
    if (STATUS_FAIL == USCI_A_UART_init(USCI_A1_BASE, &param1)){
            return;
        }
    //Enable UART module for operation
    USCI_A_UART_enable(USCI_A1_BASE);

}

void UART_printf(uint16_t baseAddress, const char *format,...)
{
    uint32_t length;
    va_list args;
    uint32_t i;
    char TxBuffer[128] = {0};

    va_start(args, format);
    length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer), (char*)format, args);
    va_end(args);

    for(i = 0; i < length; i++)
        USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}

void up(int r,int l)
{

               GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN1 );
               GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN2 );
               GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN3 );
               GPIO_setAsOutputPin (GPIO_PORT_P6,GPIO_PIN4 );

               GPIO_setOutputHighOnPin (GPIO_PORT_P6, GPIO_PIN2);GPIO_setOutputHighOnPin (GPIO_PORT_P6, GPIO_PIN3);
               GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN1);GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN4);

               GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN3);
               GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P1,GPIO_PIN2);
               //Generate PWM - Timer runs in Up mode
               Timer_A_outputPWMParam paramr = {0};
               paramr.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
               paramr.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
               paramr.timerPeriod = 100;
               paramr.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
               paramr.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
               paramr.dutyCycle = r;
               Timer_A_outputPWM(TIMER_A0_BASE, &paramr);

               //Generate PWM - Timer runs in Up mode
               Timer_A_outputPWMParam paraml = {0};
               paraml.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
               paraml.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
               paraml.timerPeriod =100;
               paraml.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
               paraml.compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET;
               paraml.dutyCycle = l;
               Timer_A_outputPWM(TIMER_A0_BASE, &paraml);
}
void time()
{
            Timer_A_initContinuousModeParam initContParam = {0};
            initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
            initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
            initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
            initContParam.timerClear = TIMER_A_DO_CLEAR;
            initContParam.startTimer = false;
            Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam);

            //Initiaze compare mode
            Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
                TIMER_A_CAPTURECOMPARE_REGISTER_0
                );

            Timer_A_initCompareModeParam initCompParam = {0};
            initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
            initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
            initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
            initCompParam.compareValue = 50000;
            Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);
            Timer_A_startCounter( TIMER_A1_BASE,TIMER_A_UP_MODE);
           //__bis_SR_register(GIE);
}
void pidcapture()
{
            Timer_A_initContinuousModeParam htim = {0};
            htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
            htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
            htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
            htim.timerClear = TIMER_A_DO_CLEAR;
            htim.startTimer = false;
            Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);

            //捕获右轮
            GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN5);
            Timer_A_initCaptureModeParam initComParam = {0};
            initComParam.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2;
            initComParam.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
            initComParam.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
            initComParam.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
            initComParam.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
            initComParam.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
            Timer_A_initCaptureMode(TIMER_A2_BASE, &initComParam);

            //捕获左轮
            GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN3);
            Timer_A_initCaptureModeParam initComParamzuo = {0};
            initComParamzuo.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
            initComParamzuo.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
            initComParamzuo.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
            initComParamzuo.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
            initComParamzuo.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
            initComParamzuo.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
            Timer_A_initCaptureMode(TIMER_A2_BASE, &initComParamzuo);
            Timer_A_startCounter( TIMER_A2_BASE,TIMER_A_CONTINUOUS_MODE);
}

int main(void) {

    WDT_A_hold(WDT_A_BASE);
    time();
    uartinit1();
    pidcapture();
    __bis_SR_register(GIE);
    return (0);
}


#pragma vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR (void)
{

      capy=(int)capy;
      error=aim-capy;
      allerr += error;
      altererr = error - previouserr;
      previouserr =  error;
      output =  kp*error+ki*allerr+kd*altererr;
      if(output>95)output=95;
      if(output<15)output=15;
      output = (int)output;
      up(output,output);
      UART_printf(USCI_A1_BASE, "%d,%d,%d\r\n", output,80,capy);
      capy=0;
      capz=0;

}

#pragma vector=TIMER2_A1_VECTOR//右轮
__interrupt
void TIMER2_A1_ISR(void)
{
    switch(TA2IV)
        {
            case TA2IV_TACCR2:
                capy++;
                break;

        }

}

#pragma vector=TIMER2_A0_VECTOR//左轮
__interrupt
void TIMER2_A0_ISR(void)
{

            capz++;
}

效果

每0.05秒捕获的上升沿个数目标值为40,实际值为40.

预计pwm占空比为80,实际占空比为86.

注意事项 

开启多少个中断就要写多少个中断服务函数,如果需要执行中断时程序找不到中断服务函数入口地址,会从main函数重新执行,程序会死机。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值