Lecturer: Reza Arjmandi Autumn 2015 Timer Counter 0 Lecturer: Reza Arjmandi Autumn 2015 Lecture 12, 13: Introduction Timer/Counter, Timer/Counter0 initialization
AVR Microcontroller-General Structure AVR CPU BUS Flash Memory SRAM EEPROM Timer/ Counter USART TWI ADC MCU Control and Timing I/O Ports Interface Watchdog Timer SPI ISP Interrupt Unit PORTD PORTC PORTB PORTA Internal Calibrated Oscillator Crystal ATMEGA32 Block Diagram: DataSheet Page4
Counter IC Counter IC 8bit Accuracy Binary Decimal 00000000 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 00000001 1 Counter IC 8bit Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 00000010 2 00000011 3 Clock 00000100 4 00000101 5 … … Accuracy 11111111 255
Timer/Counter کلاک تایمر / کانترها میتواند از دو راه تامین شود: 1-کلاک داخلی(تایمر) 2-کلاک خارجی(کانتر) امکانات و توانایی تایمر/کانترها: تولید وقفه های داخلی شمارش پالس های خارجی تولید پالس های مربعی و PWM و... مدهای شمارش: در هر یک از مدها مقادیر آرگومان های زیر با توجه به کاربردی خاص متفاوت است رجیستر شمارش: مقدار لحظهای شمارش در رجیستر TCNTx قرار دارد وقفه سرریز شدن(Overflow): شمارش دوباره شمارنده از مقدار Bottom که امکان ایجاد وقفه داخلی هم وجود دارد بیت Flag : TOVx بیت فعال ساز اختصاصی: TOIEx وقفه مقایسه(CompareMatch): مقایسه مقدار لحظهای شمارنده با رجیستر مقایسه OCRx که امکان ایجاد پالس مربعی و وقفه وجود دارد بیت Flag: OCFx بیت فعال ساز اختصاصی: OCIEx Max: حداکثر مقداری که تایمر/کانتر میتواند شمارش کند(دقت) TOP: حداکثر مقداری که تایمر/کانتر شمارش میکند و بعد از آن سرریز اتفاق می فتد Bottom: مقداری که شمارش از آن شروع میشود Bottom(=0) TOP(=131) TOP(=Max) TOP(=230) Max(=255) شکل موج خروجی OCRx Timer/ Counter ATMEGA16: Timer/Counter0 (8bit) Timer/Counter1 (16 bit) Timer/Counter2 (8 bit) Prescaler fsystem/N fsystem
Timer/Counter 0 Counter0 Timer/ Accuracy: 8 Bit Modes: 1-Normal 2-CTC 3-FastPWM 4-Phase correct PWM Pins: T0:پایه ورودی برای اتصال منبع کلاک خارجی OC0: پایه خروجی برای تولید شکل موج Prescalar N: 1, 8, 64, 256, 1024 TCNT0 Register: Timer/Counter0 Register OCR0: Output Compare Match Register Timer/Counter0 Counter0 Timer/ نکته! برای تولید شکل موج خروجی باید پین های مربوط به آن به صورت خروجی پیکره بندی شود
Timer/Counter0-Modes-Normal OverFlow InterruptTOV0=1; Bottom Max(=255) TOP(=Max) OC0 OCR0 Max=255 TOP=Max Bottom= Change By TCNT0 OCR0 Update= Immediate Duty Cycle=50% Normal Mode Formula: FOC0=Fsystem/(2*N*(256-Bottom)) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer Compare Match InterruptOCF0=1;
Timer/Counter0-Modes-Normal مثال 1: در مد نرمال تایمر/کانتر صفر، با فرض منبع پالس داخلی سیستم 1MHz ضریب تقسیم N=64 و TCNT0=0x2A، زمان فعال شدن Overflow Flag را محاسبه کنید. Ftimer = 1MHz / 64 = 15.625KHz Ttimer = 1 / 15.625KHz = 64us Toverflow = (0xFF – 0x2A) * 64us = 13.696ms مثال 2: در مد نرمال تایمر/کانتر صفر، با فرض منبع پالس داخلی سیستم 8MHz ضریب تقسیم N=8 برای تولید زمان 0.1ms چه عددی را باید در TCNT0 قرار داد؟ Ftimer = 8MHz / 8 = 1MHz Ttimer = 1 / 1MHz = 1us (0xFF – Bottom) * 1us = 0.1ms Bottom = TCNT0 = 0x9C مثال 3: در مد نرمال تایمر/کانتر صفر، با فرض منبع پالس داخلی سیستم 4MHz ضریب تقسیم N=8 و Bottom=0 فرکانس موج خروجی را محاسبه کنید. FOC0 = 4MHz / (2 * 8 * (256 – 0)) = 976.56KHz Normal Mode Formula: FOC0=Fsystem/(2*N*(256-Bottom)) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer
Timer/Counter0-Modes-CTC CTC: Clear Timer on Compare Match Compare And Overflow interrupt TOV0=1 AND OCF0=1 OCR0 Bottom Max(=255) OC0 Max= 255 TOP= Change By OCR0 Bottom= Change By TCNT0 OCR0 Update= Immediate OCR0 OCR0 OCR0 Duty Cycle=50% CTC Mode Formula: FOC0=Fsystem/2*N*(1+OCR0) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=مقدار تاخیر دلخواه/دوره تناوب مدکاری CTC معمولا برای ایجاد زمان های تاخیر دلخواه ونیز برای تولید شکل موج هایی با فرکانس های متفاوت استفاده میشود
Timer/Counter0-Modes-CTC مثال 1: در مد CTC از تایمر/کانتر صفر اگر از منبع پالس داخلی سیستم با فرکانس 8MHz استفاده شود چه مقدار را باید در رجیستر OCR0 قرار دهیم تا شکل موج تولیدی روی پایه OC0 فرکانسی برابر با 1KHz داشته باشد؟ مقدار N چیست؟ 1KHz = 8MHz / 2 * N * (1 + OCR0) 0<OCR0<256 N=1,8,64,256,1024 N=64 select OCR0=61 مثال 2: در مد CTC از تایمر/کانتر صفر اگر از منبع پالس داخلی سیستم با فرکانس 1MHz استفاده شود.اگر بخواهیم یک تابع تاخیر 200ms بسازیم، مقدار رجیستر OCR0 را چقدر قرار دهیم؟(N=1024) Ftimer = 1MHz / 1024 Ttimer = 1 / Ftimer = 1024us OCR0 = مقدار تاخیر دلخواه / دوره تناوب OCR0 = 200ms / 1024us = 195.3 ~ 195 CTC Mode Formula: FOC0=Fsystem/2*N*(1+OCR0) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=مقدار تاخیر دلخواه/دوره تناوب
Timer/Counter0-Modes-Fast PWM PWM: Pulse Width Modulation از این مد بیشتر برای تولید شکل موج در خروجی استفاده میشود OverFlow InterruptTOV0=1; Bottom Max(=255) TOP(=Max) OC0 OCR0 Inverted Non-Inverted Max=255 TOP=Max Bottom= Change By TCNT0 OCR0 Update= TOP Fast PWM Mode Formula: FPWM=Fsystem/N*(256-Bottom) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=%dutyCycle * 255 Duty Cycle=قابل تغییر Compare Match InterruptOCF0=1;
Timer/Counter0-Modes-Fast PWM مثال 1: در مد Fast PWM از تایمر/کانتر صفر اگر از منبع پالس سیستم با فرکانس 16MHz استفاده شود، چه مقداری را باید در رجیستر OCR0 قرار دهیم تا شکل موج تولیدی PWM دارای duty cycle=50% و فرکانسی برابر 10KHz باشد؟ مقدار N چیست؟ 10KHz = 16MHz / N * (256 - 0) N=6.2 N=8 Select N=1,8,64,256,1024 OCR0 =0.5* 255 OCR0 = 127.5 ~ 127 Fast PWM Mode Formula: FPWM=Fsystem/N*(256-Bottom) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=%dutyCycle * 255
Timer/Counter0-Modes-Phase Correct PWM تفکیک پذیری(resolution) بالا را مهیا میسازد، یعنی شکل موج دقیقتری را نسبت به Fast PWM تولید میکند ولی دارای فرکانس تولیـدی پـایـیـن تری نـسـبـت بـه مــد FastPWM میباشد از مد تصحیح فاز بیشتر برای کنترل دور موتور استفاده میشود. دلیل این کار هم مـتـقارن بودن عملکرد شمارنده میباشد OverFlow InterruptTOV0=1; TOP(=Max) Bottom Max(=255) OCR0 Max=255 TOP=Max Bottom= Change By TCNT0 OCR0 Update= TOP OCR0 OCR0 OCR0 Non-Inverted OC0 Phase Correct PWM Mode Formula: FPWM=Fsystem/N*(510-Bottom) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=%dutyCycle * 510 Duty Cycle=قابل تغییر Inverted Compare Match InterruptOCF0=1;
Timer/Counter0-Register 1- TCCR0 2- TCNT0 3- OCR0 4- TIMSK 5- TIFR 6- SFIOR for Timer/Counter0 for All Timer/Counters
Timer/Counter0-Register-TCCR0 TCCR0: Timer/Counter0 Control Register توسط این رجیستر تنظیمات مربوط به انتخاب مدکاری، انتخاب منبع پالس، پیکره بندی پایه خروجی OC0 انجام میشود بیت های انتخاب منبع کلاک(CS00~02): CS:Clock Select
Timer/Counter0-Register-TCCR0 بیت های انتخاب مدکاری(WGM00~01): WGM: Waveform Generation Mode
Timer/Counter0-Register-TCCR0 بیت های پیکره بندی پایه خروجی(COM00~01): COM: Compare match Output Mode
Timer/Counter0-Register-TCCR0 بیت تغییر اجباری پایه خروجی(FOC0): FOC: Force Output Compare match این بیت فقط زمانی set میشود که یک حالت non-PWM (Normal-CTC) را انتخاب کرده باشید. در هنگام set کردن این بیت، یک تغییر وضعیت روی پایه OC0 ایجاد میشود. در زمان Set شدن این بیت Flag مقایسه خروجی OCF0 ست نمیشود و وقفهای بوجود نخواهد آمد این بیت در کل هیچ تاثیری بر هیچ رجیستر و Flagی ندارد و فقط وضعیت پایه OC0 را با توجه به تنظیمات آن تغییر میدهد
Timer/Counter0-Register-TIMSK AND TIFR TIMSK: Timer/Counter Interrupt Mask Register TIFR: Timer/Counter Interrupt Flag Register وقفه سرریز شدن(Overflow): بیت Flag : TOV0 بیت فعال ساز اختصاصی: TOIE0 بردار وقفه در IAR : TIMER0_OVF_vect وقفه مقایسه(CompareMatch): بیت Flag: OCF0 بیت فعال ساز اختصاصی: OCIE0 بردار وقفه در IAR: TIMER0_COMP_vect #include <ioavr.h> … void main(void) { TCCR0=0x01; while(1) if(TIFR_TOV0==1) code for overflow } void main(void) { TCCR0=0x01; TIMSK_Bit0=1; //overflow interrupt enable; asm(“sei”); while(1) … } #pragma vector=TIMER0_OVF_vect __interrupt void function(void) {code for overflow}
Timer/Counter0-Register-SFIOR SFIOR: Special Function I/O Register PSR10: Prescaler for timer/counter 0 and 1 هنگامی که مقدار بیت صفر از این رجیستر برابر 1 است واحد prescaler مربوط به تقسیم پالس برای تایمر/کانتر صفر و یک درحال ریست میباشد این بیت بصورت خودکار تغییر میکند و نمیتوان در آن تغییری ایجاد کرد
Timer/Counter0-Example1 میخواهیم یک تابع تاخیر 200ms بسازیم که با استفاده از آن یک LED واقع روی بیت 2 از پورت A چشمک بزند از فرکانس داخلی سیستم 1MHz و N=1024 استفاده شود #include<ioavr.h> void delay_200ms(void); main() { DDRA_Bit2=1; while(1) PORTA_Bit2=!PORTA_Bit2; delay_200ms(); } void delay_200ms(void) TCCR0= (1<<WGM01)|(1<<CS02)|(1<<CS00); OCR0=195; while(!TIFR_Bit1); TIFR_Bit1=1; TCCR0=0; Bottom Max(=255) OC0 OCR0 CTC Mode Formula: FOC0=Fsystem/2*N*(1+OCR0) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=مقدار تاخیر دلخواه/دوره تناوب Ftimer = 1MHz / 1024 Ttimer = 1 / Ftimer = 1024us OCR0 = مقدار تاخیر دلخواه / دوره تناوب OCR0 = 200ms / 1024us = 195.3 ~ 195
Timer/Counter0-Example2 با استفاده از وقفه مقایسه تایمر صفر یک وقفه 50ms تولید کنید و بوسیله آن یک LED چشمک زن روی بیت 2 پورت A بسازید، تایمر صفر در مد CTC باشد و با N=1024 از منبع پالس سیستم 1MHz استفاده کند #include<ioavr.h> main() { DDRA_Bit2=1; TCCR0=((1<<WGM01)|(1<<CS02)|(1<<CS00)); TIMSK=(1<<OCIE0); OCR0=48; asm("sei"); while(1); } #pragma vector=TIMER0_COMP_vect __interrupt void isr(void) PORTA_Bit2=~PORTA_Bit2; Bottom Max(=255) OC0 OCR0 CTC Mode Formula: FOC0=Fsystem/2*N*(1+OCR0) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=مقدار تاخیر دلخواه/دوره تناوب Ftimer = 1MHz / 1024 Ttimer = 1 / Ftimer = 1024us OCR0 = مقدار تاخیر دلخواه / دوره تناوب OCR0 = 50ms / 1024us = 48.8 ~ 48
Timer/Counter0-Example3 یک پالس مربعی با فرکانس 40KHz روی پایه OC0 بسازید. شرایط مسئله بصورت زیر است: مد تایمر/کانتر: CTC فرکانس داخلی سیستم : 8MHz N=1 OC0=toggle on compare match #include<ioavr.h> main() { DDRB_Bit3=1; TCCR0=((1<<COM00)|(1<<WGM01)|(1<<CS00)); OCR0=0X64; while(1); } Bottom Max(=255) OC0 OCR0 CTC Mode Formula: FOC0=Fsystem/2*N*(1+OCR0) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=مقدار تاخیر دلخواه/دوره تناوب 40KHz = 8MHz / 2 * 1 * (1 + OCR0) OCR0=99 0x64
Timer/Counter0-Example4 فرکانس متر: با استفاده از مد Normal تایمر صفر یک فرکانس متر دیجیتال بسازید که فرکانس موج روی پایه T0 را روی LCD نمایش دهد
Timer/Counter0-Example4 فرکانس متر: با استفاده از مد Normal تایمر صفر یک فرکانس متر دیجیتال بسازید که فرکانس موج روی پایه T0 را روی LCD نمایش دهد #include<ioavr.h> #include<intrinsics.h> #include "LCDCHR_Lib.c" unsigned long int i,j; void main() { DDRC=0XFF; LCDinit(); TIMSK=0X01; while(1) TCCR0|=(1<<CS02)|(1<<CS01); asm("sei"); __delay_cycles(952000); asm("cli"); j=i*256+TCNT0; LCDcursorOFF(); LCDclr(); LCDGotoXY(5,0); LCDstring("F= "); LCD_intnum(j); __delay_cycles(1000); TCCR0=0X00; i=0; TCNT0=0x00; } #pragma vector=TIMER0_OVF_vect __interrupt void wave(void) { i++;
Timer/Counter0-Example5 یک پالس مربعی با فرکانس 2KHz با duty cycle=30% روی پایه OC0 بسازید. شرایط مسئله بصورت زیر است: مد تایمر/کانتر: Fast PWM فرکانس داخلی سیستم : 4MHz N=8 OC0=non-inverted PWM #include<ioavr.h> main() { DDRB_Bit3=1; TCCR0=((1<<COM01)|(1<<WGM00)|(1<<WGM01)|(1<<CS01)); TCNT0=0X06; OCR0=0x4C; } Bottom Max(=255) TOP(=Max) OC0 OCR0 Inverted Non-Inverted Fast PWM Mode Formula: FPWM=Fsystem/N*(256-Bottom) Ftimer=Fsystem/N Ttimer=1/Ftimer Toverflow=(256-Bottom)*Ttimer OCR0=%dutyCycle * 255 2KHz = 4MHz / 8 * (256 - Bottom) Bottom = 6 OCR0 = 0.3 * 255 = 76.5 ~76
Timer/Counter0-Example6 برنامهای بنویسید که با استفاده از مد Fast PWM تایمر/کانتر صفر، نور یک LED که به خروجی OC0 تایمر صفر متصل است را بصورت پیوسته کم و زیاد کند و همچنین با دو کلید قابلیت تنظیم شدت نور را داشته باشد Bottom Max(=255) TOP(=Max) OC0 OCR0 Inverted Non-Inverted
Timer/Counter0-Example6 برنامهای بنویسید که با استفاده از مد Fast PWM تایمر/کانتر صفر، نور یک LED که به خروجی OC0 تایمر صفر متصل است را بصورت پیوسته کم و زیاد کند #include <ioavr.h> #include <intrinsics.h> enum Mode{automatic,NonAutomatic}; enum Mode VarMode=automatic; void main(void) { GICR|=(1<<INT0)|(1<<INT1)|(1<<INT2); //Enable EX Int0,1,2 MCUCR|=(1<<ISC01)|(1<<ISC11); //Trigger on falling edge DDRD&=~((1<<PD2)|(1<<PD3)); DDRB&=~(1<<PB2); DDRB|=(1<<PB3); //OC0 output dir PORTD|=(1<<PD2)|(1<<PD3); PORTB|=(1<<PB2); TCCR0=(1<<COM01)|(1<<WGM01)|(1<<WGM00)|(1<<CS00); //FastPWM OCR0=0X10; unsigned char i=0; asm("sei"); while(1) if(VarMode==automatic) OCR0=i++; __delay_cycles(20000); } #pragma vector=INT0_vect __interrupt void SelectAuto() { if (VarMode==automatic) VarMode=NonAutomatic; else VarMode=automatic; } #pragma vector=INT1_vect __interrupt void Up() OCR0+=8; #pragma vector=INT2_vect __interrupt void down() OCR0-=8;
Timer/Counter-PWM Application انتقال اطلاعات الکترونیک قدرت منابع تغذیه سوییچینگ کنترل دور موتورهای DC کاربرد های صوتی
Contact us www.e-system.ir Info@e-system.ir