منتديات الالكترونيات العصرية  
yoursite.com page title .

استرجاع كلمة المرور طلب كود تفعيل العضوية تفعيل العضوية
العودة   منتديات الالكترونيات العصرية > منتدى الحاكمات الدقيقة Microcontroller > منتدى المتحكمات ميكرو بلغة الاسمبلي

  #81  
قديم 08-23-2018, 10:52 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

أنظمة التأخير Delay Loops
وضعنا فى التعريفات خانتين باسم Del1,Del2 وهما كمتغيرين لحساب أزمنة التأخير. نحتاج بضع قيم متباينة للتأخير بعضها بالميكرو ثانية و بعضها بالمللي ثانية و لذلك نحتاج لحسابات بسيطة لتحديد هذه الدورات.
نستخدم كريستال 4 ميجا إذن النبضة ¼ أى 0.25 ميكرو ثانية. دورة الأمر تحتاج 12 نبضة إذن 12*0.25 = 3 ميكرو ثانية. و من ثم عندما نريد مثلا 120 ميكرو ثانية نقسم 120 / 3 = 40 دورة
أى نكتب DJNZ Del1,40 لكن طلب هذا الأمر سيحتاج دورتين و ذلك لو نسيت الأمر Acall Delay120 مثلا و العودة أيضا RET, RETI كلاهما يأخذ دورتين إذن لدينا 4 دورات يمكن حذفهم لتصبح 36 فقط.
كود:
Wait_120:            ; 3usec per inst
	MOV Del2,#36
	DJNZ Del2,$	
	RET
الآن لتأخير زمن طويل سنحتاج لدورة تكرر عدد من المرات أى فى داخل دورة أخرى وهى تسمى Nested أى متداخلة و النسق التقليدى لهذا هو
كود:
;---------------------------
; time:		10060 cyc.	(incl. ACALL/RET) 0.054 sec
; stack:	2		(incl. ACALL/RET)
wait_20ms:	
		MOV Del1,#107		; Del1 = 107
    _wait_20:	MOV Del2,#45		; Del2 = 45
		DJNZ Del2,$		; Del2--: If (Del2 > 0) repeat
		DJNZ Del1,_wait_20	; Del1--: If (Del1 > 0) _wait_20
	RET
عنوانWait_20ms ثم حفظ فى الخانة الأولى 107 لتكرر الدورة الداخلية 107 من المرات ثم عنوان ثانى للدورة الداخلية حيث تحفظ فى الخانة الثانية 45 مرة و تنقصها حتى الصفر مع الاختبار ثم تنقص الخارجية مع الاختبار لتكرر الداخلية 45 مرة لتعود فتنقص الخارجية و هكذا. بسيطة و سهلة و لكن لو أردت 47 مللى ستنشئ أخرى و ثالثة وهكذا وهو استهلاك للذاكرة فيما لا يجدى ، لذا هيأت الداخلية لتكفى 1 مللى ثانية و جعلت الخارجية للمستخدم يحدد فيها كم مللى ثانية يحتاج و من ثم لو أردت 1 مللى ضع 1 فى Del1 و اطلب هذا الكود و ألذى أسميته
كود:
Wait_n_ms:		; 333 instruction / ms	; Time in ms saved in Del1	
	MOV Del2,#165
	_wait_n:	
		nop
		DJNZ Del2,_Wait_n		
	DJNZ Del1,Wait_n_ms	
	RET
هنا أطلت زمن التقليل مع الاختبار بإضافة NOP قبلها و بذلك أصبحت 3 بدلا من 2 فقط ولو أردت أكواد أكبر فيمكنك تنفيذ أوامر ملغية مثل PUSH A ثم PULL A وهى أن تحفظ المراكم فى المصفوفة و تستهلك دورتين ثم تسترجعه فى دورتين و فى خانتى ذاكرة استهلكت ما يوازى 4 أوامر NOP و عندما كانت الذاكرة حرجة كان حفظ كل من A,B فى المصفوفة PUSH A , PUSH B ثم بعد ذلك الأمر MUL AB أى اضرب محتوى A فى محتوى B وهو يستهلك 4 دورات ولكن بايت واحدة فقط و قبل العودة استرجع B,A مرة أخرى PULL B , PULL A ما حفظ أخيرا يسترجع أولا فلا يغير أى شيئ .
وهذه الأكواد مطلوبة للذاكرة و للشاشة و للمحول التماثلى الرقمى أيضا
رد مع اقتباس
  #82  
قديم 08-24-2018, 09:16 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

أكواد الشاشة
درسنا سابقا أكواد التهيئة و قمنا بضبطها على 8 بت 5*8 الخ. الآن ندرس الكتابة فيها. ستقول الأمر سهل بأن نضع الحرف على المنفذ ثم نضع RS =1 ثم نضع E=1 ثم ننتظر ثم نضع E=صفر . أجل هذا صحيح لكن كم مرة سنكتبه؟ هذا هو السؤال فبدلا من هذا بما يستهلكه من جهد و خانات بلا جدوى من الذاكرة،نضعه فى كود نطلبه عند كل كتابة و نكتب مثيل له بوضع RS= صفر لتنفيذ الأوامر و من ثم يكون لدينا كود باسم Do_LCD وآخر باسم Writ_LCD ولو لاحظنا سنجد أننا نعامل الطرف E ذات المعاملة فى الحالتين و يمكن تسميته مثلا LCD_CLK و يصبح الكود المشترك هكذا وهو مثال لكون أو Subroutine له مدخلين مختلفين ، المدخل الأول هو Writ_LCD حيث نضع RS =1 ثم عنوان للنبضه LCD_CLK حيث نضع E=1 ثم ننتظر ثم نضع E=صفر و الانتظار فيما سبق غير ضرورى مع هذا الكريستال البطيء لكنه هنا للصورة العامة. ثم فى النهاية الانتقال لتأخير 120 ميكرو ثانية و هذه ميزة أخرى حيث لا نكرر كتابة هذا الأمر مع كل مرة نحتاج للتعامل مع الشاشة. يمكن تغيير هذه القيمة بحسب ما يتطلبه كل أمر وهذا سيأتى لاحقا فى كود التأخير إن شاء الله.
المدخل الثانى هو Do_LCD حيث نجعل RS = صفر ثم ننتقل للنبضة أيضا .

