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

   

ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 25-07-2018, 08:29 AM المشاركة 89   
افتراضي




كود المفاتيح keyPad
سبق أن شرحنا فكرتها وهى الصفوف و الأعمدة و الآن للتطبيق. هنا نقطة لنتحسب لها، أنك ستجعل 4 طرف خرج و 4 دخول، الدخول عادة غير محدد لكونه معاوقة كبيرة و من ثم سيحتاج لمقاومة إما للأرضى أو للموجب إذن يمكننا أن نضع 5 فولت على أحد الصفوف ثم نرى من أى عامود خرج أو العكس بالطبع نضع على أى عامود ونرى من أى صف خرج. أيضا يمكننا أن نضع صفر على أحد الأطراف و نرى من أى طرف خرج.

كما سبق القول فمنافذ أتميل عندما تكون دخل أى وضع آحاد عليها، فهى فى الواقع توصل الطرف من خلال مقاومة جذب لأعلى ضعيفة وهذا سبب عدم قدرتها على الإمداد بتيار و حاجتنا لهذه الدائرة الخاصة لنتمكن من تفعيل الريلاى . بهذا لو وضعنا FF أو 255 على منفذ سيكون كل الأطراف عليها 5 فولت ولا حاجة لتوصيل مقاومات خارجية.
الآن ضع صفر على طرف ما سيكون قادر على أن يبتلع مئات المرات التيار ألذى يصدره أى من الأطراف الباقية ، حسنا ما بقى أن نضغط الزر و نرى أين خرج هذا الصفر.

قبل أن نفكر فى أى شيئ يجب تحديد وظائف الأزرار، فلدينا عادة عشرة أزرار متفق عليها من صفر إلى 9 و لدينا سته متباينة لكن سنرقمهم من أعلى لأسفل بالأرقام 10 ، 11 ، 12 ، 13 ، 14 ثم 15

هذه الأزرار يكتب عليها أى شيء فكما فى المثال السابق تكون A,B,C,D حيث A=10 و هكذا أو أحيانا F1,F2,F3,F4 حيث F1 = 10 وهكذا و يليها # قبل الصفر ثم * بعده و أحيانا F1,F2,F3 ثم Enter ورقمه 13 ثم Cancel برقم 14 ثم الصفر و أخيرا أى كلمة أخرى مثل Mode برقم 15
لنتفق مع أى لوحة أزرار قد نجدها سنجعل وظيفة 13 هى Enter و تكون تشغيل الجهاز ثم 14 Cancel بمعناها و تلغى فقط ما سبق إدخاله قبل التشغيل و أثناء التشغيل تكون إيقاف مؤقت كما فى حال فتح الباب و الأخير إيقاف تام أى إلغاء ما بقى من وقت و العودة للبدء.
يبقى لدينا ثلاث أزرار أكواد 10 و 11 و 12 فيمكننا جعل الأول أثناء العمل يزيد 10 ثوانى و الثانى يزيد دقائق و الثالث يزيد 10 دقائق و نظرا لعدم وجود زر آخر لتنقيص الرقم سنجعل كل منهم دوار بمعنى يتحرك من صفر إلى 9 ثم صفر مرة أخرى ولا يحدث أى من الأرقام الأخرى فمثلا لو لديك 3:45 ثم حركت الدقائق تصبح 3:55 ثم 3:05 وهكذا كما لو أنك أنقصت الرقم. و هكذا.
هنا أيضا نحتاج أن نحدد كيف ندخل الطاقة المخفضة التى تحدثنا عنها. المشكلة أنه لم يعد لدينا أزرار لذا سنجعل زر 10 مزدوج الأداء بمعنى لو ضغط قبل التشغيل يتولى ضبط نسبة الطاقة و إن ضغط أثناء التشغيل يزود الزمن 10 ثوانى كما اتفقنا.
هذا الكود يحتاج بضع احتياطات مثلا لو ضغطت على زر سيقرأه المتحكم عدة مرات لسرعته فى تنفيذ الأوامر ، لذا سنحتاج أن نتأكد من أن الزر قد ترك قبل أن نعيد القراءة و أبسط حل إضاعة نصف ثانية حتى يرفع الشخص يده و لهذا ميزة و عيب أنه يمكنك من تكرار الإدخال دون الحاجة لرفع الأصبع لكن عيبه أنه يختلف من شخص لآخر، و هناك من يضع دورة يقرأ ذات الكود حتى يتغير و لكن لدينا إمكانيه المقارنة و القفز عند التساوى وهى تحتاج 3 بايت .

حل ثالث هو أننا نبدأ بوضع 255 أو FF على الخرج فإن كان هناك كود تحول إلى قيمة من صفر إلى 15 أى 0F و من ثم نستشعر البت رقم 7 و نستخدمها Flag ، طالما هناك كود سيكون = صفر أما لو رفع الإصبع سيكون =1
بهذا و بمجرد إضافة تعريف بلا كود نستطيع أن نختبر هذه البت بدلا من أمر قارن و اقفز CJNE و هكذا نضع عنوان
كود:

ReadAndChk:
	ACALL	ReadKPD
	JNB	NoKey,ReadAndChk		; Wait  key released
	RAC:
	ACALL	ReadKPD
	JB	NoKey,RAC			; wait Key pressed
	MOV	A,#9				; Put 9 in Accumulator
	CLR	C				; clear carry
	SUBB	A,B				; Command Or Number
	RET
ثم نقرأ الأزرار ونختبر البت رقم 7 و التى أسميناها NoKey بالأمر JNB و طالما هى بصفر أى يوجد رقم سابق فننتقل للعنوان و بهذا ننتظر رفع الأصبع عن الأزرار و بعدها يدخل فى الاختبار التالى لانتظار رقم بالضغط على زرار و ألذى بدوره يجعلها = صفر ، بهذا نقرأ الرقم. بعد ذلك نضع فى المراكم 9 و نطرح منه كود الزرار فلو كان من صفر إلى 9 لن يكون هناك C أى رقم و إلا سيكون C=1 أى أمر من الستة و هكذا حللنا كل البيانات المطلوبة.
قراءة الأزرار KeyPad
بقى كود قراءة الأزرار وهو ببساطة كما ذكرنا نضع FF كخرج ثم صفر على أى طرف و نقرا أين ظهر و منه نحدد الكود ثم نعود
كود:

