목차
1. DC Motor란?
2. DC Motor의 특성
3. DC Motor의 결점
4. DC Motor의 구조
5. DC 모터의 제어
6. PID란?
7. PID Gain 조정 및 제어 특성
8. 회 로 도
9. DC Motor Control Code
10. 결과값
11. 실험결과 및 고찰
2. DC Motor의 특성
3. DC Motor의 결점
4. DC Motor의 구조
5. DC 모터의 제어
6. PID란?
7. PID Gain 조정 및 제어 특성
8. 회 로 도
9. DC Motor Control Code
10. 결과값
11. 실험결과 및 고찰
본문내용
1;
float P_gain = 5.0;
float I_gain = 0.0;
float D_gain = 5.4;
int offset = 0;
void bad_trap(void)
{
while(1);
}
void c_int2(void)
{
DI;
if((PIVR-0x002F) == 0){
SET(EVBIFRA, T3PINT_FLAG);
control_period = 0;
}
EI;
}
void main(void)
{
unsigned int k, j;
int ref_pos, rel_pos, pos_er, prev_pos_er, pos_er_dot, pos_er_int, pwm;
char ch;
char s[40];
UINT ad_value;
DSPInit(PLLx4);
SCIInit();
SET_PC_OUT(BIT1|BIT0);
CLEAR (PORTC, BIT0);
// ADC setting 순서
// 1. ADC가 속해있는 모듈을 활성화 시킨다.
ADC_ENABLE; // ADC module enable
// 2. ADC를 초기화한다.
SET(ADCTRL1,BIT14); // RESET 비트를 '1'로 설정하여 ADC 모듈을 리셋한다.
NOP; // delay
ADCTRL1 = 0x0010;
// immediate stop, prescaler:16, CPS:0, start-stop mode
// 3. 최대 변환 채널을 지정한다.
MAXCONV= 0x0001; // 1 channel
// 4. 채널 변환 순서를 지정한다.
CHSELSEQ1 = 0x0000; // A/D 1
// 5. A/D 변환을 시작한다.
AD_START;
EVA_ENABLE;
T1DISABLE;
SET_PWM1;
SET_PWM2;
SET_PWM3;
SET_PWM4;
T1PR = (CPU_clk()/PWM_PERIOD);
ACTRA = 0x0099;
CMPR1 = (unsigned int)(T1PR*0.0);
CMPR2 = (unsigned int)(T1PR*0.0);
COMCONA = 0xC200;
T1CON = 0xD040;
T2PR = 0xFFFF;
T2CNT = 0;
T2CON = 0xD870;
EVB_ENABLE;
T3DISABLE;
T3CON = 0x5700;
T3PR = 15624; //20Hz
T3ENABLE;
SET(EVBIMRA, T3PINT_ENA);
SET(IMR, INT2_MASK);
EI;
CLEAR(PORTC, BIT0);
CLEAR(PORTC, BIT1);
ref_pos = 0;
pos_er = 0;
rel_pos=0;
pos_er_int = 0;
k=0; j=0;
pwm=0;
T2CNT=0;
while(1){
while(IS_AD_BUSY);
// A/D 변환값을 읽는다.
ad_value = (RESULT0>>6)&0x03FF;
// A/D 변환값을 시리얼 통신을 통해 전송한다.
while(control_period);
control_period = 1;
//if(j <= 50) {
// TOGGLE(PORTC, BIT0);
// TOGGLE(PORTC, BIT1);
// pwm = 0;
// T2CNT = 0;
// j++;
//}
//else {
ref_pos = ad_value*4;//(int)500*sin(2*3.1415926*k/100);
//if(k < 50) ref_pos = 0;
//else if(k<150) ref_pos = 1000;
//else if(k<250) ref_pos = -1000;
//else if(k<350) ref_pos = 1000;
//else if(k<450) ref_pos = -1000;
//else if(k<500) ref_pos = 0;
//else break;
prev_pos_er = pos_er;
rel_pos = T2CNT;
pos_er = ref_pos - rel_pos;
pos_er_dot = pos_er - prev_pos_er;
pos_er_int = pos_er_int + pos_er;
pwm = (int)(P_gain*pos_er + D_gain*pos_er_dot + I_gain*pos_er_int + offset);
k++;
//}
if(pwm > 0){
SET(PORTC, BIT0);
SET(PORTC, BIT1);
//pwm += 200;
//if(pwm > 1300)
// pwm = 1300;
}
else if(pwm == 0) {
TOGGLE(PORTC, BIT0);
TOGGLE(PORTC, BIT1);
}
else {
CLEAR(PORTC, BIT0);
CLEAR(PORTC, BIT1);
//pwm -= 200;
//if(pwm < -1300)
// pwm = -1300;
}
// if(k >= 450) break;
// else if(k >= 400) pwm = 0;
// else ;
CMPR1 = abs(pwm);
CMPR2 = abs(pwm);
//sprintf(s,"%d %d %d\n",ref_pos,pwm,rel_pos);
sprintf(s,"%d %d\n",ref_pos,rel_pos);
SCIPrintf(s);
AD_START;
}
while(1);
}
10. 결과값
float P_gain = 5.0;
float I_gain = 0.0;
float D_gain = 5.4;
int offset = 0;
void bad_trap(void)
{
while(1);
}
void c_int2(void)
{
DI;
if((PIVR-0x002F) == 0){
SET(EVBIFRA, T3PINT_FLAG);
control_period = 0;
}
EI;
}
void main(void)
{
unsigned int k, j;
int ref_pos, rel_pos, pos_er, prev_pos_er, pos_er_dot, pos_er_int, pwm;
char ch;
char s[40];
UINT ad_value;
DSPInit(PLLx4);
SCIInit();
SET_PC_OUT(BIT1|BIT0);
CLEAR (PORTC, BIT0);
// ADC setting 순서
// 1. ADC가 속해있는 모듈을 활성화 시킨다.
ADC_ENABLE; // ADC module enable
// 2. ADC를 초기화한다.
SET(ADCTRL1,BIT14); // RESET 비트를 '1'로 설정하여 ADC 모듈을 리셋한다.
NOP; // delay
ADCTRL1 = 0x0010;
// immediate stop, prescaler:16, CPS:0, start-stop mode
// 3. 최대 변환 채널을 지정한다.
MAXCONV= 0x0001; // 1 channel
// 4. 채널 변환 순서를 지정한다.
CHSELSEQ1 = 0x0000; // A/D 1
// 5. A/D 변환을 시작한다.
AD_START;
EVA_ENABLE;
T1DISABLE;
SET_PWM1;
SET_PWM2;
SET_PWM3;
SET_PWM4;
T1PR = (CPU_clk()/PWM_PERIOD);
ACTRA = 0x0099;
CMPR1 = (unsigned int)(T1PR*0.0);
CMPR2 = (unsigned int)(T1PR*0.0);
COMCONA = 0xC200;
T1CON = 0xD040;
T2PR = 0xFFFF;
T2CNT = 0;
T2CON = 0xD870;
EVB_ENABLE;
T3DISABLE;
T3CON = 0x5700;
T3PR = 15624; //20Hz
T3ENABLE;
SET(EVBIMRA, T3PINT_ENA);
SET(IMR, INT2_MASK);
EI;
CLEAR(PORTC, BIT0);
CLEAR(PORTC, BIT1);
ref_pos = 0;
pos_er = 0;
rel_pos=0;
pos_er_int = 0;
k=0; j=0;
pwm=0;
T2CNT=0;
while(1){
while(IS_AD_BUSY);
// A/D 변환값을 읽는다.
ad_value = (RESULT0>>6)&0x03FF;
// A/D 변환값을 시리얼 통신을 통해 전송한다.
while(control_period);
control_period = 1;
//if(j <= 50) {
// TOGGLE(PORTC, BIT0);
// TOGGLE(PORTC, BIT1);
// pwm = 0;
// T2CNT = 0;
// j++;
//}
//else {
ref_pos = ad_value*4;//(int)500*sin(2*3.1415926*k/100);
//if(k < 50) ref_pos = 0;
//else if(k<150) ref_pos = 1000;
//else if(k<250) ref_pos = -1000;
//else if(k<350) ref_pos = 1000;
//else if(k<450) ref_pos = -1000;
//else if(k<500) ref_pos = 0;
//else break;
prev_pos_er = pos_er;
rel_pos = T2CNT;
pos_er = ref_pos - rel_pos;
pos_er_dot = pos_er - prev_pos_er;
pos_er_int = pos_er_int + pos_er;
pwm = (int)(P_gain*pos_er + D_gain*pos_er_dot + I_gain*pos_er_int + offset);
k++;
//}
if(pwm > 0){
SET(PORTC, BIT0);
SET(PORTC, BIT1);
//pwm += 200;
//if(pwm > 1300)
// pwm = 1300;
}
else if(pwm == 0) {
TOGGLE(PORTC, BIT0);
TOGGLE(PORTC, BIT1);
}
else {
CLEAR(PORTC, BIT0);
CLEAR(PORTC, BIT1);
//pwm -= 200;
//if(pwm < -1300)
// pwm = -1300;
}
// if(k >= 450) break;
// else if(k >= 400) pwm = 0;
// else ;
CMPR1 = abs(pwm);
CMPR2 = abs(pwm);
//sprintf(s,"%d %d %d\n",ref_pos,pwm,rel_pos);
sprintf(s,"%d %d\n",ref_pos,rel_pos);
SCIPrintf(s);
AD_START;
}
while(1);
}
10. 결과값