كود:
Do_LCD:
	CLR	LCD_RS		; Command Reg
	SJMP	LCD_CLK

Writ_LCD:
	SETB	LCD_RS		; Data Reg
	NOP
	LCD_CLK:
		SETB	LCD_Ena		;
		NOP			; DELAY > 175 ns
		CLR	LCD_Ena
		ACALL wait_120		; Wait Execution CurTime
	RET
الآن نحتاج لكتابة سطر كامل على الشاشة وهنا نفرق بين سطر ثابت ككتابة رسالة ترحيب أو سطر خطأ فعند اكتشاف عطب المحول فلا جدوى من الاستمرار فنكتب رسالة خطأ و نتوقف أو جزء من السطر كإضافة الوحدات مثل RPM أو Amp مثلا و كلمة Manu و كلمة Auto و بين سطر متغير حيث تحسب هذه القيم و تضعها على الشاشة.
السطر الثابت أسميته هكذا لكونه لا يتغير وهو جزء من الكود وهو رسالة تضعها فى اللغات العالية كثابت تطبعه على الشاشة وهو حقيقة سيضاف كجزء من الكود.
كل مترجم بالأسيمبلى يتيح لك تعريف جدول ثوابت تضعه حيث شئت لكن الأفضل وضعة فى نهاية الكود حتى لا تضطر للالتفاف حوله وهو بالكلمة DB أو Data Byte وهو مجموعة من القيم كل منها بايت كاملة بأى نسق مقبول مثل الثنائى أو العشرى أو الثمانى أو هيكسا أو DW أو Data Word وهى قيم من 2 بايت أى 16 بت. كل منها تبدأ بعنوان ثم الكلمة DB أو DW أ و ما شئت من قيم حتى تكتب عنوان آخر و تعريف آخر هكذا

كود:
Testing: DB "Testing Pls Wait"
ADCErr: DB "ADC: No Responce"
MemFlt: DB "Mem Err,MAN Def "
Auto4: DB "Auto"
Man4:  DB "Manu"
ByteExample:     DB    24,“A”,255,0Fh,0011b
WordExample:    DW   12300,0FFFFh,2,65500
الأسطر الخمسة الأولى مستخدمة فى برنامجنا كرسائل و تعريف و السطرين الأخيرين مثالين يحتويان أرقام و حروف نصية. العنوان هنا هام لكونه يحدد بدء المجموعة فهى أسبه بمصفوفة تبدأ بالعنوان و هنا الرسائل كلها 16 حرف لكونها تكتب فى سطر واحد ولو استخدمت شاشة أكبر 20 أو 24 حرف يمكنك الزيادة لما يناسبها. الآن كيف ننقلها للشاشة؟

لدينا الأمر باستخدام DPTR و سبق شرحة وهنا لدينا العنوان WriteMsg و أول أمر فقط للتأكيد على استخدامنا DPTR0 و إن كان حقيقة هنا لا يهم فلم نحتاج لتبديل DPTR و أى منهما سيكون فاعلا فلا بأس ثم نضع فى R7 أو أى خانة تختارها كعداد الرقم 16 لكوننا سننقل 16 حرف ثم عنوان NextC أى الحرف التالى

كود:
WriteMsg:	; Writes a message on LCD, start in 
	ANL	EECON,#11111011b	; Clear DPS bit in EECOM to select DPTR0
	MOV	R7,#16			; 16 character
	NextC:
	CLR	A
	MOVC	A,@A+DPTR		; Read 1st byte
	MOV	LCD,A			; put on lcd data
	ACALL	Writ_LCD 
	INC	DPTR
	DJNZ	R7,NextC
	RET
الأمر المستخدم هو MOVC A,@A+DPTR و هو يعنى MOVC اختصار انقل كود ولهذا الحرف C إلى المراكم A من خانة البرنامج المشار إليها بمجموع محتوى DPTR + محتوى المراكم A و هذا يتيح لك التعامل مع جداول شتى. هنا سنشير بالمؤشر DPTR فقط لذا نلغى محتوى A ثم ننفذ الأمر و جدير بالذكر أننا وضعنا عنوان الرسالة فى DPTR قبل طلب هذا الكود و من ثم سيؤشر المؤشر على أول حرف و نتيجة الأمر ينسخ الحرف فى المراكم A و من ثم نضعه من A على المنفذ ثم نكلب كود الكتابة على الشاشة السابق شرحه ثم نزود المؤشر DPTR بواحد ليشير للحرف التالى ثم ننقص العداد R7 بواحد فإن كان بصفر نكون اتممنا 16 حرف و إلا نعود للنقل الحرف التالى فى عنوان NextC و أخيرا نعود
السطر المتغير موضوعنا القادم بإذن الله:
رد مع اقتباس
  #83  
قديم 08-24-2018, 01:22 PM
MOHAMED_ABDELRAHMAN MOHAMED_ABDELRAHMAN غير متواجد حالياً
عضو جديد
 