ReadKPD:
	MOV	KeyValue,#255	; No key code
	Mov	R4,#5		; Read 5 times
	KPDLOOP:
		MOV	KeyPad, #254			; 1111 1110	COL4
			JB	ROW1,C4R2
			MOV	KeyValue,#10		; F1 or A pressed ret 0xA = 10
			RET
		C4R2:	JB	ROW2,C4R3
			MOV	KeyValue,#11		; F2 or B pressed ret 0xB = 11
			RET
			C4R3:	JB	ROW3,C4R4
			MOV	KeyValue,#12		; F3 or C pressed ret 0xC = 12
			RET
		C4R4:	JB	ROW4,C3R1
			MOV	KeyValue,#13		; Enter Pressed  ret 0xD = 13
			RET
		C3R1:	MOV	KeyPad,#11111101b	; Col3
			JB	ROW1,C3R2
			MOV	KeyValue,#3		; 3  pressed ret 3
			RET
		C3R2:	JB	ROW2,C3R3
			MOV	KeyValue,#6		; 6  pressed ret 6
			Ret	
		C3R3:	JB	ROW3,C3R4
			MOV	KeyValue,#9		; 9  pressed
			Ret	
			C3R4:	JB	ROW4,C2R1
			MOV	KeyValue,#14		; "cancel" btn  pressed
			Ret	
		C2R1: MOV	KeyPad,#11111011b	; Col2
			JB	ROW1,C2R2
			MOV	KeyValue,#2		; 2  pressed
			Ret	
		C2R2:	JB	ROW2,C2R3
			MOV	KeyValue,#5		; 5  pressed
			Ret	
		C2R3:	JB	ROW3,C2R4
			MOV	KeyValue,#8		; 8  pressed
			Ret	
			C2R4:	JB	ROW4,C1R1
			MOV	KeyValue,#0		; 0  pressed
			Ret	
		C1R1: MOV	KeyPad,#11110111b	; Col1
			JB	ROW1,C1R2
			MOV	KeyValue,#1		; 1  pressed
			Ret	
		C1R2:	JB	ROW2,C1R3
			MOV	KeyValue,#4		; 4  pressed
			Ret	
		C1R3:	JB	ROW3,C1R4
			MOV	KeyValue,#7		; 7  pressed
			Ret	
		C1R4: JB	ROW4,CR00
			MOV	KeyValue,#15		; Mode pressed
			RET
		CR00:	DJNZ	R4,KPDLOOP
			RET
طبعا ستسأل من أين أتينا بهذه الأكواد أى عندما نضع كذا و نقرأ كذا يكون الرد هو 5 وليس 7
ببساطة من الرسم حيث تجد الصفوف و الأعمدة ثم تفترض أنك ستضع على صف 1 فأين سيخرج بالضغط على عامود 1 و هكذا.
لو اتبعت الخطوات بدقة مع الرسم الصحيح على البوردة و مطابقتها من لوحة الأزرار لا يجب أن تجد مشاكل لكن ماذا نفعل لو حدثت؟ لن نلقى بالمشروع فى القمامة! أولا جرب قلب المدخل فلوحة الأزرار لها 8 طرف و ستضعها على مشط من 8 طرف و ربما عكسته أثناء الإدخال.
لم يأتى بالكثير إذا ماذا نفعل؟ فرضا اللوحة مختلفة كليا عما توقعناه و رسمناه..
الحل بسيط جدا ،ـ ورقة و قلم و اضغط على زر 1 و اقرأ ما ظهر و ليكن 5 مثلا، اكتب فى الورقة 1 > 5 مثلا ثم كرر مع زر2 ثم 3 وهكذا
الآن فى المترجم ستجد جملة
MOV KeyValue,#1 ; 1 pressed
لكنها الآن أعطت 5 فنغير كل واحد بخمسة فتصبح
MOV KeyValue,#5 ; 5 pressed *

و الآن أضفنا نجمة لنتذكر أن هذا السطر قد تم تعديله أو تصحيحه وهكذا حتى تصحح الستة عشر زرار.

المرة القادمة إن شاء الله نتحدث عن باقى البرنامج


اعلانات

ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 26-07-2018, 08:55 AM المشاركة 90   
افتراضي




برنامج الميكرو ويف
أول البرنامج هو العنوان StartIt حيث نبدأ أولا بالتهيئة وكل تعليماته سبق شرحها فى برنامج الغسالة و الجديد فقط هو تصفير الدقائق و الثوانى ثم نطلب برنامج عرض الوقت.
كود:

;=====================================
; CODE SEGMENT
;=====================================

Startit:	
	MOV	IE,#10000011b			; Enable T0 & INT0 external
	MOV	TH0,#205			; Auto reload
	MOV	TL0,#205	
	MOV	TMOD,#00000110b			; T0 8bit counter auto reload
	MOV	TCON,#1				; Clr All interrupts, Set INT0 Edge trigger
	MOV	SP,#70				; Move stack away
	MOV	Relays,#0			; Reset All PORTS! select Small cold cycle
	MOV	Relays,#255
	MOV	Controls,#255
	MOV	MinLeft,#0
	Mov	SecLeft,#0
	ACALL	ShowTime
بعد عرض الوقت تأتى الدورة التكرارية وهى قسمين الأول لمعالجة الأعداد و الثانى لمعالجة الأوامر.
تبدأ بعنوان العودة للبدء باسم LoopAll ثم نطلب كود قراءة الأزرار و اختبارها وهو كما سبق سيعيد قيمة هذا الزرار فى المراكم B وهذا لسبب أن المراكم A و المراكم B فقط يمكن أن تشير إلى بت واحدة منهم و السبب لو تذكر فى مسجل الوظائف الخاصة يمكنك الإشارة لأى بت من العمود الأول فقط و به المنافذ كاملة و كل من A و B . لكن و بسبب RISC أيضا لا تستطيع الإشارة لأى بت فى الذاكرة – فقط بايت كاملة.
كود:

LoopAll:	
	ACALL	ReadAndChk
	JC	LoopAll				; Number first
	MOV	SecLeft,B			; Add SecLeft
	ACALL	ShowTime			; Display it
TenSec:
الآن أيضا نعرف هل هو رقم من صفر إلى 9 أم هو أمر من 10 إلى 15 من الراية C فلو =1 يكون أمر ، إذن نستخدم Jc وهو يعنى Jump If Carry set لنعود للبدء مرة أخرى و ذلك لسبب أنك لا تدخل أمرا الأول فلا يجوز تشغيل الجهاز بدون وضع وقت التشغيل أولا.
لو كان هذا رقم ستعتمده كآحاد للثوانى بحفظه فى الثوانى ثم تطلب عرض الأرقام ليراه المستخدم ثم تعود لتبحث ماذا بعد.
سيكون التالى إما أمر للتنفيذ أو رقم للإضافة
كود:

TenSec:
	ACALL	ReadAndChk
	JC	ChkCmnd				; Command	
	MOV	A,SecLeft
	SWAP	A
	ADD	A,B				; Add SecLeft
	MOV	SecLeft,A				; save
	ACALL	ShowTime			; Display it
