Date post: | 20-Jan-2016 |
Category: |
Documents |
Upload: | hugh-walker |
View: | 218 times |
Download: | 3 times |
Application of Interrupt and Timer :
Measurement of Motor Speed
incoming Lab.incoming Lab.
Rotary Encoder
A (rotary) encoder is an electro-mechanical device that converts the angular position of a shaft or axle to digital code or digital pulse
absolute/incremental
incoming Lab.incoming Lab.
DC motor
incoming Lab.incoming Lab.
Encoder
Incremental Encoder13 pulses/round/channel1 pulse = 360/13 도 (motor), 360/50/13 도 (wheel)Motor Speed
rpm (round per minute)– rad/sec = rpm*2pi/60
102 rpm (wheel) = 5100 rpm (motor)direction
A/B channel 의 위상을 비교
A Ch.
B Ch.
A Ch.
B Ch.
incoming Lab.incoming Lab.
DC Motor
RB-35GM 제어전압 : DC 12V감속비 [Reduction ration] : 1/50정격토크 [Rated torque](Kg-cm): 2.0정격회전수 [Rated speed](rpm):102Rated torque 60 g-cm, 5100 rpm, current 470 mA 이하 , 3.14 WNo load speed 6200 rpm, No load current 120 mA 이하
incoming Lab.incoming Lab.
Measurement of motor speed (I)
pulse 간의 시간 측정
Example)
rpm(wheel)50
1
13
601
rpm(Motor) 13
601round/sec)(
13
11pulse/sec)(
1
904.9usecsec 0009049.0102
1
50
1
13
60 rpm 102
rpm 9250
1
13
60
001.0
1001.01
mSec
incoming Lab.incoming Lab.
Measurement of motor speed (I)
pulse 간의 시간 측정예) fclk = 1 Mhz, N(prescale) = 100
ftimer = fclk/N=10kHz, Ttimer = 100uSec timer_diff = 100 => 10 mSec
timerT timer_diff
timer_diff
incoming Lab.incoming Lab.
Measurement of motor speed (I)
External InterruptINT 5 : Left motor A channel (PE5) INT 7 : Right motor A channel (PE7)external interrupt 간 timer 비교EICRB = 0x88; EIMSK = 0xA0;
A Ch.
tcnt1 tcnt2 timer_diff = tcnt2 – tcnt1
incoming Lab.incoming Lab.
바퀴구동체 도면
incoming Lab.incoming Lab.
External interrupt Setting
EIMSK : external Interrupt MaSK register
EICRB
1 0 1 0 0 0 0 0
1 0
1 0
incoming Lab.incoming Lab.
Measurement of motor speed (I)
timer for external interruptTCNT0 : 8 bit timer/counterTCNT1 : Motor Speed ControlTCNT2, TCNT3 : same prescaler with TCNT1
normal modeno timer interruptfclk = 7372800 Hz & prescale : 256
ftimer = 7372800/256 = 28800
Ttimer = 1/28800 = 34.72 uSec 예상 ) 102 rpm => 904.9 uSec => 26 (= timer_diff )
TCCR0 = 0x06;
incoming Lab.incoming Lab.
Measurement of motor speed (I)
TCCRn : Timer/Counter Control Register
1 1 0
incoming Lab.incoming Lab.
Interrupt Service Routine (INT5, Left Motor)
ISP(INT5_vect){ static unsigned char timer_cur = 0, timer_prev = 0;
timer_cur = TCNT0; Left_timer_diff = timer_cur – timer_prev; timer_prev; = timer_cur;
if ( (PINE & 0x10) == 0 ) Dir_L = 0; // forward else Dir_L = 1; // backward}
incoming Lab.incoming Lab.
Speed Measurement Program (I)
#include <avr/io.h>#include <avr/interrupt.h>
void txd_char(unsigned char data){ while( (UCSR0A & 0x20) == 0 ); UDR0 = data;}
unsigned char Left_timer_diff, Right_timer_diff;unsigned char Dir_L, Dir_R;
int main(){
unsigned char i, time_diff;unsigned char text[] = "\r Left : ";
incoming Lab.incoming Lab.
Speed Measurement Program (I)
DDRB = 0xCF; DDRD = 0x18; DDRE = 0x01; PORTB = 0x01; /* 원하는 방향을 기입 */
EICRB = 0x08; // EICRB = 0x88; EIMSK = 0x20; // EIMSK = 0xA0; TCCR1A = 0x2B; TCCR1B = 0x0A; TCCR1C = 0x00; OCR1B = 0x00; /* 원하는 속도를 기입 0x000 ~ 0x3FF */
// OCR1C = 0x00; /* 원하는 속도를 기입 0x000 ~ 0x3FF */
TCCR0 = 0x06; EIMSK = 0x20; /* Left interrupt 만 enable */ sei();
incoming Lab.incoming Lab.
Speed Measurement Program (I)
while(1){ i=0; while(text[i] != '\0') txd_char(text[i++]);
if( Dir_L == 1 ) txd_char('+'); // 부호 출력 else txd_char('-'); time_diff = Left_timer_diff; // 임시 저장 txd_char(time_diff/100 + '0'); // 백의 자리 출력 txd_char((time_diff/10)%10 + '0'); // 십의 자리 출력 txd_char(time_diff%10 + '0'); // 일의 자리 출력 txd_char('\r');
return 0;
}
incoming Lab.incoming Lab.
연습
Right Motor 에 대해 속도 측정 code 완성Left/Right motor 에 대해 다양한 속도에 대한 속도측정RPM 단위로 출력 (UART)
incoming Lab.incoming Lab.
Measurement of motor speed (I)
timerT timer_diff
incoming Lab.incoming Lab.
Interrupt Service Routine (INT5, Left Motor)
ISR(INT5_vect){ static timer_cur = 0, timer_prev = 0;
timer_cur = TCNT0; if (timer_cur >= timer_prev) Left_timer_diff = timer_cur – timer_prev; else Left_timer_diff = 255- timer_prev+timer_cur+1; timer_prev; = timer_cur;
if ( (PINE & 0x20) == 0 ) Dir_L = 0; // forward else Dir_L = 1; // backward }
incoming Lab.incoming Lab.
Interrupt Service Routine (INT5, Left Motor)
ISR(INT5_vect){ Left_timer_diff = TCNT0; TCNT0 = 0;
if ( (PINE & 0x20) == 0 ) Dir_L = 0; // forward else Dir_L = 1; // backward }
incoming Lab.incoming Lab.
Measurement of motor speed (II)
일정한 시간 간격 동안 pulse 의 개수 측정
Example)
rpm(wheel)50
1
13
60
rpm(Motor) 13
60round/sec)(
13
1pulse/sec)(
n
nnn
1150 60
1301.0102 rpm 102
rpm 3750
1
13
60
01.0
4401.010
n
nmSec
incoming Lab.incoming Lab.
Measurement of motor speed (II)
clear time on compare match (CTC) mode (output compare interrupt)
TCNT0 : 8 bit timer/counterfclk = 7372800 Hz & prescale : 1024
ftimer = 7372800/1024 = 7200
Ttimer = 1/7200
OCR0 = 144 => 144*Ttimer = 1/50 = 20 mSec 마다 interrupt 발생
예상 ) 102 rpm => 904.9 uSec => 22 개 pulse
TCCR0 = 0x0F;TIMSK = 0x02;
숫자세기구간
0
OCRn
255
인터럽트 발생위치
(한계값)
incoming Lab.incoming Lab.
Measurement of motor speed (II)
TCCRn : Timer/Counter Control Register
TIMSK : Timer/Counter Interrupt Mask Register
1 1 1 1
incoming Lab.incoming Lab.
Interrupt Service Routine (INT5, Left Motor)
ISP(INT5_vect){ Pulse_L++; if ( (PINE & 0x20) == 0 ) Dir_L = 0; // forward else Dir_L = 1; // backward}
incoming Lab.incoming Lab.
Interrupt Service Routine (Timer0)
ISR(TIMER0_COMP_vect){ static unsigned char no_timer = 0; no_timer++; if ( no_timer >= 10 ) { // 20*10 = 200 mSec no_timer = 0; No_Pulse_L = Pulse_L; No_Pulse_R = Pulse_R; Pulse_L = Pulse_R = 0; }}
incoming Lab.incoming Lab.
Interrupt Service Routine (Timer0) – 20mSec
ISR(TIMER0_COMP_vect){ No_Pulse_L = Pulse_L; No_Pulse_R = Pulse_R; Pulse_L = Pulse_R = 0;}
incoming Lab.incoming Lab.
Speed Measurement Program (II)
#include <avr/io.h>#include <avr/interrupt.h>
void txd_char(unsigned char data){ while( (UCSR0A & 0x20) == 0 ); UDR0 = data;}
unsigned char Pulse_L, Pulse_R, No_Pulse_L, No_Pulse_R;unsigned char Dir_L, Dir_R;
int main(){ unsigned char cmd, i=0, no_pulse_l;
unsigned char text[] = "\r Left : ";
incoming Lab.incoming Lab.
Speed Measurement Program (II)
/* UART0 초기화 추가 */ DDRB = 0xCF; DDRD = 0x18; DDRE = 0x01; PORTB = 0x01; /* 원하는 방향을 기입 */
EICRB = 0x08; // EICRB = 0x88; EIMSK = 0x20; // EIMSK = 0xA0; TCCR1A = 0x2B; TCCR1B = 0x0A; TCCR1C = 0x00; OCR1B = 0x00; /* 원하는 속도를 기입 0x000 ~ 0x3FF */
// OCR1C = 0x00; /* 원하는 속도를 기입 0x000 ~ 0x3FF */
OCR0 = 144; TCCR0 = 0x0F; /* CTC mode prescale = 1024 */ TIMSK = 0x02; /* Timer Interrupt */ sei();
incoming Lab.incoming Lab.
Speed Measurement Program (II)
while(1){ i=0; while(text[i] != '\0') txd_char(text[i++]);
if( Dir_L == 1 ) txd_char('+'); // 부호 출력 else txd_char('-'); no_pulse_l = No_Pulse_L; // 임시 저장 txd_char(no_pulse_l /100 + '0'); // 백의 자리 출력 txd_char((no_pulse_l /10)%10 + '0'); // 십의 자리 출력 txd_char(no_pulse_l %10 + '0'); // 일의 자리 출력 txd_char('\r');
return 0;
}
incoming Lab.incoming Lab.
연습
Right Motor 에 대해 속도 측정 code 완성Left/Right motor 에 대해 다양한 속도에 대한 속도측정RPM 단위로 출력 (UART)