تاريخ التسجيل: Aug 2018
المشاركات: 1
معدل تقييم المستوى: 0
MOHAMED_ABDELRAHMAN is on a distinguished road
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

شكرا جزيلا على المواضيع القيمة.
رد مع اقتباس
  #84  
قديم 08-25-2018, 06:53 PM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

اسعدنى مروركم الكريم
رد مع اقتباس
  #85  
قديم 08-26-2018, 09:42 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

السطر المتغير
السطر المتغير هو ببساطة حيث تقوم بحساب ما تريد ثم تجمع النتائج معا و تكتبها على الشاشة مرة واحدة و يمكنك الكتابة مباشرة من الحساب لكن لو تطلب الأمر تعديل القيم لن يكون لديك الحرية فى تهيئة السطر كما تريد لذا كثيرا أفضل تخصيص 16 خانة أكتب فيها ما أريد طباعته و عندما أقرر تحديث الشاشة أنقلها معا.
فى المقدمة خصصت Disp00 إلى Disp15 لتدوين نتائج الحساب فيها بصورة ASCII أى الرقم 5 يكون 035h وهى بصورة أخرى إضافة 030h تقابل 48 عشرى أى أن الرقم "7” = 037h وهى 55 بالعشري و فى النهاية استخدم الكود WriteLine لكتابة هذا السطر على الشاشة.
لو أردت كتابة رقم ما أو إشارة ما فببساطة استخدم الأمر MOV Dispxx,#NewValue و ذلك عوضا عن الحاجة لاستخدام الأمر goto character وهو 080h+Address لتوجيه الشاشة حيث اريد الكتابة ثم أبدأ.
كود:
WriteLine:		; Put Line number on buss then call
	ACALL	Do_Lcd		
	MOV		R0,#Disp00
	LineLoop:
	MOV		LCD,@R0
	ACALL	Writ_LCD
	INC		R0
	CJNE		R0,#Disp11,LineLoop
	RET
يبدأ بفرض أنك وضعت رقم السطر على المنفذ فيطلب تنفيذ الأمر ثم يضع العنوان الخاص بأول حرف وهو Disp00 فى R0 وبذا يكون R0 به 020h ثم عنوان تكرارى للسطر و يلى ذلك الأمر ينقل غير مباشر باعتبار R0 حاملا العنوان ما يشير إليه R0 للمنفذ LCD مباشرة ثم يطلب كود Writ_LCD لكتابته ثم نزيد R0 بواحد ليشير للتالى و نقارن محتواه بعنوان الخانة Disp11 و نكرر لو لا يتساوى إذن سنكتب عشرة أحرف فقط من الستة عشر و ذلك لكتابة Manu/Auto ولا حاجة لتكرار كتابتها إلا عند تغيير الوضع من يدوى لآلى أو العكس.
سنضع عنوان أى من الرسالتين فى DPTR ثم نطلب هذا الكود فنضع عنوان الكتابة بالأمر الخاص بها على المنفذ ثم نطلب تنفيذ الأمر ثم نحفظ عدد الأحرف 4 فى العداد R7 المستخدم فى كتابة رسالة و المشروح المرة الماضية لننتقل لعنوان NextC الحرف التالى وهذا أيضا كود ذو نقطتين مختلفتين.
كود:
LCD4:
	MOV		LCD,#13+80H	; 80H is Goto Command + address 13
	ACALL	Do_LCD
	MOV		R7,#4		; write 4 chrs
	SJMP		NextC
WriteMsg:	; Writes a message on LCD, start in 
	ANL	EECON,#11111011b	; Clear DPS bit in EECOM to select DPTR0
	MOV	R7,#16			; 16 character
	NextC:
	CLR	A
	MOVC	A,@A+DPTR		; Read 1st byte
	MOV	LCD,A			; put on lcd data
	ACALL	Writ_LCD 
	INC	DPTR
	DJNZ	R7,NextC
	RET
لتطوير هذا الكود لو لديك عدد متباين من الحروف كل مرة، يمكنك وضع عدد الأحرف فى R7 أو العداد ألذى تختاره و بدء الكتابة على المنفذ و تطلب الكود فقط تحذف السطرين حيث MOV R7,#4 و السطر MOV R7,#16
كود:
WriteMsg:	; Writes a message on LCD, start on port, count in R7
	ANL	EECON,#11111011b	; Clear DPS bit in EECOM to select DPTR0
	ACALL	Do_LCD
       NextC:
	CLR	A
	MOVC	A,@A+DPTR		; Read 1st byte
	MOV	LCD,A			; put on lcd data
	ACALL	Writ_LCD 
	INC	DPTR
	DJNZ	R7,NextC
	RET
لو شئت لأى سبب محو الستة عشر خانة خاصة لو تريد كتابة قليلة مع بقاء الباقى خاليا يمكنك استخدام هذا الكود
كود:
ClrTxt: MOV	R0,#Disp00
   TTT:	MOV	@R0,#20h
	INC	R0
	CJNE	R0,#30h,TTT
	RET
بقى لدينا كود القراءة من المحول وهذا موضوعنا القادم بإذن الله
رد مع اقتباس
  #86  
قديم 08-28-2018, 11:24 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