ReadMin:
أول أمر لقراءة واختبار الأزرار ثم اختبار لو أمر نذهب لكود تحليل الأوامر و إلا نعتبر هذا الرقم تعديل للثوانى أى ما سبق سيصبح عشرات ثوانى و الجديد آحاد. الآن نقرأ الثوانى فتكون مثلا 03 للمراكم A ثم ننفذ الأمر
SWAP A
و ألذى يبدل النصفين معا فيصبح 30 و الآن نضيف القيمة الجديدة و بفرض أنها 6 ستكون 36 ثم نحفظ الناتج فى ثوانى مرة أخرى.
يلى ذلك قراءة الدقائق و جدير بالذكر أن هذه العناوين لا حاجة لها فى البرنامج ولكنها تعرفك ما هذا الجزء. البعض يستخدم تعليق فى صورة جمالية مثل
;************** Read Minutes *****************
وهذا أفضل لأنه يتيح لك إضافة ما تشاء من تعليقات للتوضيح. يلى ذلك قراءة الدقائق حيث نبدأ كما سبق بقراءة و تحليل الأزرار فإن كان أمرا نذهب لتحليله و إلا كرقم نضيفه.
كود:

ReadMin:
	ACALL	ReadAndChk
	JC	ChkCmnd			; Command	
	MOV	A,SecLeft	
	SWAP	A			; Keep ten SecLeft to make it MinLeft
	ANL	A,#0Fh			; now it is units
	MOV	MinLeft,A		; save MinLeft 
	Mov	A,SecLeft		; get SecLeft and save tens
	ANL	A,#0Fh	 		; Keep units
	Swap	A
	ADD	A,B	
	Mov	SecLeft,A		; save
	ACALL	ShowTime		; Display it			
TenMinLeft:
لكى نضيف الرقم كثوانى نحتاج تعديل ما سبق، فنقرأ الثوانى أولا للمراكم و كانت 36 ثم بالأمر SWAP سيصبح 63 و بالأمر AND “مع" السابق شرحه نبقى منه 03 و نحفظها فى الدقائق. بعدها نعيد قراءة الثوانى 36 و نبقى 06 ثم نبدله ليصبح 60 ثم نجمع عليه الرقم الجديد و ليكن 1 فتصبح 61 نحفظها فى الثوانى.
كود:

TenMinLeft:
	ACALL	ReadAndChk
	JC	ChkCmnd			; A Command
	Mov	A, SecLeft			
	Swap 	A			; Make it tens	
	ANL	A,#0F0h			; get tens
	ADD	A,B			; add new units
	Xch	A,SecLeft	
	ANL	A,#0F0h			; delete units
	ADD	A, MinLeft		; Make 2 digits	swapped
	Swap	A
	MOV	MinLeft,A		; save it 
	ACALL	ShowTime
Wait4Command:
	ACALL	ReadAndChk
	JNC	Wait4Command		; not A Command
ChkCmnd:
الأمر الأول و الثانى كما سبق و الآن لدينا الرقم الرابع للقيمة 361 ، نقرأ الثوانى 61 و نبدلها 16 و نبقى 10 و نجمع عليه الجديد وليكن خمسة فيصبح 15 الآن نريد حفظه فى الثوانى دون تغيير قيمتها لنأخذ منها للدقائق. حسنا لدينا الأمر XCH وهو بمعنى Exchange أى تبديل و فى أمر واحد نضع ما فى A فى الثوانى و نأخذ ما فى الثوانى فى A و يذلك تصبح الثوانى 15 و A به 61 فنحذف الآحاد لتصبح 60 فنضيف عليها الدقائق و كانت 03 فتصبح 63 ثم نبدله لتصبح 36 و نحفظها فى الدقائق. ممكن استخدام هذا الأمر فى جزء الدقائق السابق إلا أنه بهدف التعليم نتعرض لأكثر من طريقة.
لو ادخلنا 4 أرقام إذن لا بد من أمر لذا ننتظر وصول أمر وهو من العنوان Wait4Command ثم نقرأ ونختبر الأزرار فإن كان رقم نكرر حتى يأتى أمر ننتقل لتحليل الأوامر فى الجزء ChkCmnd وهذا موضوعنا القادم إن شاء الله




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

ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 27-07-2018, 10:22 AM المشاركة 91   
افتراضي




تحليل الأوامر :
لدينا كما ذكرنا سته أوامر بأرقام من 10 إلى 15 و 10 له أكثر من وظيفة ، لذا و برغم التسلسل المنطقى أن نحلل بالترتيب إلا أننى أفضل البدء بالرقم 13 وهو Enter أى بدء التشغيل. جدير بالذكر أنه لا فرق أين تضع ماذا فالأمر هنا خمسة تعليمات CJNE لفحص خمسة أوامر منها و إن لم يكن كذلك فلا جدوى من اختبار الأمر السادس.
فى العنوان الأول ChkCmnd سننقل القيمة من B إلى A لنجرى عليه اختباراتنا ثم CJNE بقيمة 10 أو ننتقل للعنوان ADD10 برقم 11 حيث نكرر الاختبار بالرقم 11 و ننتقل لو مختلف للعنوان ADD10Min و هناك نختبر بالرقم 12 فننتقل للرقم 13 بعنوان Enter و هنا للتوضيح
كود:
 	Enter:					; 13 = Enter or Run
		CJNE	A,#13,Cancel
		MOV	A,SecLeft
		Add	a,MinLeft		; Sum = F2 max
		JZ	Nothing			; Time not set
		SETB	JobPending
		SETB	TR0			; Start Timer/Counter
		CLR	OFF_Non			; power on
		CLR	HIv_Off			; Turn On Hi voltage
		Nothing:
		SJMP	Back	
	Cancel:				    
حيث نقارن بالرقم 13 فإن اختلف ننتقل لأمر Cancel أو نكمل حيث نقرأ الثوانى فى A ثم نجمع عليها الدقائق و ننتقل لو الناتج = صفر لعنوان Nothing و ألذى ينقلنا لعنوان Back وهو من اسمه نعرق الأرقام ثم نعود لأول البرنامج أى لأن الزمن = صفرا فلا تفعيل لأى أمر. طبعا ستسأل لماذا لم نكتب
JZ Back
من الممكن ذلك لكن هكذا لم تضيف أى أمر و يمكنك نقل الكتلة البرمجية دون خشية تعدى حدود 128 خطوة.
أما لو كان هناك زمن لا يساوى صفر فسنقيم الراية JobPending وهى الدالة على أن الجهاز الآن فى حال التشغيل ثم نفعل البت TR0 لتشغيل التايمر و نجعل كل من OFF_Non Hiv_Off = صفر لتشغيل الماجنيترون و يظل الوضع هكذا حتى ينتهى الوقت و فى كود المقاطعة ستنعكس حالة هذه البت الأربع. هكذا سنعلم ما إن كان الماجنيترون يعمل أم لا
الآن نأخذ باقى الأوامر بالترتيب. أولا الرقم 10 وهو لو كان الماجنيترون يعمل يؤدى وظيفة تغيير الزمن 10 ثوانى كل مرة أما لو الماجنيترون لا يعمل فسيحدد نسبة الطاقة
كود:

