سلام چند وقتی بود که تو فکر این بودم timeout واسه چیزای مختلف تو avr بزارم با یه تایمر .
خیلی وقتا موقع کار ممکن داخل حلقه مثل while درگیر بشید و مشکلات زیادی واستون ایجاد کنه مثلا موقع کار با I2c تو محیط نویز دار میکرو خیلی هنگ میکرد و امکانات دیگه غیر I2C هم از کار می افتاد (sim900 و DS1307) با هم داشتم استفاده میکردم . از این تابع به عنوان delay دقیق هم میشه استفاده کرد
این یه برنامه ساده به عنوان نمونه میتونه کمک کنه واسه جلو گیری از هنگ کامل . امیدوارم به درد کسی بخوره
تو این برنامه با تایمر 0 یه شمارنده درست شده .
با تابع timer که ورودیش بر حسب ثانیه هست و اند شدنش با شرط اصلی میشه راحت یه تایم اوت درست کرد . قبل از چک کردن شرط تایمر روشن میشه و بعدشم تایمر رو خاموش میکنیم
از یه ال سی دی برای گرفتن فیدبک استفاده شده . در صورتی که شرط حلقه while اجرا بشه done و در صورت timeout روی ال سی دی timeout رو میندازه از flag برای تشخیص حالتش استفاده شده
خیلی وقتا موقع کار ممکن داخل حلقه مثل while درگیر بشید و مشکلات زیادی واستون ایجاد کنه مثلا موقع کار با I2c تو محیط نویز دار میکرو خیلی هنگ میکرد و امکانات دیگه غیر I2C هم از کار می افتاد (sim900 و DS1307) با هم داشتم استفاده میکردم . از این تابع به عنوان delay دقیق هم میشه استفاده کرد
این یه برنامه ساده به عنوان نمونه میتونه کمک کنه واسه جلو گیری از هنگ کامل . امیدوارم به درد کسی بخوره
کد:
#define F_CPU 8000000 #include <avr/io.h> #include <avr/delay.h> #include <avr/interrupt.h> #include "lcd.h" int timerCounter = 0; int flag; ISR (TIMER0_OVF_vect) { timerCounter++; } int timer(int time_sec) { int ret=1; if(timerCounter>=time_sec*30) { ret=0; deinittimer(); } return ret; } void initTimer(void)//1S=30C { TCCR0=0x05; TCNT0=0x00; OCR0=0x00; TIMSK |= 0x01; PORTD|=0xF0; timerCounter = 0; } void deinittimer(void) { TCCR0=0x00; TCNT0=0x00; OCR0=0x00; TIMSK |= 0x00; } int main(void) { DDRA=0xFF; DDRB=0xFF; DDRD=0x00; DDRC=0x00; SREG|=0x80; PORTA=0x01; // something to do lcd_init(); lcd_putsf("TIMEOUT TEST"); _delay_ms(1000); lcd_putsf("Press The Key"); while (1) { if((PINC&0x01)==0x01) { lcd_clr(); //LCD clear lcd_putsf("Waiting"); initTimer(); //Start the Timer while(((PIND&0x01)!=0x01)&&(flag=timer(5))); //timeout in 5 Sec if not done within deinittimer(); lcd_clr(); if(flag==0) //check if timeout/done|| 0=timeout 1=done lcd_putsf("ReqTimeout"); else lcd_putsf("done"); } else if((PINC&0x02)==0x02) { lcd_clr(); //LCD clear lcd_putsf("Waiting"); initTimer(); //Start the Timer while(((PIND&0x01)!=0x01)&&(flag=timer(5))); //timeout in 5 Sec if not done within deinittimer(); lcd_clr(); if(flag==0) //check if timeout/done|| 0=timeout 1=done lcd_putsf("ReqTimeout"); else lcd_putsf("done"); } } }
با تابع timer که ورودیش بر حسب ثانیه هست و اند شدنش با شرط اصلی میشه راحت یه تایم اوت درست کرد . قبل از چک کردن شرط تایمر روشن میشه و بعدشم تایمر رو خاموش میکنیم
از یه ال سی دی برای گرفتن فیدبک استفاده شده . در صورتی که شرط حلقه while اجرا بشه done و در صورت timeout روی ال سی دی timeout رو میندازه از flag برای تشخیص حالتش استفاده شده