كود المحول
درسنا كيف يعمل المحول التماثلى رقمى و عرفنا بعض الأشياء عن المتكاملة ADC0808 و علمنا أن هناك كثير غيرها بدقة أعلى من 8 بت. على أى حال هذه المتكاملة تعمل فى دورة من 8 خطوات لو أصدرنا لها أمر لبدء التحويل لن تبدأ فيه قبل تمام الدورة لذا لها طرف اسمه EOC اختصار End Of Count لن يصبح بصفر مباشرة إلا صدفة أو يكمل ثمانية نبضات وهى فى طريقتنا فى التوصيل تكافئ 8 أوامر NOP أو اربعه من ذات الدورتين كحد أقصى . لذا لبدء القراءة نضع أولا العنوان و هنا لدينا 3 خطوط لكونها تقرأ من 8 مداخل إلا أننا نستخدم 2 فقط لذا وصلنا الخطين الباقيين للأرضى و بذلك أصبحنا نقرأ من مدخل صفر و مدخل 1 فقط و نختار بينهما و هذا الطرف باسم I_NV أى التيار لو = 1 ولو = صفر يقيس الفولت على المقاومة المتغيرة المستخدمة لضبط السرعة.

بعد تحديد العنوان نضع 1 على خط ADCStart لبدء دورة قياس ثم نعيده للصفر و هنا تبدأ داخليا تتهيأ لقياس كما باللون الأزرق مع ملاحظة أن ALE بحسب الدائرة متصل بالخط START و يتغيران معا.


كود:
GetADC:			; Set ADC adress, reply in A
	SETB	ADCStrt
	NOP
	CLR	ADCStrt
	MOV	Del1,#20
	DJNZ	DEL1,$		; Now EOC should be zero
	JB	EOC,Fault	; if still one, it is defective
	MOV	DEL1,#100
   ADCloopChk:
		JB	EOC,ADCOK		; if EOC = Hi again it is ok
		DJNZ	DEL1,ADCloopChk	; did not responde
   Fault:		
	AJMP	ADCFault
   ADCOK:
	MOV	A,ADC
	RET
نظرا لكوننا غير قادرين على تحديد متى ننتظر الخط EOC أن يصبح صفر فهو كما بالسهم الأحمر عند اكتمال من صفر إلى 8 نبضات ، لذا ننشئ دورة تكفى أن تكون 8 لكن للاحتياط جعلتها 20 فلا تأخير هنا سيحتسب لأن الوقت مشاركة بين هذه النبضات الثمانية و اللازمة للتحويل وهى حتى 64 بحسب القيمة لذا بعدها يجب أن يكون EOC = صفر .
نختبر لو =1 إذن المتكاملة تالفه و نقفز لعنوان Fault أى عطل و إلا لو قبل انتهاء العد عادت للقيمة 1 طبقا للخط البنفسجى يكون التحويل قد اكتمل فننتقل للعنوان ADCOK أى المحول أوكي حيث نضع القيمة من المنفذ للمراكم A ثم نعود طبعا بالأمر RET لكن لو انتقلنا للعنوان حيث يوجد عطل ستجد أمر انتقال AJMP ADCFault و هناك فى أول الكود ستجده حيث تكتب رسالة أن المحول لا يعمل ثم تتوقف نهائيا فلا جدوى من العمل بدونه.
الكود من صفر حتى 255 لذا المرة القادمة إن شاء الله نحوله لأعداد لكتابتها على الشاشة
الصور المرفقة
نوع الملف: jpg DC_motor-C51ADC.jpg‏ (27.4 كيلوبايت, المشاهدات 12)
نوع الملف: jpg ADC0808 timing.jpg‏ (23.8 كيلوبايت, المشاهدات 13)
رد مع اقتباس
  #87  
قديم 08-30-2018, 09:01 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