ChkCmnd:	; If 10 then either ADD 10 secinds or set Low Power
		MOV	A,B
		CJNE	A,#10,AddMinLeft        ; 10 = Add 10 sec
		JB	JobPending,Add10	; It is Running, so increase time
		Mov	Displays,#0FFh		; Display Blank MinLeft
		CLR	MinLatch
		nop
		Setb	MinLatch
		MOV	Displays,#0
		CLR	SecLatch
		nop
		SETB	SecLatch		; Show -- 00
	
		Acall	ReadAndChk
		JC	ChkCmnd			; if Command, cancel Low Power	
	SetLow:	Mov	PowerSel,B
		Setb	LowHeat
		MOV	A,B
		Swap	A
		Mov	Displays,A
		CLR	SecLatch
		nop
		SETB	SecLatch			; Show -- x0
		MOV	CurrPwr,#0
		Acall	ReadAndChk
		JC	ChkCmnd
		sjmp	SetLow
	Add10:
    
هنا نختبر لو الأمر لا يساوى 10 ننتقل للأمر التالى و إلا نفحص JobPending و لو =1 إذن الماجنيترون يعمل و ننتقل لزيادة الزمن و إلا نطلب من المستخدم تحديد النسبة. سنضع على Displays القيمة FF وهى = 255 و هذه محلل الشفرات لا يعطى أى شيئ و يجعل الشاشات مطفأة ، وهذه علامة للمستخدم. لو تستخدم رقم غير 4011 يمكنك اختيار أى كود يلائمك. بعد ذلك تضع نبضة على خط MinLatch فتظهر شاشتين مطفأتين ثم نضع صفر على Displays و نضع نبضة على SecLatch فيظهر صفرين. و عندها نقرأ الأزرار و نختبر C فإن كان رقم فهو النسبة ولو كان أمر نلغى خيار القدرة المخفضة ونعود من جديد فى انتظار أمر.
لو كان رقم سننسخ ما فى B لمتغير PowerSel كما سبق الشرح أننا سنشغل الجهد العالى بضع ثوانى و نوقفه باقى الثوانى العشرة. بعد ذلك نقيم الراية LowHeat لنعلم ذلك أثناء كود المقاطعة و حساب الزمن ثم ننسخ هذا الرقم من B إلى A و لو كان مثلا 4 سنقلبه ليصبح 40 و نضعه على Displays و نضع نبضة على SecLatch فيظهر الرقم 40 ثم نصفر CurrPwr الذى يحدد أين نحن من الثوانى العشرة ثم نقرأ مرة أخرى الأزرار . الآن لو عدد سنعيد الكرة أى أن المستخدم بعد أن اختار 40% عاد و اختار 60% مثلا أما لو كان أمر سننتقل لتحليله من جديد.
كود:

	Add10:	
		MOV	A,SecLeft
		ADD	A,#10h			; Add 10 sec
		DA	A	
		MOV	SecLeft,A		; Save it Back
		SJMP	Back
	AddMinLeft

هنا سيكون الوضع الماجنيترون يعمل و المطلوب زيادة الثوانى ، نقرأ الثوانى ثم نضيف هيكسا 10 و الأمر DAA ثم نحفظه
	AddMinLeft:				; 11 = Add MinLeft
		CJNE	A,#11,Add10Min
		JNB	JobPending,Back		; if not running do nothing
		MOV	A,MinLeft
		ANL	A,#0F0h			; Keep tens
		MOV	B,A			; save it
		MOV	A,MinLeft
		ANL	A,#00Fh			; Keep ones
		ADD	A,#1
		DA	A
		ANL	A,#00Fh			; Keep ones
		ADD	A,B
		MOV	MinLeft,A	
		SJMP	Back	
	Add10Min:					; 12 = Add 10 MinLeft
    
هنا الأمر مكرر إلا أننا نعدل الدقائق بدلا من عشرات الثوانى فنقارن لو لا يساوى 11 ننتقل للتالى أو نفحص JobPending فلو لا يعمل الماجنيترون نعود لنكرر الدورة أو لو كان يعمل نكمل إذن بقراءة الدقائق . لا توجد وسيلة لزيادة الرقم دون التأثير على العشرات فإما نقارن بالعدد 9 إلا أننا لا نعلم العشرات فقد تكون من 0x إلى 9x لذا سنستخدم AND لحذف الآحاد و الإبقاء على العشرات فقط و نحفظها فى B ثم نعيد قراءة الدقائق و نحذف العشرات هذه المرة و نجمع لها 1 ثم DA و بعد ذلك نعيد حذف العشرات لأن 9 بإضافة 1 ستصبح A و الأمر DAA سيحولها إلى 10 لذا وجب حذف العشرات. ثم نجمع ما حفظناه فى B و نعيده للدقائق
كود:

	 Add10Min:
		CJNE	A,#12,Enter	
		JNB	JobPending,Back		; if not running do nothing
		MOV	A,MinLeft
		ADD	A,#10h
		DA	A
		MOV	MinLeft,A
		SJMP	Back	
	Enter:					; 13 = Enter or Run
		CJNE	A,#13,Cancel
		MOV	A,SecLeft
		Add	a,MinLeft		; Sum = F2 max
		JZ	Nothing			; Time not set
		JB	DoorOpen,$		; Wait Door Close
		SETB	JobPending
		SETB	TR0			; Start Timer/Counter
		CLR	OFF_Non			; power on
		CLR	HIv_Off			; Turn On Hi voltage
		Nothing:
		SJMP	Back	
	Cancel:					; 14 = Cancel
		CJNE	A,#14,StopAll		; enter, run oven
		JB	DoorOpen,$		; Wait Door Close
		JNB	JobPending,Back		; If not running , Do nothing
		CPL	TR0			; stop if runnuig or run if stopped Timer/Counter
		CPL	OFF_Non			; Reverse On / Off	
		Ajmp	Back	
	StopAll:  
		ajmp	StartIt			 
	Back: 
		ACALL	ShowTime
		AJMP	LoopAll 
    
الأمر Enter سبق شرحه و بقى الأمر Cancel وهو إيقاف مؤقت. فنقارن بالرقم 14 فإن لم يتساوى فهو 15 أى إلغاء تام وهو بدء من جديد. أما لو تساوى فننتظر غلق الباب لو مفتوح فربما أثناء الإيقاف تم فتح الباب لأى سبب ثم نعكس وضع التشغيل بالأمر CPL أى Complement فإن كان متوقفا سيعمل و إن كان يعمل سيتوقف.

إضافات كودية
لو لا تتقبل حسابات BCD فيمكنك ببساطة استخدام الحساب الثنائى العادى و كل ما هنالك ستحتاج لتحليل البايت سواء ثوانى أو دقائق لمكونيها الآحاد و العشرات ثم تضعها على Displays للعرض
ذلك بأمر بسيط جدا وهو DIV ِAB وهو يقسم محتوى A على محتوى B و يكون المراكم A به الرقم الصحيح و الباقى فى B لذا ببساطة ضع فى A الثوانى أو الدقائق و ضع فى B الرقم 10 عشرى أى A هكسا و بتنفيذ الأمر تقسم ما فى A على 10 فيبقى فى A عشرات الثوانى و فى B أحاد الثوانى
و إن شئت تجميعهما مرة أخرى أيضا استخدم الأمر MUL AB فيمكنك وضع عشرات الثوانى مثلا فى A و الرقم 10 فى B و بتنفيذ الأمر سيتم ضرب عشرات الثوانى فى 10 ثم تجمع عليها الآحاد.
هنا نقطة يجب ذكرها أن ناتج ضرب 8 بت فى 8 بت = 16 بت تكون الثمانية الأعلى منها فى B و الأقل فى A لكن أقصى رقم فى هذا التطبيق هو ضرب 9 فى 10 = 90 أقل من بايت واحدة 255 لذا سيكون بكامله فى A

