[DC 모터 제어] RDK-BDC Kit 예제 분석
[2009-03-26 11:56:56]
RDK-BDC 데모키트
LM3S2616을 이용한 모터 드라이버 보드이다.
//PID제어기를 돌려 값을 설정한다.
lTemp = PIDUpdate(&g_sSpeedPID, lTemp) / 256;
// Limit 설정
// 새로운 모터 출력값 설정
[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;
lTemp = g_lSpeedTarget - lTemp;
//PID제어기를 돌려 값을 설정한다.
lTemp = PIDUpdate(&g_sSpeedPID, lTemp) / 256;
// Limit 설정
if(lTemp < -32768)
{
lTemp = -32768;
}
if(lTemp > 32767)
{
lTemp = 32767;
}
{
lTemp = -32768;
}
if(lTemp > 32767)
{
lTemp = 32767;
}
// 새로운 모터 출력값 설정
g_lVoltage = lTemp;
}
}
// 모터 전압 설정 -> PWM출력
HBridgeVoltageSet(g_lVoltage);
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();
// 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;
}
코드 자체는 별것 아닌데... 상당히 복잡하게 작성해놨다. 좀더 쉽고 간단하게 프로그램 짜면 쉽게 가져다 쓰기 편할텐데..
"가장 좋은 코드는 가장 쉽게 이해하는 코드다!"라는 말이 생각난다.
반응형