التحويل من ثنائى لعشرى و الكتابة
الآن قرأنا من المحول و نريد تحويل القراءة لنص على الشاشة. تعرضنا سابقا لأمر الضرب MUL AB حيث نضرب رقمين كل منهما من 8 بت موجب أحدهما فى A و الآخر فى B و النتيجة ستكون 16 بت البايت الصغرى فى A و الكبرى فى B و لو الناتج أكبر من 255 فالعلم OV =1 و هذا لسبب أن فى حالة = صفر فالناتج أقل من 256 و بالتالى يكون كله فى المراكم A ولا حاجة للتعامل مع B فهو = صفر.
الآن نتعامل مع الآمر المكمل له وهو DIV AB حيث يقسم الرقم الموجب فى A على الرقم الموجب فى B و يكون الرقم الصحيح فى A و الباقى فى B و هنا لو كان المقسوم عليه B = صفر فالناتج غير محدد و العلم OV=1 كدلالة على خطأ فى الحساب.
الكود هنا يفترض الرقم فى A و يعطى الناتج فى مسجلات R7,6,5
كود:
Bi2BCD_Ascii: ; converts data in Acc to 3 digits Ascii in R5(units) and R6(tens),R7(Hundred) MOV B,#100 DIV AB ; Devide A/100, Hunderds in A, remainder in B ORL A,#30h ; Convert to ascii MOV R7,A ; save 100's MOV A,B ; Get remainder MOV B,#10d DIV AB ; Devide A/10, Tens in A, remainder in B ORL A,#30h ; Convert to ascii MOV R6,A ; save Units ORL B,#30h MOV R5,B ; put result RET
نبدأ بوضع 100 فى B و نقسم الرقم بالأمر DIV AB فيكون العدد الصحيح 0 أو 1 أو 2 فى A و الباقى حتى 99 فى B. و نحول الرقم المئات لحرف بإضافة 030H أو 48 عشرى و كثير من البرامج تستخدم ORL بدلا من ADD و لكن كلاهما سيان فى الميكرو لكن مع المتحكم سترى. ثم ننقل الحرف الأول للمسجل 7 ثم ننقل الباقى من B إلى A و نضع الآن 10 فى B لنقسم على 10 . نتيجة القسمة العشرات فى A و الآحاد فى B و نضيف على العشرات 48 للتحويل لحرف و نحفظه فى R6 و الآحاد لنضيف بالأمر ADD لوضع أحدهما فى A و لكن بالأمر ORL نستطيع أن ننفذه مباشرة على B دون نقل ثم بعد ذلك نحفظه فى R5 لنعود.
الآن نريد الكتابة على الشاشة فنبدأ بتحويل قيمة السرعة الحالية CurrSpeed لحروف ثم نعرضها و هنا يجب أن نذكر أمر قبل أن تعترض. من أين نعلم أن سرعة الموتور مطابقة للمدى من صفر إلى 255؟ هنا للسهولة افترضنا ذلك لكن فى الواقع ستحتاج لإضافة أمرين فقط
القراءة القصوى 255 و السرعة القصوى مثلا 6000 أعيد لذهنك الحقيقة أنك لو لم تستخدم تاكو كعداد فالمسألة كلها تقريبية لذا فلا بأس من نسبة خطأ ولو وصلت 10%
سنقول 6000 / 250 = 24 أى تحتاج لضرب القراءة فى 24 لكن على أى مقياس لن تقرأ حقيقة سرعة3521 و سرعة 3522 و هكذا فأنت أصلا تقفز مع كل بت 24 عد أى ستقرأ 3480 ثم 3504 ثم 3528 إذن إما تستخدم محول ذو عدد بت أكبر و هنا ستعانى من الفرق فى الدقة بين ما يكون فى الواقع من سرعة نتيجة الحمل الخ و بين ما تقوله الحسابات.
لذا أقترح أن تستخدم صفرين و تكتب الرقمين فقط. بقى أن نحول هذه 255 إلى 600 وهى النسبة 2.4 ولدينا أمرى الضرب و القسمة فنقسم أولا على 10 ثم نضرب فى 24 دون الحاجة لحسابات الأرقام الكسرية
الآن استخدمنا CurrSpeed لأنه معبر عن السرعة المطلوبة الحالية سواء من الذاكرة أو من المقاومة و لكنها ما نحتاجه الآن. نحوله لحروف ثم ننقلها من R7,6,5 لخانات Disp00,01,02 ثم نضيف الصفر و مسافة و حروف RPM ثم نقطة و حرف & لأنه يعنى "و" لنضيف لاحقا كلمة Auto أو Manu ثم نضع 2 على منفذ الشاشة للعودة لأول الشاشة و نطلب كود كتابة سطر و ألذى سبق شرحه وهو ينفذ الأمر بالتوجه للسطر السابق وضعه وهو 00 أى الأول ثم أمر تصفير مسجل الحراسة WDT
كود:
	
ShowValues: MOV A,CurrSpeed ACALL Bi2BCD_Ascii MOV Disp00,R7 MOV Disp01,R6 MOV Disp02,R5 MOV Disp03,#"0" MOV Disp05,#" " MOV Disp06,#"R" MOV Disp07,#"P" MOV Disp08,#"M" MOV Disp09,#"." MOV Disp10,#26h ; Type "&" MOV LCD,#2 ; Goto HOME ACALL WriteLine ; Line no 1 = 00, it has goto line nu ORL WDTCON,#2 ; clear WDT SETB InotV ; Get Current Reading ACALL GetADC ACALL Bi2BCD_ASCII MOV Disp00,R7 MOV Disp01,R6 MOV Disp02,#"." MOV Disp03,R5 MOV Disp05,#"A" MOV Disp06,#"m" MOV Disp07,#"p" MOV Disp08,#"s" MOV Disp09,#" " MOV Disp10,#" " MOV LCD,Line2+080H ; 80H to create Goto Location in LCD memory ACALL WriteLine ; Line no 1 = 00 AJMP Looping
يلى ذلك تغيير الفولت و التيار لقياس التيار بالأمر GetADC ثم نحول لأحرف و نكرر و نضع السطر 2 و نكتب.
الآن نبدأ فى كتابة كود البرنامج
رد مع اقتباس
  #88  
قديم 09-01-2018, 09:03 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

كود البرنامج:
أتممنا المخدمات التى تكمل أداء المهام و الآن نبدأ فى كود صلب البرنامج. البداية من جزأين الأول تهيئه العتاد ثم الجزء الثانى التهيئة للتشغيل.
كشأن كل الميكرو عادة يكون عنوان صفر هو البدء Reset و لذا و لأن عنوان المقاطعة الخارجية هو خانة 3 فلا يسعنا إلا الانتقال للبدء فنجد AJMP BeginP و يليه العنوان 3 حيث المقاطعة الخارجية من زر STOP أو التوقف وهذا طارئ يجب التوقف فورا ثم نفكر لاحقا فنوقف التايمر و نوقف الموتور ثم ننتقل لتهيئه ظروف التشغيل. يلى ذلك مقاطعة التايمر وهى الخاصة بموضوع PWM .

كود:
org	000
	AJMP	BeginP	
org	003h 			; Adress of INT0 (IE0)Emergency  	
	SETB	PWMout		; HI = Stop
	CLR	TR0		; Stop counter
	SJMP	Emrgncy		
org	00Bh			; Adress of Interrupt Timer 0 (TF0)		
	XRL	TH0,#255 	; Complement Timer Hi		
	CPL	OutLo
	MOV	C,OutLo
	MOV	PWMout,C	
	RETI