المرة القادمة إن شاء الله نستخدم AVR مع بيزك ثم ميكرو تشيب مع C




ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 28-07-2018, 08:36 AM المشاركة 92   
افتراضي




استخدام AVR مع البيزك
من الدوائر السابقة وجدنا أنه مجرد فقط نبدل الأطراف و نغير الأوامر لذا تعديل الدائرة ليس مشكلة و كما سبق ستصبح

نأتى للكود و طبعا كل مترجم له مكتبة أساسية تعتمد لوحة الأزرار و تدعم الشاشات بأنواعها و يمكننها استخدامها ولكن مشكلة الأزرار حقيقة لو لم تعمل فلا حيلة لديك لكى تقوم بالتصحيح ألذى قمنا به فى الأسيمبلى . طبعا يمكن عمل ما يسمى Lookup Table أو جدول البحث حيث تضع فيه كم من المدخلات و مقابلها من القيم المطلوبة فيكون لو كان واحد فتبحث فى الجدول عن القيمة واحد فتجد الصواب هو 3 و هذا يكون فى صورة مصفوفة من البيانات وهى مستهلكة للكود و الذاكرة. أيضا كما سبق تبنينا الدائرة التقليدية فى تفعيل الريلاى أى 1 = تشغيل و صفر إيقاف.
كود:

$regfile = "m16adef.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32

Displays Alias Porta : Controls Alias Portb : Keypad Alias Portc : Relays Alias Portd
Keyread Alias Pinc

Dooropen Alias Relays.2 : Buzzer Alias Relays.4 : Off_non Alias Relays.5 : Hiv_on Alias Relays.6
Seclatch Alias Controls.1 : Minlatch Alias Controls.2
Const Adigit = 0 : Const Acmnd = 1

' VARIABLES
Dim Lowheat As Bit , Jobpending As Bit , Nokey As Bit , Cmd_ndgt As Bit
Dim Secleft As Byte , Minleft As Byte , Powersel As Byte , Currpwr As Byte
Dim Keyvalue As Byte , Cntr As Byte , Tmp As Byte

Declare Sub Showtime() : Declare Sub Readandchk() : Declare Sub Readkpd()
البنود الخمسة الأولى لتحديد مجال العمل للمترجم وسبق شرحها فى البرنامج السابق الخاص بالغسالة ، يليه التعريفات و نلاحظ هنا أننا لم نعرف أطراف الأزرار فقط حددنا المنفذ PORT و أيضا استخدمنا تعريفين للأزرار واحد للقراءة وهو للمنفذ PORTC و الآخر للأطراف بهدف القراءة منها و يخص PINC و أضفنا ثابت "رقم" adigit ويساوى صفر و آخر "أمر"ACMD = 1 وهذا للتسهيل فبعد قراءة الأزرار نبحث إن كان رقم أم أمر وهو صفر أم 1 و هذا أسهل للتذكرة .
كود:

Startit:
    Config Displays = Output : Config Keypad = &H0F : Config Controls = 254
   Config Relays = &HF0
    Config Timer0 = Counter , Edge = Falling
    Timer0 = 205                                            ' Was Th0 = 205
    Enable Interrupts : Enable Int0
    Relays = &H0F : Controls = 255                          ' Pulup for Door Open Sw
    On Int0 Emergency , Nosave
    On Timer0 Counttime
    Minleft = 0 : Secleft = 0 : Showtime
يلى ذلك أول البرنامج وهو التهيئة حيث أوامر تهيئة المنافذ كدخول أو خروج أو كما فى لوحة الأزرار نصفها دخول و ألنصف خروج. يلى ذلك كما فى الأسيمبلى جزء الدورة ألمستديمة ثم دورة قراءة الأزرار مع الفحص و التكرار حتى تقرأ رقم كما سبق تماما و فى كود القراءة نفس الخطوات (وليس الأوامر) لمتابعة القراءة و فحص كونها رقم أو أمر الخ. و هنا يعتمد الرقم كثوانى مثلا 6 ثم تعرض ثم تعيد القراءة والفحص، لو أمر تذهب لعنوان فحص الأوامر و إلا نكرر نفس الخطوات السابقة لعمل عشرات الثوانى. نضرب الثوانى فى 10 تصبح 60 و نضيف لها الجديد مثلا 5 فتصبح 65 ثم نعرض و نعيد القراءة مع الفحص.
هنا وجب التنويه عن نقطة هامة وهى أن الضرب فى 10 و الجمع يجب أن يكونا فى خطوة واحدة هكذا
SecLeft = (SecLeft * 10) + KeyValue
لكنها قصور المترجم النسخة المجانية
كود:

    Do
         Do
           Readandchk
         Loop Until Cmd_ndgt = Adigit
         Secleft = Keyvalue : Showtime : Readandchk
         If Cmd_ndgt = Acmnd Then Goto Chkcmnd
         Secleft = Secleft * 10 		'make 10 seconds
          Secleft = Secleft + Keyvalue          
         Showtime
         Readandchk
         If Cmd_ndgt = Acmnd Then Goto Chkcmnd
         Minleft = Secleft \ 10 
          Tmp = Secleft Mod 10                ' a digit, make minutes
         Secleft = Keyvalue + Tmp : Showtime : Readandchk
         If Cmd_ndgt = Acmnd Then Goto Chkcmnd
         Tmp = Secleft \ 10 : Minleft = 10 * Minleft 
          Minleft = Minleft + Tmp       ' adigit make ten minutes
         Readandchk
         If Cmd_ndgt = Acmnd Then Goto Chkcmnd
         Tmp = Secleft / 10 
	    Minleft = Minleft * 10 ' a last digit, make 10 min
         Minleft = Minleft + Tmp : Tmp = Secleft Mod 10 
          Secleft = Secleft + Keyvalue
         Do                               ' wait For command
           Readandchk
         Loop Until Cmd_ndgt = Acmnd
