سلام چند وقتی بود که تو فکر این بودم 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 برای تشخیص حالتش استفاده شده

