قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

Mohammedalharbi
:: مهندس متواجد ::
تاريخ التسجيل: Dec 2012
المشاركات: 58
نشاط [ Mohammedalharbi ]
قوة السمعة:
قديم 12-05-2013, 11:55 AM المشاركة 9   
افتراضي



السلام عليكم
انا اشتغلت على نفس الفكرة قبل اسبوعين. وضبطت معايا لقياس التردد من 1 هرتز الى 500 كيلوهرتز. استخدمت برنامج mplab بس تقدروا تطبقوا نفس الفكرة في مايكروسي.
خليني اشاركم الاشياء الي فهمتها خلال بحثي لحساب التردد.. عندنا طريقتين لحساب التردد باستخدام المايكروكنترولر:
1- الطريقة الاولى تشغيل التايمر لمده ثانية وحساب عدد مرات (rising edge) للاشاراة التماثلية الداخلة للمايكروكنترولر. ومن ثم ايجاد الترد. للاسف ماجربت الطريقة هذه واحسها احسن من الطريقة الثانية في حساب الترددات العالية.
2- الطريقة الثانية (وهي الي استخدمتها) تعتمد على خاصية capture الموجودة في المايكروكنترولر..وفكرتها انها تسجل الوقت لل(rising edge) مرتين فقط ومن ثم حساب الفرق في التوقيت وايجاد التردد. اذا حصل طفح للتايمر قبل وصول ال rising edge الثاني, الكود يدخل على كود المقاطعة ويزيد المتغير ov_cnt وفي النهاية نحسب الفرق بين 2 rising edge عن طريق المعادلة التالية:

كود:
period= ov_cnt*65536 + temp2 - temp1
وهنا الكود
كود:
#define _XTAL_FREQ 16000000
unsigned int temp1,temp2,ov_cnt=0;
unsigned long long period;    //32-bit period value

long long float freq;
void main (void)
{

	OSCCON  = 0x7B;  //select internal osciallator =16Mhz
	__delay_us(4);			//allow the new clock to stabilize

	ANSELB=0x00;			//configure portB as digital
	TRISBbits.TRISB0 =1;	//RB0 input
	TRISBbits.TRISB1 =0;	//RB1 output
	RB1= 0;					//clear RB1

	TRISCbits.TRISC2 =1;    // set RC2 as input (CCP1)
	USARTInit(); 			//initalize USART communication



	CCP1CON=0b000000101;		////capture mode: every rising edge
	
	while (1)
	{

		if (!RB0) //if pushbutton is pressed
		{	
	     	__delay_ms(50);
			ov_cnt=0;				// clear overflow counter 
			GIE=0; 					//Disable global interrupt
			TMR1IF=0;				//clear timer1 overflow
			CCP1IE=0;				//Disable CCP1 interrupt
			CCP1IF=0;				//clear CCP1 overflow 
			RB1=1;					// Set RB1 high
			TMR1L=0;				//clear least significant bits of tmr1 register
			TMR1H=0;				//clear most significant bits of tmr1 register
			T1CON=0b00000101;		//Timer1 source:fosc/4 , 1 prescale, timer on
			
			
			while(CCP1IF==0);  //while rising edge doesnt occur, stay here
			temp1= ((unsigned int)CCPR1H << 8) | CCPR1L; //first rising edge occurs, get the time for first edge
			CCP1IF=0;  //clear cpp1 interrupt
			TMR1IF=0;  // clear timer1 overflow
			INTCON |= 0xC0;  // enable global and PEIE 
			TMR1IE=1;		//enable timer interrupt
			while(CCP1IF==0); //wait for second egde 
			temp2= ((unsigned int)CCPR1H << 8) | CCPR1L;//get the readings of the time for second edge
			GIE=0;  //disable global interrupt
			TMR1ON=0;  // stop timer1
			

			period= ov_cnt*65536 + temp2 - temp1;
		
			
			freq=period;     //calculating frequency: frequency= 1/( period* 250*10^(-9) )
			freq= freq *250; //250*10^(-9) ==> Fosc= 16Mhz ==> 16Mhz/4= 4Mhz ==> 1/4Mhz= 250ns 
			freq= freq/1000000;
			freq= freq/1000;
			freq=1/freq;
			period= freq;

		    USARTWriteString("Frequency: ");  //send frequency, first edge, second edge,and how many times timer1 overflow to USART (using us232) 
			USARTWriteInt(freq,7); //7 char
			USARTWriteString(" Hz");
			USARTWriteLine("");
		
			USARTWriteString("First edge: ");
			USARTWriteInt(temp1,6); //6 char
			USARTWriteLine("");
			USARTWriteString("Second edge: ");
			USARTWriteInt(temp2,6); //6 char
			USARTWriteLine("");
			USARTWriteString("Timer overflow happend: "); 
			USARTWriteInt(ov_cnt,2); //2 char
			USARTWriteString(" times");
			USARTWriteLine("");
			RB1=0;
		}
	}
}		