الآن لو أمر ننتقل أو نكون الدقائق و ذلك بأن نقسم الثوانى على 10 فنحصل على عشرات الثوانى 65 ÷ 10 = 6 و نضعه كدقائق ثم نستخدم الدالة Mod اختصار Modulus وهى المتبقى من القسمة فالأمر Tmp = Secleft Mod 10
يضع فى المتغير Tmp باقى القسمة وهو 5 ثم نضربه فى 10 ليصبح 50 و نضيف الجديد وليكن 4 لتصبح 54 و نعرض ثم نعيد القراءة مع الفحص و إن كان أمر ننتقل أو نكون عشرات الدقائق بضرب الدقائق فى 10 لتكون 60 ثم نقسم الثوانى على 10 لنحصل على 5 نجمعها مع الدقائق لتكون 65 ثم نحصل على المتبقى من الثوانى 4 نضربه فى 10 أى 40 و نضيف له الجديد و ليكن صفرا فتصبح 40 و الزمن الكلى الآن 65 دقيقة و 40 ثانية و الآن بعد أربعة أرقام سنقرأ و ننتظر أمر و ليس رقم. العدد من 10 إلى 15 لنحلله. و ننفذه وهذا موضوعنا القادم إن شاء الله




ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 29-07-2018, 09:16 AM المشاركة 93   
افتراضي




لو الأمر القادم هو 10 فإما نزود 10 ثوانى أو نحدد به نسبة تخفيض القدرة. أى أن الزر الأول له وظيفتين متباينتين ومن ثم نحتاج تحديد ما يحدد هذه الوظيفة أو تلك.
لو الجهاز يعمل أى الماجنيترون يطلق الطاقة ستوقف خاصية تعديل الطاقة لذا سنغير الثوانى أما لو لا يطلق الطاقة سنسأل عن النسبة و نرفع راية طاقة مخفضة. أنسب تعليمه هنا هى Select Case أو فى اللغات الأخرى Switch حيث نفاضل بين قيم متعددة لناتج قراءة الأزرار. إن كانت = 10 سنسأل هل Jobpending = 1 إذن الماجنيترون يعمل فنزيد 10 للثوانى و إن تعدت 59 نطرح منها 60 لنبقى على الآحاد كما هى.
أما لو = صفرا أى الماجنيترون لا يعمل و لكننا هنا فى هذا الجزء من البرنامج أتممنا تحديد الزمن، سنعرض فى الدقائق ما ينبه المستخدم لذا بوضع أى رقم أعلى من 9 ستعرض الشاشة لا شيء. يمكنك أيضا اختيار طرف آخر لإنارة علامة عشرية أو ليد آخر أو لو تستخدم رقم غير المحلل 4511 سيعطى أشكال طبقا للداتاشيت.
نضع 255 ثم صفر على MinLatch ثم نعيده للواحد. هنا كان ممكنا استخدام الأمر
PULSEOUT PORT , PIN , PERIOD
PULSEOUT Controls , Seclatch , 1
حيث الفترة PERIOD تحسب بالدورة و هى ربع الكريستال. و لكن يجب التأكد من البداية الصحيحة لأنها تنفذ بتبديل البت مرتين فلو بدأت بصفر ستنتج نبضة موجبة و إن بدأت بواحد تنتج نبضة سالبة
بعد ذلك نضع صفر و نكرر للثوانى لتظهر صفرين علامة انتظار نسبة التخفيض ثم نقرأ مع الفحص. فإن كان أمر ننتقل لفحصه أو لو رقم نضعه فى خانة Powersel أى القيمة المختارة و نقيم راية الحرارة المنخفضة ثم نضرب القيمة فى 10 و نستخدم الدالة Makebcd والتى تحول الناتج لما يناسب الشاشات و نعرضه و نضع صفرا فى Currpwr قيمة البدء ثم نقرا مع الفحص . من الممكن انتظار أمر كما سبق لكن نفكر قليلا سنجد أن لو كان رقم يمكن أن نعدل الخيار السابق، ولم لا فنعود للتعديل فى عنوان Setlow أو لو أمر ننتقل لتحليله
كود:

Chkcmnd:
    Select Case Keyvalue
        Case 10                 ' If 10 then either ADD 10 seconds or set Low Power
            If Jobpending = 1 Then     ' running , add ten
               Secleft = Secleft + 10
               If Secleft > 59 Then Secleft = Secleft - 60 
            Else                       ' Set low power
               Displays = 255           ' Display Blank MinLeft
               Reset Minlatch : Nop : Set Minlatch : Waitus 1
               Displays = 0 : Reset Seclatch : Nop 
	 	   Set Seclatch             ' Show -- 00
               Readandchk
               If Cmd_ndgt = Acmnd Then Goto Chkcmnd   ' if a 2nd Command, cancel Low Power
               Setlow:
               Powersel = Keyvalue : Set Lowheat            ' Setlow
               Tmp = Keyvalue * 10 : Displays = Makebcd(tmp)
               Reset Seclatch : Nop : Set Seclatch          ' Show -- x0
               Currpwr = 0 : Readandchk
               If Cmd_ndgt = Adigit Then
                   Goto Setlow          ' a digit, replace the old one
               Else
                   Goto Chkcmnd
               End If
            End If
        Case 11                         ' 11 = Add MinLeft
            If Jobpending = 1 Then        ' if not running do nothing
               Tmp = Minleft \ 10 : Incr Minleft : Cntr = Minleft \ 10
               If Cntr > Tmp Then Minleft = Minleft - 10
            End If
        Case 12                          ' 12 = Add 10 MinLeft
            If Jobpending = 1 Then        ' if not running do nothing
               Minleft = Minleft + 10
               If Minleft > 100 Then Minleft = Minleft - 100
            End If
        Case 13                          ' 13 = Enter or Run
            If Minleft <> 0 Or Secleft <> 0 Then
                  Bitwait Dooropen , Reset      ' Wait Door Close
			Set Jobpending : Start Timer0 : Set Off_non : Set Hiv_o
            End If
        Case 14                          ' 14 = Cancel
            Bitwait Dooropen , Reset      ' Wait Door Close
            If Jobpending = 1 Then
                Toggle Timer0 : Toggle Off_non
            End If
        Case Else                        ' 15 stop all
           Goto Startit
    End Select
    Showtime
    Loop
يلى ذلك باقى الأكواد وهى أسهل لكونها تنفذ أمرا واحدا فقط فنجد الأمر 11 وهو نضيف دقائق وهذا الأمر و التالى حقيقة ضرورى فقد تجد أنك تحتاج لزيادة الوقت لإكمال الطهى ولو انتظرت ستحتاج لإعادة ضبط نسبة الحرارة مرة ثانية وهى نسبة لو زادت قد لا تكون جيدة فبعض الأشياء تحتاج حرارة منخفضة و بعض الأشياء تحتاج وقت لتوزيع الحرارة على الجسم كله خاصة لو تفك شيئ مجمدا و رفعت الحرارة ستسوى جزء و يبقى آخر مجمدا.
لتنفيذ هذا نسأل لو Jobpending =1 فهذا يعنى أنه يعمل فنقسم الدقائق المتبقية على 10 ثم نزيد الدقائق بواحد ثم نقسم الناتج على 10 . المشكلة هنا أننا نريد بعد 39 العدد 30 و ليس 40 لعدم توافر زرار آخر للنقصان و الحل بسيط فالقسمة الأولى ستعطى 3 و الثانية 4 لذا سنطرح 10 أما لو كلاهما 3 فلا نطرح.
الكود 12 نضيف 10 دقائق فإن كان الرقم أكبر من 100 سنطرح 100 لأن الأرقام الأكبر من 99 لن تعرض جيدا
ثم الكود 13 للتشغيل فلو يوجد زمن سبق تحديده نتأكد من غلق الباب ثم نشغل الجهاز و المؤقت و ننصب راية Jobpending أى مهمة قيد التنفيذ.
الكود 14 نتأكد من غلق الباب ثم نعكس حال التشغيل و الكود الأخير لإلغاء كل شيئ و التوقف التام و العودة للبدء
يلى ذلك كود المقاطعتين الأولى للطوارئ أى الباب مفتوح و الثانية لحساب الوقت التايمر.
وهو موضوعنا القادم بإذن الله




ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 30-07-2018, 08:46 AM المشاركة 94   
افتراضي