فى جزء التهيئة السابق تحدثنا عن PWM و ذكرنا أنه يتم بأن نجعل العد المناسب في تايمر TL0 و المتمم أو المكمل له وهو 255-العد فى TH0 و بذلك سنتحرك حسب العد حتى يصل 255 وهنا تحدث مقاطعة فنأتى هنا و المطلوب فقط أن نعكس الخرج وهو PWMout وهذا سهل بالأمر CPL bit لكن هذا الأمر يجب أن يعرف قيمة البت أولا ثم يعكسها و مخارج كل متحكم قد تتأثر بالحمل ولذا البعض جهز بمسجل واقى Buffer لهذا الغرض. حسنا وفرنا هذا الواقى بالبت OUTLo و من ثم سنتمم أى جعل الآحاد أصفار و العكس هذه البت ثم ننقلها لمخرج PWM ولا ننسى أن نسخ بت لا يكون إلا بين C و أى بت أخرى ، و أيضا سنتمم محتوى TH0 لأنه لو يحتوى العد الآن فالتالى بعد المقاطعة يجب أن يكون تمامه و العكس بالعكس.

العنوان التالى هو بداية الكود وهذا الجزء للتهيئه حيث نهيئ المقاطعات كلها و التايمر صفر و الخارجى ثم تهيئة التايمر 8 بت ذاتى التحميل ثم تهيئه المقاطعة قدح بالحافة ثم ننتظر 20 مللى ثانية للشاشة لتكمل البدء ثم اربعه أوامر للشاشة لتعمل 8 بت سطرين 5*8 و تفعيل الشاشة و إخفاء المؤشر و ثبات الشاشة مع حركة المؤشر لليمين و أخيرا محو الشاشة و البدء من الصفر.

كود:
BeginP:	
	CLR	LCD_Ena		; Clear LCD ENA bit    Init_LCD
	MOV	IE,#10000011b		; Enable T0 & INT0 external	
	MOV	TMOD,#00000110b		; T0 8bit counter auto reload
	MOV	TCON,#1	; Clr All interrupts, Set INT0 Edge trigger  #5 for INT0,INT1
	mov	Del1,#20		; call del with 20 ms
	ACALL	wait_n_ms		; Wait LCD	
	MOV	LCD,#00111000b	; 8bit, 2line, 5X8 display
	LCALL  Do_LCD	; Execute: WAIT IS ADDED TO STORE_CMD 
	MOV	LCD,#00001100b	; Set display on,cursor off, blinking off
	LCALL	Do_LCD		
	MOV	LCD,#00000110b	; Set Increment +1 mode, move screen off
	LCALL	Do_LCD	
	MOV	LCD,#00010100b	; Shift Cursor, dcn=right
	LCALL	Do_LCD			
	MOV	LCD,#1		; clear entire display
	LCALL	Do_LCD		
	ORL	EECON,#00001000b	; XX,EELD Page/nbyte, mem Write ena,MOVX w dptr to 
;eeMem DPS=0 Bank1 or 1 bank2' 1 = ready 0 busy, if VDD << it is ZERO (Read only) Write_Inh
	MOV	DPTR,#Testing
	ACALL	WriteMsg		; write testing pls wait
	ACALL	GetADC		; if error will ret to ADC Fault
	SJMP	OKey
	ADCFault:
	SETB	PWMout		; HI = Stop
	MOV	DPTR,#ADCErr
	ACALL	WriteMsg
	SJMP	$
	OKey:
يلى ذلك تهيئة الذاكرة EEPROM داخله حيث يجب وضع 1 لتوجيه الأمر MOVX A,@DPTR للذاكرة بدلا من الخارج. ثم نحمل DPTR مؤشر البيانات بعنوان الرسالة Testing لإخبار المستخدم بالانتظار. ثم نطلب كود كتابة رسالة ثم نطلب كود القراءة من المحول ، فإن أتم القراءة سيعود بأمر RET و ألذى يقوده للخطوة التالية وهى القفز لعنوان OKEY و إلا سيعود من هناك بأمر القفز للعنوان ADCFault حيث نوقف الموتور أولا ثم نحمل مؤشر البيانات بعنوان الرسالة ADCErr و نطلب كود كتابة رسالة ثم يدخل فى دورة لا منتهية فلا يعمل شيئ حتى يوقف الجهاز و يتم إصلاحه ومن ثم إعادة تشغيله.
رد مع اقتباس
  #89  
قديم 09-04-2018, 09:01 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

تهيئة القيم:

الآن الوحدة سليمة و عدنا للعنوان Okey سنجد كود تهيئه القيم المطلوبة للعمل و تبدأ بالعنوان Emergncy وهو نفس الموقع Okey فقط تكون أوضح حينما تنتقل من كذا لكذا ثم تضع منفذ Cmnds كله آحاد ماعدا RS,E يجب أن يكونا صفرين لتشغيل الشاشة و إطفاء الليدات كلها ماعدا Stop, Manual كحالة افتراضية للبدء و خرج PWM أيضا =1 لأن عائلة C51 تبدأ هكذا ولذا جعلناه يقطع التيار عن الموتور. ثم ننقل مؤشر الرصة بعيدا و نهيئ مؤقت الحراسة و شرح كل بت بجواره للتذكرة وهى 7و6و5 لزمن 128 مللى فى 4 لأننا نستخدم كريستال ربع التردد ثم نبطل فى حال التوقف ثم لا ريسيت للبوردة و التعامل بالبرنامج ثم تصفير و إتاحة . يلى ذلك تحميل مؤشر البيانات DPTR بصفر و نستخدم الأمر MOVX A,@DPTR لنقرأ الخانة صفر و فيها هل نعمل آليا أم يدويا و القيمة ستكون فى المراكم A و نحفظها فى المتغير MAN_NAUTO ثم نقفز لو = صفر للعنوان Auto فالقيمة صفر تعنى آليا أما أى قيمة أخرى تعنى يدوى وهنا فقط نضىء ألليد المناسب و نطفئ الآخر ثم نزود مؤشر البيانات DPTR بواحد ليشير للخانة التالية حيث القيمة المختارة للسرعة الآلية و نقرأ بذات الأمر MOVX A,@DPTR و نحفظ الناتج فى متغير SavedSpeed أى السرعة المحفوظة

