본문 바로가기

[MODULE]/MOTOR

[DC 모터 제어] RDK-BDC Kit 예제 분석

[DC 모터 제어] RDK-BDC Kit 예제 분석



[2009-03-26 11:56:56]
RDK-BDC 데모키트
LM3S2616을 이용한 모터 드라이버 보드이다.



전체 코드는 PWM2 Timer 인터럽트를 이용해서 1ms 로 전체 하드웨어를 제어하고 있다. <- 1ms로 CAN, Swith등을 제어한다. if, switch의 분가 좀 있는데 큰 무리가 없나보다.
ControllerIntHandler(void) 함수가 인터럽트 핸들러이다.
 
인터럽트 핸들러 안에
ControllerSpeedMode()
ControllerPositionMode()
등등 모터 제어를 하고 있다.
 
속도제어
우선 스피드 제어쪽을 보면...
ControllerSpeedMode()
{
        // 엔코더의 속도값을 읽어와서
        lTemp = EncoderVelocityGet();
 
        // 에러값을 구함 -> 목표 속도와 비교한다.
        lTemp = g_lSpeedTarget - lTemp;

        //PID제어기를 돌려 값을 설정한다.
        lTemp = PIDUpdate(&g_sSpeedPID, lTemp) / 256;

        // Limit 설정
        if(lTemp < -32768)
        {
            lTemp = -32768;
        }
        if(lTemp > 32767)
        {
            lTemp = 32767;
        }

        // 새로운 모터 출력값 설정
        g_lVoltage = lTemp;
    }
 
    // 모터 전압 설정 -> PWM출력
    HBridgeVoltageSet(g_lVoltage);
}
 
encoder.c 파일의 속도값 읽어오는 함수
long EncoderVelocityGet(void)
{
    return(MathDiv16x16(SYSCLK * 60, g_ulEncoderClocks * g_ulEncoderLines));
}
 
 
속도는 외부 인터럽트를 이용하여 펄스의 시간을 측정하도록 되어 있다.
 
startup.c 외부 인터럽트 핸들러 설정
    EncoderIntHandler,                      // GPIO Port C
 
EncoderIntHandler()
{
    // Save the time.
    ulNow = ROM_SysTickValueGet();

    // Clear the encoder interrupt.
    ROM_GPIOPinIntClear(QEI_PHA_PORT, QEI_PHA_PIN);

    //이전 타이머 값에서 형재의 타이머 값을 빼서 펄스의 시간을 측정한다.
    if(g_ulEncoderPrevious > ulNow)
    {
        g_ulEncoderClocks = g_ulEncoderPrevious - ulNow;
    }
    else
    {
        g_ulEncoderClocks = (16777216 - ulNow) + g_ulEncoderPrevious;
    }

    //이전값 저장
    g_ulEncoderPrevious = ulNow;
}

코드 자체는 별것 아닌데... 상당히 복잡하게 작성해놨다. 좀더 쉽고 간단하게 프로그램 짜면 쉽게 가져다 쓰기 편할텐데..
"가장 좋은 코드는 가장 쉽게 이해하는 코드다!"라는 말이 생각난다.
반응형