السلام عليكم
إخواني الكرام هذا الكود كتبته لثلاث سويتشات فعند الضغط على الأولى تضيء الليد الأول وعند فصل السويتش تبقى ثلاث ثواني مضاءة وبعدها تفصل والكود عمل جيداً ولكن المشكلة أنني أريد أن تعمل السويتشات معاً يعني مثلاً السويتش الأول والثالث أو الثاني والأول وهكذا ولكن المشكلة أن البيك لاتنفذ إلا أمر واحد يعني أضغط السويتش الأول فتعمل الليد الأول وعند الضغط على السويتش الثالث مثلاً لايعمل حتى أفصل السويتش الأول وأنتظر ثلاث ثواني حتى إنتهاء الأمر الأول وبعدها يعمل الثالث فهل هناك طريقة لكي تعمل السويتشات بشكل منفصل ودقيق لأن الدقة ضرورية في هذه الدارة وشكراً.
كود:
void main() {
trisa.f2=1;
trisa.f3=1;
trisa.f4=1;
trisb=0;
portb=8;
delay_ms(1000);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
while(1){
if(porta.f2==1){portb.f0=1;delay_ms(3000);}
else{portb.f0=0;}
if(porta.f3==1){portb.f1=1;delay_ms(3000);}
else{portb.f1=0;}
if(porta.f4==1){portb.f2=1;delay_ms(3000);}
else{portb.f2=0;}
}
}
|
الحل الوحيد هي بأستخدام الانتربت لان ديلي delay يجبر المايكرو على الانتظار ولكن بأستخدام الانتربت يستطيع مايكرو تنفيذ جميع الاوامر
سأعطيك الفكره
كود:
sbit sw1 at RA2_bit;
sbit sw1_dir at TRISA2_bit;
sbit sw2 at RA3_bit;
sbit sw2_dir at TRISA3_bit;
sbit sw3 at RA4_bit;
sbit sw3_dir at TRISA4_bit;
char sw1_flag=0,sw2_flag=0,sw3_flag=0 ;
char sw1_time=0,sw2_time=0,sw3_time=0 ;
//Timer1
//Prescaler 1:2; TMR1 Preload = 15536; Actual Interrupt Time : 50 ms
//Place/Copy this part in declaration section
void InitTimer1(){
T1CON = 0x11;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
TMR1IE_bit = 1;
INTCON = 0xC0;
}
void Interrupt(){
if (TMR1IF_bit){
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
//Enter your code here
if(sw1_flag==1)sw1_time++;
}
}
void main() {
sw1_dir=1;
sw2_dir=1;
sw3_dir=1;
trisb=0;
portb=8;
delay_ms(1000);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
portb=0;
delay_ms(500);
portb=8;
delay_ms(500);
while(1){
if(sw1==0)
{
sw1_flag=1;
}
if(sw1_flag==1 && sw1_time>=10)// this mean time >= 500
{
sw1_flag=0;
sw1_time=0;
PORTB.F0=1;
}
}
بالنسبه للكود الانتربت فهناك برنامج من شركه مايكروشيب اسمه timer-calculator
يحتاج منك العائله الي ينتمي لها البيك و تردد كرستاله و نوع تايمر وزمن الانتربت عندها يعطيك الكود الكامل
http://www.mikroe.com/timer-calculator/
هنا مثلا زمن الانتربت كل 50ms عندما نضغط على سويج نجعل flag لهذا سويج =1 لكي يدل على انه تم ضغط سويج
وفي الانتربت تضع شرط اذا flag لسويج =1 قم بتفعيل متغير اخر لنسميه مثلا time يعني sw_time هنا مايكرو كل 50 ملي ثانيه راح يتم مقاطعته لينفذ اوامر داله الانتربت وبتالي هذه طريقه لن تأخر عمل مايكرو
انت أفهم طريقه ستلاحظ تطبيقها سهل جدا
تحياتي