كود:
	
Emrgncy:
	MOV	Cmnds,#00111111b	; All Off RS,E low	
	MOV	ADC,#255
	MOV	LEDs,#11110101b	; PWM off,InV=I,ADC start,RUN off,Stop On,Save off,Manual On,Auto Off
	MOV	SP,#70		; Move stack away
	MOV	WDTCON,#01100010b ; 7,6,5 time,WDTidle=0,DISRTO(dis Rst out)=no 
	; out,HWDT Hard wdt=noWSWRST soft reset ,WDTEN read only disabled low power 
	MOV	DPTR,#0		; Read Mem 00
	MOVX	A,@DPTR
	MOV	MAN_Nauto,A		; MAN_Nauto
	JZ	Auto
		CLR	MANLED
		SETB	AutoLED
		SJMP	GoOn
	Auto:
		CLR	AutoLED
		SETB	ManLED
	GoOn:	
	INC	DPTR
	MOVX	A,@DPTR
	MOV	SavedSpeed,A	; Value		
	MOV	SScntr,#SlowStart
	MOV	TL0,#254		; Hi=1 and low = 254
	MOV	TH0,#1
	SETB	OutLo		;  Zero =Motor Run, 1= Motor Off.  OutLo = PWMout
	MOV	CurrSpeed,#0		; Start from zero
	JNB	STOPsw,$		; Wait while sw pressed
	
	MOV	A,MAN_NAuto
	SUBB	A,#1Fh			; C if zero or 0f, otherwise defective
	JC	Looping
	MOV	DPTR,#MemFlt
	ACALL	WriteMsg	
	MOV	DEL1,#0		; delay 255 ms
	ACALL	Wait_n_ms	
	ACALL	Wait_n_ms
	ACALL	Wait_n_ms
	MOV	LCD,#1
	ACALL	DO_LCD		; Clear display
بعد قراءة السرعة وضعنا فى متغير SlowStart قيمة 5 كما سبق الذكر أننا خاصة فى الموتورات الكبيرة نحتاج الزيادة ببطء و التوقف مفاجئ و سبق أن قلنا لو لدينا لوحة أزرار يمكننا اختيار هذه القيمة و حتى فى وجود فرملة يمكن التحكم فى قدرها.
سنبدأ بالعد 254 فى TL0 أى تشغيل 1 فقط و العد 1 فى TH0 أى التوقف من 1 وحتى 255 ثم نحمل CurrSpeed=صفر لتبدأ دوما من صفر سرعة مهما كانت الظروف.
إن كان مازال الزر StopSw مضغوطا "تذكر البرامج السابقة" ننتظر تركه حرا ثم نضع فى A قيمة MAN_NAuto وهى للتذكرة إما صفر أو 0FH أى 15 ثم نطرح منها قيمة 1FH أى31 فلو نتج C كانت القيمة صحيحة و إلا فهى أكبر من 1Fh أى أن الذاكرة لم تحفظ القيمة و أعطت بدلا عنها 255 أى 0FFh و هنا سنضع عنوان رسالة الخطأ فى مؤشر البيانات DPTR و نكتب رسالة الخطأ لكن لن نوقف العمل فما زلنا نستطيع العمل يدويا. نضع صفرا فى DEL1 و نطلب كود الانتظار فينتظر 256 مللى ثانية لأنه سيقلل الصفر قبل الاختبار فيجعله 255 ثم نكرر التأخير لضمان رؤية الرسالة ثم نمسح الشاشة.
يلى ذلك كود الدورة المستديمة وهى موضوعنا القادم إن شاء الله
رد مع اقتباس
  #90  
قديم 09-16-2018, 09:38 AM
ماجد عباس محمد ماجد عباس محمد غير متواجد حالياً
استاذ
ومشرف الكترونيات
 
تاريخ التسجيل: Jun 2011
الدولة: القاهرة - مصر
المشاركات: 1,394
معدل تقييم المستوى: 26
ماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant futureماجد عباس محمد has a brilliant future
افتراضي رد: الميكرو كونترولر انواعه و برمجته و استخداماته