كود مقاطعة الطوارئ بسيط و يبدأ بعنوان Emergency حيث نوقف الطاقة و نوقف المؤقت و ننتظر حتى غلق الباب و عندها نطلق التايمر و نطلق الطاقة ثم نعود و الميكرو آليا يعيد إتاحة المقاطعة.
كود:

Emergency:                       ' Adress of INT0 (IE0)Emergency
    Reset Off_non                ' stop Outs and motors etc
    Stop Timer0                 ' Stop counter
    Bitwait Dooropen , Reset
    Start Timer0                ' Start counter
    Set Off_non                  ' Resetart All
    Return

Counttime:
    Decr Secleft
    If Secleft = 0 Then
       If Minleft <> 0 Then
            Decr Minleft
            Secleft = 59
       Else                      ' Sec = 0 and Min = 0
            Reset Jobpending      ' All Done
            Stop Timer0          ' Stop counter
            Reset Lowheat         ' Clear if selected
            Reset Off_non         ' Power Off
            Reset Hiv_on          ' Turn Off HI Voltage
            Reset Buzzer
            Waitms 1000
            Set  Buzzer
       End If
    End If
    Showtime                        ' display New Time
    If Lowheat <> 0 Then
        Incr Currpwr
        If Currpwr > 10 Then Currpwr = 0       ' loop again
        If Currpwr > Powersel Then Reset Hiv_on Else Set Hiv_on
    End If
    Return
يلى ذلك كود مقاطعة حساب الوقت التايمر وهى باسم Counttime حيث ننقص الثوانى الباقية فإن كان الباقى لا = صفر فسنعرض الوقت و إن كانت راية الطاقة المخفضة مرفوعة نزيد عداد الطاقة الحالية بواحد فإن كان اكثر من 10 نعيده للصفر ثم نختبر هل أكثر من النسبة المحددة نوقف الطاقة و إلا نطلقها ثم نعود .
فى حال الثوانى = صفر نختبر الدقائق، لو لا تساوى صفر ننقصها بواحد و نعيد الثوانى 59 أما لو أيضا تساوى صفر نوقف المؤقت و نوقف الطاقة و نلغى كل الرايات و نطلق الزامور لمده ثانية ثم نعرض الوقت و نعود .
كود:

Sub Showtime():         ' ======== Display Time ========
    Set Minlatch
    Displays = Makebcd(minleft)
    Reset Minlatch
    nop
    Set Minlatch
    Set Seclatch
    Displays = Makebcd(secleft)
    Reset Seclatch
    nop
    Set Seclatch
 End Sub
المرة القادمة إن شاء الله نكمل




ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 31-07-2018, 09:07 AM المشاركة 95   
افتراضي




لقراءة الكيباد
كود:

Sub Readandchk()
    Do
       Readkpd
       Nokey = Keyvalue.7
    Loop Until Nokey = 1                          ' Wait  key released
    Do
       Readkpd
       Nokey = Keyvalue.7
    Loop Until Nokey = 0                          ' Wait  key Pressed
    If Keyvalue > 9 Then Cmd_ndgt = 1 Else Cmd_ndgt = 0' Command Or Number
End Sub
يلى ذلك كود عرض الوقت و أظنه سهلا فقد سبق التعرض لمثيله سابقا. نضع على المنفذ نتيجة الدالة Makebcd فهى تحول الرقم الثنائى لأرقام عشرية مناسبة للعرض فنضع الدقائق على المنفذ ثم نحرك طرف MinLatch من 1 إلى صفر ثم عودة للواحد ثم نضع الثوانى و نكرر مع SecLatch و هكذا يتم عرض الوقت.
يلى ذلك – و أذكر أنك تضع هذه الأكواد فى أى مكان يروق لك و ألدوال بأى ترتيب فلا يهم أن كانت هذه الدالة قبل تلك أم العكس – يلى ذلك كود القراءة مع الفحص حيث نطلب دالة قراءة الأزرار و التى تعيد القيمة فى متغير بحجم بايت باسم Keyvalue ثم نجعل البت باسم NOKEY تساوى البت رقم 7 من Keyvalue و التى = صفر لو ضغط على أى زرار و تساوى 1 لو لم يضغط . نكرر الدورة حتى تصير NoKey = صفر أى لا أزرار مضغوطة و عندها ندخل فى دورة حتى يتم الضغط على زرار. بعد الضغط نفحص النتيجة فإن كانت أكبر من 9 فهو أمر و Cmd_ndgt = 1 و إلا فهى = صفر
كود:

Sub Readkpd()
   Keyvalue = 255                         ' No key code
    For Cntr = 1 To 5                     ' Read 5 times
       Keypad = 254                       ' 1111 1110    COL4
       Tmp = Keyread And &B11110000
       Select Case Tmp
         Case &B01110000 : Keyvalue = 10   ' F1 or A pressed ret 0xA = 10
             Return                      ' Row1 = 0
         Case &B10110000 : Keyvalue = 11   ' F2 or B pressed ret 0xB = 11
             Return
         Case &B11010000 : Keyvalue = 12   ' F3 or C
             Return
         Case &B11100000 : Keyvalue = 13   ' Enter Pressed  ret 0xD = 13
             Return
       End Select
       Keypad = &B11111101                 ' Col3
       Tmp = Keyread And &HF0

       Select Case Tmp
         Case &B01110000 : Keyvalue = 3      ' 3
             Return
         Case &B10110000 : Keyvalue = 6      ' 6
             Return
         Case &B11010000 : Keyvalue = 9      ' 9
             Return
         Case &B11100000 : Keyvalue = 14     ' Cancel Btn
             Return
       End Select
       Keypad = &B11111011                   ' Col2
       Tmp = Keyread And &HF0

       Select Case Tmp
         Case &B01110000 : Keyvalue = 2       ' 2
             Return
         Case &B10110000 : Keyvalue = 5       ' 5
             Return
         Case &B11010000 : Keyvalue = 8       ' 8
             Return
         Case &B11100000 : Keyvalue = 0       ' 0
             Return
       End Select
       Keypad = &B11110111                    ' Col1
       Tmp = Keyread And &HF0

       Select Case Tmp
         Case &B01110000 : Keyvalue = 1        ' 1
             Return
         Case &B10110000 : Keyvalue = 4        ' 4
             Return
         Case &B11010000 : Keyvalue = 7        ' 7
             Return
         Case &B11100000 : Keyvalue = 15       ' Mode
             Return
       End Select
     Next
     End Sub