static void interrupt isr(void) 
{

	if (TMR1IF) //if timer1 overflow
	{
		TMR1IF = 0; //clear overflow
		ov_cnt ++;	//add 1 to ov_cnt	
			
	}
}

اعلانات

ennng
:: مهندس متميز ::
تاريخ التسجيل: Jul 2010
المشاركات: 453
نشاط [ ennng ]
قوة السمعة:
قديم 12-05-2013, 02:11 PM المشاركة 10   
افتراضي


اكثر من رائع اخي Mohammedalharbi وبارك الله فيك وطريقة جميلة عندي كم سؤال
1-لما بيحصل rising الاول نقرا الريجستر في متغير temp1 ونصفر flag طيب في اللحظة هذه هل timer1 بيكون شغال او بيتصفر!! اذا بيرجع للصفر وكانت الاشارة الداخلة متساوية راح يعطي صفر لان temp1 راح يساوي temp2. اعتقد ان timer يبقى شغال!!

2-اذا لم يحصل overflow في rising الثانية كيف يكون حسبة period هل period= ov_cnt*65536 + temp2 - temp1;
بحيث ان ov_cnt=1 !!!

3-هل الوقت بشكل عام بيكون او انا غلطان
65536 /(period= (temp2 - temp1;
4-ليه استخدمت
freq=period; //calculating frequency: frequency= 1/( period* 250*10^(-9) ) freq= freq *250; //250*10^(-9) ==> Fosc= 16Mhz ==> 16Mhz/4= 4Mhz ==> 1/4Mhz= 250ns freq= freq/1000000; freq= freq/1000; freq=1/freq; period= freq;
لان freq مقلوب period
freq=1/period
5-هل اذا حدث rising الاول راح يرتفع علم capture طيب في هذه الحالة كانها مقاطعة هل يحتاج نضع سبروتيين لهذه المقاطعة او لا فقط نقرا الريجستر تبع capture ونصفر flag من main program

6- ايش رايك لو وضعنا setting على انها تكون 4 rising ومن ثم قرائنا الريجستر بعد رفع العلم لل rising 4 ومن ثم نقسم القراءة على 4 راح يعطينا بالضبط قراءة ل period واحد ومن ثم نحسب freq
7-شكرا لك اخي واسف على الاسئلة.

نتمنى ممن يتابعنا ان يحول الكود للميكروسي مع قراءة القيم على LCD
بارك الله في تظافر الجميع

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية حيدر علاج حسن
حيدر علاج حسن
:: مشرف منتدى الهندسة الكهربائية ::
تاريخ التسجيل: Mar 2005
الدولة: IRAQ
المشاركات: 9,848
نشاط [ حيدر علاج حسن ]
قوة السمعة:
قديم 12-05-2013, 09:23 PM المشاركة 11   
افتراضي


الجديد في المشكلة ...
التردد هو مقلوب زمن النبضة و ليس الزمن بين نبضة واخرى ...
اعول على فكرة برمجية نسبة نجاحها 80% ان شاء الله . فقط احتاج الى بعض الوقت ..


ennng
:: مهندس متميز ::
تاريخ التسجيل: Jul 2010
المشاركات: 453
نشاط [ ennng ]
قوة السمعة:
قديم 12-05-2013, 11:54 PM المشاركة 12   
افتراضي


لجديد في المشكلة ...
التردد هو مقلوب زمن النبضة و ليس الزمن بين نبضة واخرى ...

ماذا تقصد اخي حيدر!!
التردد هو مقلوب الزمن بين نبضتيين متتاليتن اذا كانا يمثلان قمتيين او قاعيين متتاليتين سواءا صغر الزمن عن ثانية او كبر عن ثانية فهو يمثل التردد للاشارة.

اما زمن النبضة الواحدة لايمثل التردد
اما اذا انك تقصد بالنبضة (دورة كاملة) قمة وقاع!!


التعديل الأخير تم بواسطة : ennng بتاريخ 12-05-2013 الساعة 11:58 PM

Mohammedalharbi
:: مهندس متواجد ::
تاريخ التسجيل: Dec 2012
المشاركات: 58
نشاط [ Mohammedalharbi ]
قوة السمعة:
قديم 13-05-2013, 03:04 AM المشاركة 13   
افتراضي


اهلا اخوي ennng
1- لا اخي التايمر يكون شغال. لكن احنا نفعل المقاطعة لحساب عدد طفح التايمر اذا كان التردد منخفض. ونلاحظ ان المقاطعه تفعلت بعد حدوث اول rising edge. .ولكن التايمر شغال وبيعد.


2- اذا لم يحصل طفح للتايمر, ال ov-cnt =0 لانه تم تصفيرها بعد الدخول في داله ال if

كود:
		if (!RB0) //if pushbutton is pressed
		{	
	     	__delay_ms(50);
			ov_cnt=0;


Read more: http://www.qariya.com/vb/newreply.php?do=postreply&t=128416#ixzz2T74q3GXC
3- من الافضل نوضح العمليات الحسابية حتى تتضح الفكرة..
الان تايمر1 يحتوي على 16 بت..يعني راح يعد من 0 الى 65535
طيب اذا احنا فعلنا الكريستاله الداخلية وتم ضبطها على 16 ميجاهرتز. راح يكون زمن التعليمة في المايكروكنترولر pic هي 16ميجاهرتز / 4 = 4 ميجاهرتز. وزمن النبضة راح يكون 1/4Mhz= 250ns.
تايمر1 يعتمد على زمن النبضة لزيادة قيمة التايمر. اذا تايمر1 راح يبدا يعد من 0 الى 65535 لكل 250ns
فمثلاً:
تايمر1 ريجستر: الوقت
0 : 0s
1: 250 ns
2: 2* 500ns= 250ns
:
:
65535: 65535 * 16ms= 250ns

الان ان شاءالله وضحت فكرة الحساب ..خلينا ناخذ مثالين..واحد يحدث في طفح للتايمر والاخر بدون طفح للتايمر..حتى تتضح الفكرة اكثر

مثال 1: لو بنحسب تردد 100 كيلوهرتز.. وخلينا نقول ان اول rising edge حصل عند (تايمر1 ريجستر = 34 ,الوقت : 8.5us ) ..ثاني rising edge راح يكون:
تايمر1 ريجستر: الوقت
34 : 8.5us
8.5us + (1/100Khz) 18.5us: X
ولحساب قيمة x نضرب طرفين في وسطين:
x= (18.5u * 34) /8.5u
x=74
اذا عند حدوث اول rising edge عند Timer1=34 المفروض ثاني rising edge تحدث عندما Timer2=74 وللتاكد:
تايمر1 ريجستر: الوقت
34 : 8.5us
74: 18.5us
لونطرح زمن النبضة الثانية من زمن النبضة الاولى نحصل على (18.5us - 8.5us) نحصل على 10us. وللحصول على التردد ناخذ معكوس الفرق في الزمن F=1/t
F=1/10us
F=100Khz
وهنا صورة الناتج التي تم الحصول عليه عن طريق برنامج بروتس موكدة للعمليات الحسابية التي قمت بها في الاعلى:


مثال2: لو اردنا حساب اشاراة ترددها 1 هرتز..خينا هنا نشغل البرنامج في بروتس ونشوف النتيجة وبعد كذا نتاكد من العمليات الحسابية.. هنا صورة لحساب تردد 1 هرتز
http://upload.qariya.info/images/qar...bd30432f29.jpg
نلاحظ ان اول rising edge حدث عند timer1= 23728 اي عندما كان الوقت 5.9ms (23728* 250ns طيب الان نريد ان نعرف متى سيحصل ال rsing edge الثاني:
تايمر1 ريجستر: الوقت
23728 : 5.9ms
8.5us + (1/1hz) 1.0059s: X
الان نحسب قيمة x:

X= (23728 * 1.0059s) / 5.9ms
x= 4045422

الان عندنا مشكلة طفح..لان التايمر يعد الى 65535 بينما قيمة ثاني rising edge راح تحدث عند 4045422.9
اذا لمعرفة عدد مرات الطفح نقسم 4045422 على 65535 ..وراح تساوي 61 مره .

الان عندنا 60 طفح عدت65536 ( من 0 الى 65535) وعندنا طفح واحد عد 41807 ( من 23728 الى 65535).. اذا نحسب الوقت كالتالي:

(65536 * 60 * 250ns*(41807) + (250ns = تقريبا 0.99349175s
اذا
قراءة Timer1 لثاني rising edge :
x = (1s - 0.99349175s)/250ns
x=26033

الان عندنا القيم التالية :
firs edge: 23728
Second edge: 26033
timer1 overflow: 61
لو نستخدم المعادلة لحساب الوقت:
period= ov_cnt*65536 + temp2 - temp1
period = 61 * 65536 + 26033 - 23728
period =4000 001
اذا لحساب الوقت في الثانية نضرب في 250ns
period= 250ns * 4000 001 = 1s
ولحساب التردد ناخذ مقلوب الزمن
freq =1/1s = 1hz

5- نعم صحيح راح يرتفع علم مقاطعة ال capture ولكن لان ال GIE=0, فلن نحتاج الى سب روتين للمقاطعة..والكود سوف يكمل قراءة السطر الثاني

6- جربت اخذ كل 4 rising edge بس كانت تبطي عملية الحساب. وقراءت انه من الافضل اخذ 4 rising edge للحصول على دقة اعلى.. ولكن لم الاحظ تغيير.

7- عفوا اخي وان شاءاالله قدرت اجاوب على كل اسئلتك..واسف كتبت الرد على عجلة ولكن اذا عندك استفسار او تريد توضيح اكثر اسئلني وان شاءالله ارجع اوضح اكثر.

نقطه اخيرة جربت الكود على مايكروكنترول PIC16F1937 وكانت النتيجة ممتازة ولكن اذا كنت تريد دقة اعلى يفضل استخدام كريستاله خارجية لان الكريستاله الداخلية غير دقيقة حسب ماقريت. انا ممكن اعدل على الكود واشغله على كريستالة داخلية 32Mhz وهذا راح يساعدنا لقراءة ترددات عالية.
ايضاً لما كنت اعمل على الكود كنت افكر استخدام Atml بدل PIC لان زمن قراءة التعليمة لاتقسم على 4 وهذا راح يساعد بسهولة لقراءة ترددات عالية.


الصورة الرمزية حيدر علاج حسن
حيدر علاج حسن
:: مشرف منتدى الهندسة الكهربائية ::
تاريخ التسجيل: Mar 2005
الدولة: IRAQ
المشاركات: 9,848
نشاط [ حيدر علاج حسن ]
قوة السمعة:
قديم 13-05-2013, 09:15 PM المشاركة 14   
افتراضي



الزمن T هو مقلوب التردد لكنه يحسب الزمن بين النبضتين مضافا اليه زمن نبضة واحدة ..
اما الزمن بين النبضتين فهو t


Tico
:: عضو ذهبي ::
تاريخ التسجيل: May 2012
المشاركات: 1,423
نشاط [ Tico ]
قوة السمعة:
قديم 13-05-2013, 10:14 PM المشاركة 15   
افتراضي


السلام عليكم
أخي حيدر المتعارف عليه ان T هو الزمن بين نبضتين وهو مقلوب التردد f كما تفضلت بذكره.
أما t فما هو إلا الزمن t_off حيث ان :
T= t_on + t_off
علما بأن T هو الزمن الدوري (Periode)


الصورة الرمزية حيدر علاج حسن
حيدر علاج حسن
:: مشرف منتدى الهندسة الكهربائية ::
تاريخ التسجيل: Mar 2005
الدولة: IRAQ
المشاركات: 9,848
نشاط [ حيدر علاج حسن ]
قوة السمعة:
قديم 13-05-2013, 11:19 PM المشاركة 16   
افتراضي


عليكم السلام اخي و شكرا جزيلا لك ...
نعم هو كذلك و نحن نريد حساب الزمن t و طبعا لا يمكن ان نقول هو مقلوب التردد



الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 05:31 PM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)