الدورة المستديمة
بعد التجهيزات السابقة نبدأ الدورة التى سنكررها دوما وهى ببساطة تراقب الأزرار و تستجيب لها . أول الدورة أمر تصفير مؤقت الحراسة بالأمر ORL WDTCON,#2 ثم نفحص زر ManAuto فإن كان =1 يعنى ذلك أنه لم يضغط فننتقل لفحص التالى وهو Save و إلا سنعكس حالة ليدات MANLED,AUTOLED فتتغير من آلى ليدوى أو العكس ثم ننتظر فى دورة مغلقة حتى ترك زر آلى / يدوى ثم نختبر ليد MANLED فإن كان = صفر أى اليدوى مضاء إذن الخيار هو يدوى فننتقل لعنوان SETMAN وإلا فالخيار هو آلى. و نكمل حيث "نضىء ليد اليدوى" تأكيدا و نطفئ ليد آلى و نصفر المتغير MAN_Nauto كعلامة للاختيار ثم نضع فى مؤشر البيانات DPTR عنوان رسالة Auto4 وهى رسالة من 4 حروف Äuto ثم ننتقل لعنوان WriteIt وهو عنوان وسطى لتجنب كود الخيار اليدوى. أما لو كان يدوى سننتقل لعنوان SetMan حيث نضىء و نطفئ الليدات و نضع فى المتغير MAN_Nauto القيمة 15 وهى ما سنحفظه فى الذاكرة كقيمة مغايرة للفرضية 255 ، للتأكد أن الذاكرة قد حفظت صفرا أو قيمة أقل من 255. و نضع فى مؤشر البيانات DPTR عنوان رسالة Man4 وهى رسالة من 4 حروف "Manu” ثم ننتقل لكود كتابة هذه الرسالة على ألسطر العلوى أقصي اليمين فتكون الكتابة مثلا 4500RPM Manu
بعد تغيير يدوى / آلى نجد كود Save فإن كان زر Save مضغوطا ننتقل لكود الحفظ فى الذاكرة السابق شرحة و يلى ذلك زر التشغيل
كود:
	
Looping:	
	ORL	WDTCON,#2		; clear WDT
	JNB	MANAuto,Save
		CPL	MANLED	; Switch AutuMan
		CPL	AutoLED
		JNB	MANAuto,$	; Wait Sw released
					
		JNB	MANLED,SetMan	; MAN off, set man on
		CLR	AutoLED		; Auto On
		MOV	MAN_Nauto,#0	; MAN_Nauto =0
		MOV	DPTR,#Auto4
		SJMP	WriteIT
	SetMan:
		CLR	MANLED		; Man On
		SETB	AutoLED		; Auto Off
		MOV	MAN_Nauto,#0Fh	; MAN_Nauto = 0F mem default
		MOV	DPTR,#Man4
	WriteIt:
	ACALL	LCD4
Save:	
	JB	SaveSw,RUN		; Save Not Pressed
	ACALL	WriteEEPROM
سنأتى هنا أولا فى حال التوقف مع بدء التشغيل ، لذا نختبر إن كان طرف زر التشغيل =صفر فقد تم الضغط عليه للبدء فننتقل للعنوان GoNow حيث سننتظر حتى يحرر الزر ثم نضىء RUNled و نطفئ StopLed ثم نكمل فى كود Running و إلا لو حال وصولنا كان زر التشغيل =1 إذن هو حر ولم يضغط عليه فنتأكد أن ليد Stop مضاء أى أننا فى حال التوقف فننتقل لبدء الدورة من جديد.
فى كود Running نقوم بالأمر ORL WDTCON,#3 بتصفير عداد الحراسة و تشغيله معا ثم نضع المتغير Man_NAuto فى المراكم A فإن لم يكن بصفر نقفز للتحكم اليدوى وإلا نكمل فى كود التحكم الآلى.
كود:
Run:
	JNB	RUNSW,GoNow		; RUN pressed
  	JNB	STOPled,ShowValues		; Stop Mode do nothing
  	SJMP	Running
  GoNow:
  	JNB	RUNSW,$		; Wait release
  	CLR	RUNLed
	SETB	STOPLed	
  Running:			; Runing	
	ORL	WDTCON,#3		; Start and clear WDT	
	MOV	A,Man_Nauto
	JNZ	ManualControl
		MOV	ReqSpeed,SavedSpeed	; Set required Speed as saved
		SJMP	SetMotor
	ManualControl:
		CLR	InotV
		ACall	GetADC
		MOV	ReqSpeed,A			; Set required speed as ADC
	SetMotor:		; set pwm
	MOV	A,ReqSpeed	
	SUBB	A,CurrSpeed		; If Curr > Req in A then a carry and needs to slow down
	JNC	SpeedUP		 
		MOV	CurrSpeed,ReqSpeed
		SJMP	AdjSpeed
   SpeedUP:
فى كود التحكم الألى سننسخ القيمة المحفوظة SavedSpeed فى المتغير ReqSpeed فهذه هى القيمة التى نريد بلوغها ثم ننتقل لعنوان SetMotor أى ضبط الموتور ، و إلا سنكون فى التحكم اليدوى فنصفر InotV لنختار قياس الفولت ثم نطلب كود GetADC لقراءة المحول وهو لو سليم سيعود بأمر RET لهذه الخطوة وإلا سيتوقف كليا و عند عودته ننسخ القيمة المضبوطة عليها المقاومة المتغيرة فى ReqSpeed فهذه هى القيمة التى نريد بلوغها.
يلى ذلك كود SetMotor حيث ننسخ ReqSpeed فى المراكم و نطرح منها السرعة الحالية CurrSpeed فلو كانت السرعة الحالية أقل من أو تساوى المطلوبة فلا يتطلب ذلك Carry و من ثم C = صفر أى نحتاج لزيادة السرعة فنقفز لعنوان SpeedUP اى زيادة السرعة ، و إلا سيكون C=1 وهنا يجب خفض السرعة فورا للقيمة المطلوبة.

نفعل ذلك المرة القادمة إن شاء الله
رد مع اقتباس
إضافة رد

مواقع النشر (المفضلة)

أدوات الموضوع
انواع عرض الموضوع

تعليمات المشاركة
لا تستطيع إضافة مواضيع جديدة
لا تستطيع الرد على المواضيع
لا تستطيع إرفاق ملفات
لا تستطيع تعديل مشاركاتك

BB code is متاحة
كود [IMG] متاحة
كود HTML معطلة



الساعة الآن 08:45 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
الحقوق محفوظة لمنتديات الاليكترونيات العصرية

Security team

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77