أخيرا كود قراءة الأزرار وهو بسيط جدا . نذكر أننا نسقنا المنفذ النصف الأدنى بت صفر،1،2،3 خروج و الأعلى 4،5،6،7 دخول. الآن نضع فى قيمة الزرار KeyValue القيمة 255 أى لا زرار ثم بعد ذلك ننشئ دورة من خمسة مرات نضع على المنفذ القيمة 11111110 حيث سبعة آحاد اربع منها العليا تذهب للدخول و ربما تذكر أن هذا يفعل مقاومات الجذب لأعلى فقط أما الأربعة الدنيا فتذهب لخرج و منها 3 آحاد وواحدة صفر وذلك من خلال Keypad وهو يذهب إلى PORTC.
الآن نقرأ المنفذ من المسجل PINC من خلال المتغير KeyRead وهو يقرأ حالة الأزرار الأربع العليا أما الدنيا فهى ما وضعناها نحن. نتخلص من الدنيا بالأمر "مع" AND فنضع فى Tmp نتيجة هذه الدالة بين النتيجة مع F0 فتبقى الأربع العليا فقط ثم بالتعليمه select case نفاضل و إن كانت رقم 4 فالناتج كذا أو لو البت 5 يكون كذا الخ ثم نعيد الكرة مع البت 1 و نقارن بالأربع ثم البت 2 وهكذا
بقى أن نكرر هذا البرنامج بلغة ميكرو سي المرة القادمة إن شاء الله



ماجد عباس محمد
:: نائب المشرف العام
::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
نشاط [ ماجد عباس محمد ]
قوة السمعة:
قديم 01-08-2018, 08:18 AM المشاركة 96   
افتراضي




الميكرو ويف باستخدام PIC16C877A و لغة ميكروسى :

هناك تعديلات طفيفة سنحتاج لتنفيذها كما سبق وهى بسبب تواجد طرف المقاطعة INT على منفذ B الطرف صفر و هذا يجبرنا على استخدام أزرار 4×3 مما يفقدنا أربعة من الوظائف الستة ولذا سنضطر لوضع الأزرار على منفذ آخر و ليكن D مع وضع مقاومات خارجية على أطراف الدخول و كما سبق الشرح إما تكون متصلة بالأرض و نضع واحد على الطرف و نختبر أين ظهر أو تتصل بالموجب و نكرر ذات الروتين . كانت أمامنا فرصة توفيرها فى النظم السابقة ولكننا هنا سنضطر لإستخدامها و ها هى فرصة لندرس الحل الآخر، لذا سنوصلها بالأرضى. أيضا التايمر يجب أن يوصل بالطرف PORTA.4 كما سبق الشرح , و الشاشات على المنفذ C و هكذا تصبح الدائرة كما يلى:

الآن ننشئ مشروع جديد فى ميكروسى و نضع فيه الكود و نترجمه و كما نعلم نبدأ بالتعريفات و كود المقاطعة . فى ألبيك المقاطعة واحدة ثم فيها تستفسر عن ما سبب هذه المقاطعة كما سبق و هكذا يمكن كتابتها و أيضا لا بأس من وظيفة عرض الأرقام.
كود:
// program Microwave16 Declarations section char Controls at PORTB ; char Displays at Portc ; char Keypad at Portd ; sbit Dooropen at rb0_bit ; sbit Seclatch at rb1_bit ; sbit Minlatch at rb2_bit ; sbit Hiv_on at rb3_bit ; sbit Off_non at rb4_bit ; sbit Buzzer at rd0_bit ; sbit MidtemP at rd1_bit ; sbit Waterfull at rd2_bit ; sbit Waterempty at rd3_bit ; sbit Run_nspin at rd5_bit ; sbit Motoron at rd6_bit ; sbit Heateron at rd7_bit ; sbit SmallLoad at rb5_bit ; sbit Half at rb6_bit ; sbit Full at rb7_bit ; bit Jobpending , BoKey , Lowheat , Cmd_ndgt ; // VARIABLES unsigned int Runtime ; char Rinse , Cntr , Secleft , Minleft , Powersel , Currpwr , Keyvalue , Tmp ; int Adigit = 0 ; int Acmnd = 1; void Showtime() { Minlatch = 1; Displays = Dec2Bcd(minleft) ; Minlatch = 0 ; Delay_us(1); Minlatch = 1 ; Seclatch = 1; Displays = Dec2Bcd(secleft) ; Seclatch = 0 ; Delay_us(1); Seclatch =1 ; } void interrupt() { if (INTCON.TMR0IF ) // Counttime: { if (--Secleft = 0 ) { if ( Minleft != 0 ) { --Minleft; Secleft = 59 ; } else { Jobpending = 0 ; INTCON.TMR0IF =0 ; // Clear timer flag INTCON.TMR0Ie = 0 ; // Disable timer Lowheat = 0 ; Off_non = 0 , Hiv_on = 0 ; // All off Buzzer = 1; Delay_ms(1000); Buzzer = 1; } } INTCON.TMR0IF = 0; Showtime() ; // Clear timer flag and display Time if (Lowheat =1) { ++Currpwr; if (Currpwr > 10) Currpwr = 0 ; // loop again if (Currpwr > Powersel) Hiv_on =0 ; else Hiv_on =1 ; } } else if (INTCON.INTF ) // External interrupt door open { Off_non = 0 ; // stop Outs and motors etc INTCON.TMR0Ie = 0 ; // Disable timer do { } while ( Dooropen = 1 ) ; // Wait door close INTCON.TMR0Ie = 1 ; // Enable timer Off_non = 1 ; // Resetart All } }
كود عرض الوقت كما سبق الشرح سنستخدم وظيفة Dec2Bcd وهى تعيد الرقم فى الصورة المناسبة و نضعها على المنفذ و نتأكد أن طرف التفعيل فى وضع = 1 لكى نتمكن من وضع نبضة سالبة بأن نجعله = صفر ثم 1 مرة أخرى. نكرر هذا الفعل مرة بوضع الدقائق على المنفذ و مرة بوضع الثوانى تماما كما فعلنا مع AVR
يلى ذلك كود المقاطعة حيث نسأل إن كان سبب المقاطعة من المؤقت سنكرر ذات الخطوات السابقة مع التايمر بفحص إن كانت الثوانى لا تساوى صفر فننقصها و نعرض الوقت و نرى إن كانت الطاقة المخفضة فنعالجها كما سبق و إلا ننقص الدقائق و إن كان كلاهما = صفر فنوقف الكل و نطلق الزمور و نلغى الرايات و نعود. أما لو المقاطعة الخارجية فنوقف الطاقة و التايمر و ننتظر غلق الباب لنعيد التايمر و الطاقة ثم نعود.

المرة القادمة نكمل إن شاء الله




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