[Print][Back]

จุฬาลงกรณ์มหาวิทยาลัย

คณะวิศวกรรมศาสตร์

ภาควิชาวิศวกรรมคอมพิวเตอร์

2110262 Microprocessor Systems Lab.

ชื่อ ______________________________

เลขประจำตัว ________________________

หมายเลขเครื่อง ______________________

วันที่ ______________________________


3. เวลาและระบบสัญญาณนาฬิกา

วัตถุประสงค์

  1. เพื่อให้นิสิตเกิดทักษะในการเขียนโปรแกรมภาษา Assembly มากขึ้น

  2. เพื่อให้นิสิตสามารถพัฒนาโปรแกรมในลักษณะของ Time Critical หรือ Real Time Application ได้

  3. เพื่อให้นิสิตเข้าใจหลักการของ CPU Cycle และ Timer Interrupt

อุปกรณ์ที่แจกให้

ทฤษฎีที่เกี่ยวข้อง/อ้างอิง

การพัฒนาซอฟต์แวร์ที่มีการทำงานขึ้นกับจังหวะเวลานั้นเราสามารถทำได้หลายรูปแบบ แต่ที่นิยมใช้กันมีอยู่ 3 รูปแบบคือวิธีแรก การพัฒนาซอฟต์แวร์ด้วยหลักการนับจำนวน Clock Cycle ของคำสั่ง วิธีที่สองคือการใช้ระบบ Timer Interrupt ภายในหน่วยประมวลผลเอง และวิธีที่สามคืออาศัยการทำงานของวงจรเวลาภายนอก ซึ่งทำสามวิธีต่างก็มีหลักการ ข้อดีและข้อเสียแตกต่างกันไปดังรายละเอียดต่อไปนี้ การอาศัยหลักการนับจำนวน Clock Cycle ผู้พัฒนาซอฟต์แวร์จะต้องศึกษาถึงจำนวน Cycle per Instruction (CPI) ของสถาปัตยกรรมหน่วยประมวลผลที่เราต้องการใช้ให้ละเอียด และเขียนโปรแกรมประมาณให้จำนวน Cycle คูณด้วยค่า Cycle Time ได้เวลาใกล้เคียงกับเวลาที่เราต้องการมากที่สุด เช่นกรณีของ PIC เราทราบว่าที่ Oscillator ความถี่ 4 Mhz จะมี Cycle Time เป็น 1us และคำสั่งเกือบทั้งหมดจะใช้ Cycle Per Instruction เป็น 1 เกือบทั่งหมด(ยกเว้นคำสั่งเกี่ยวกับ SubRoutine, Conditional Control และ Logical บางอัน) ดังนั้นหากต้องการให้ได้เวลาทำงานเป็น 1 วินาที เราจะต้องเขียนโปรแกรมให้ทำงานคำสั่งใดก็ได้ 1/10-6 คำสั่ง ก่อนจะทำการประมวลผลงานที่เราต้องการ ดังแสดงตัวอย่างโปรแกรมที่ 1 ซึ่งจะทำการวนรอบให้ได้การทำงานประมาณ 1,000,000 usการเขียนโปรแกรมโดยใช้ Timer Interrupt นั้นผู้พัฒนาจะต้องเข้าใจหลักการทำงานของ Timer และ Interrupt ของไมโครคอนโทรเลอร์นั้นดีพอ ในที่นี้จะขออธิบายการทำงานของ Timer ใน PIC และ โครงสร้างของ Interrupt โดยสังเขปหากต้องการรายละเอียดเพิ่มเติมผู้ใช้สามารถหาอ่านได้จากคู่มือของ PIC ภายใน PIC จะประกอบด้วย Timer 3ชุดคือ Timer 0 , Timer 1 และ Timer 2 โดยแต่ละชุดจะมีโครงสร้างและการทำงานที่แตกต่างกันไป ทั้งนี้ขึ้นอยู่กับผู้ใช้จะเลือกใช้งาน


; This Routine will loop for 1 Sec
DELAY:
	MOVLW	04     		;              
	MOVWF	CNT2		;                                         -+
	MOVLW	0FAH		;                                          +
	MOVWF	CNT1		;                                          +
	MOVLW	0FAH		; 1                     -+                 +
	MOVWF	CNT			; 1                      +                 +
	NOP	         		; 1 -+                   +                 +
	DECFSZ	CNT,F		; 1  +- 4 * 250          +- * 250          +- * 4
	GOTO	$-2			; 2 -+		             +                 +
	DECFSZ	CNT1,F		; 1	                     +                 +
	GOTO	$-6			; 2		                -+                 +
	DECFSZ	CNT2,F		;                                          +
	GOTO	$-A			;                                         -+
	RETURN

โปรแกรม 1 Routine สำหรับการ Delay 1 วินาที

Timer 0 เป็น Timer/Counter ขนาด 8 บิต สามารถทำ Prescaler ได้ตั้งแต่ 1:2, 1:4, …. , 1:256 ใช้ได้กับ Internal/External Clock และจะเกิด Interrupt เมื่อมีการ Overflow จาก FFH เป็น 00H นอกจากนี้ยังเลือกได้ด้วยว่าจะให้นับที่ Positive หรือ Negative Edge ในการควบคุม TIMER 0 จะควบคุมผ่านบิตต่างๆ ใน Register OPTION_REG ส่วนการตั้งเวลาจะทำผ่าน Register TMR0

Timer 1 เป็น Timer/Counter ขนาด16 บิตซึ่งประกอบขึ้นจาก Register ขนาด 8 บิต 2 ตัว (TMR1H:TMR1L) มีการทำงานคล้ายกับ Timer 0 กล่าวคือสามารถทำ Prescaler ได้ตั้งแต่ 1:1,1:2,…., 1:8 และจะเกิด Interrupt เมื่อมีการ Overflow เช่นเดียวกัน Register ที่ใช้สำหรับควบคุมคือ T1CON และทำงานได้แม้ว่าจะอยู่ใน Sleep Mode คุณลักษณะเด่นของ Timer 1 คือสามารถต่อ External source oscillator ให้สามารถเป็นแหล่งกำเนิดสัญญาณได้โดยตรง โดยอาจเลือกต่อเป็น Crystal Oscillator เข้ากับขา T1OS0 และ T1OS1 ควรต่อตัวเก็บประจุคร่อมระหว่างแต่ละขากับ Ground ด้วย (ดังรูป) ในที่นี้ค่า C ที่มีค่าเหมาะสมประมาณ 30 pF

Timer 2 เป็น 8 บิต Timer/Counter พร้อม 8 บิต Period Register, Prescaler และ Postscaler ซึ่งมีคุณสมบัติพิเศษที่แตกต่างจาก Timer 0 บางประการ (จะไม่ขอกล่าวถึงในที่นี้) เหมาะสำหรับเป็น Pulse Width Modulatorโครงสร้างระบบ Interrupt ของ PIC นั้น จะประกอบด้วย Register สำหรับควบคุมทั้งสิ้น 3 ตัวด้วยกันคือ INTCON, PIR1 และ PIR2 นอกจากนี้ยังมี Register ที่คอยเก็บสถานะอีกคือ PIR1 และ PIR2 ซึ่งจะถูก Set เป็น 1 โดยสัญญาณ Interrupt และ จะต้อง Clear เองด้วยซอฟต์แวร์ ในการ Enable Interrupt ของระบบจะต้องทำผ่านบิตต่างๆ ซึ่งมีโครงสร้างแสดงได้ดังรูป เช่นหากต้องการจะ Enable Interrupt เพื่อใช้กับ Timer2 เราจะต้องทำการ Enable ให้ GIE, PEIE และ TMR2IE เป็น 1 รายละเอียดโครงสร้างของ Register ให้นิสิตดูได้จากคู่มือของ PIC

Interrupt Service Routine คือ โปรแกรมย่อยที่จะทำงานเมื่อมีสัญญาณ Interrupt เกิดขึ้น โดยปกติเมื่อเกิดสัญญาณ Interrupt ไมโครโปรเซสเซอร์ทั่วไปมักจะเปิด Interrupt Vector Table ทำการบันทึกค่าของ Register ต่างๆ ลง Stack แล้ว Jump ไปยังโปรแกรมย่อยที่ชี้โดย Vector Table แต่สำหรับ Pic แล้วสัญญาณ Interrupt ต่างๆ ที่เกิดขึ้นจะมีค่า Vector คงที่อยู่ที่ตำแหน่ง 0x0004 และจะไม่มีการบันทึกค่า Register ใดไว้ให้ ผู้พัฒนาโปรแกรมจะต้องทำการบันทึกค่า Context ต่างๆ เอง ค่าของ Context ที่ควรจะเก็บประกอบด้วย Register W, STATUS และ PCLATH ดังแสดงในโปรแกรมที่ 2

	
	List p=16f877
	Include 
;***** VARIABLE DEFINITIONS
W_TEMP        EQU     0x20        ; variable used for context saving 
STATUS_TEMP   EQU     0x21        ; variable used for context saving
PCLATH_TEMP   EQU     0x22        ; variable used for context saving

;**********************************************************************
	ORG     0x000             	; processor reset vector
	CLRF    PCLATH            	; ensure page bits are cleared
	GOTO    MAIN              	; go to beginning of program

	ORG     0x004             	; interrupt vector location
; Save Context
	MOVWF   W_TEMP      	; save off current W register contents
	SWAPF	STATUS, W	; Swap status to be saved into W
	CLRF	STATUS	; bank 0, regardless of current bank, Clear IRP,RP1,RP0
	MOVWF	STATUS_TEMP	; Save status to bank zero STATUS_TEMP REGISTER
	MOVF	PCLATH, W	  	; Only required if using pages 1, 2 and/or 3
	MOVWF	PCLATH_TEMP ; move status register into W register
	CLRF	PCLATH		; page zero, regardless of current page

;  ISR code can go here or be located as a call subroutine elsewhere

; Clear Interrupt Flag ( If used)
; Restore Context
	MOVF	PCLATH_TEMP, W    	; Resture PCLATH
	MOVWF	PCLATH            	; Move W into PCLATH
	SWAPF	STATUS_TEMP,W     	; Swap STATUS_TEMP register into W
                                  			; (sets bank to original state)
	MOVWF	STATUS            	; Move W into STATUS register
	SWAPF	W_TEMP,F          	; Swap W_TEMP
	SWAPF	W_TEMP,W          	; Swap W_TEMP into W
	RETFIE                    		; return from interrupt
MAIN:
; remaining code goes here

	END                       ; directive 'end of program'

โปรแกรมที่ 2 ตัวอย่างการเขียน Interrupt Service Routine

เมื่อมีสัญญาณ Interrupt จาก Timer ระบบจะทำการ Set ให้บิต Interrupt Flag ให้เป็น 1 ทั้งนี้ผู้เขียนซอฟต์แวร์จะต้อง Clear บิตนี้เองก่อนที่จะ Return ออกจาก Interrupt Service Routine โดย Interrupt ของ Timer 0,1 และ 2 คือบิต T0IF ใน Register INTCON, บิต TMR1IF และ TMR2IF ใน Register PIR1 ตามลำดับ

การทดลอง

  1. ให้พัฒนาซอฟต์แวร์ด้วยหลักการของการนับ Instruction Cycle เพื่อให้ LED (RB1) เกิดการกระพริบทุกๆ 1 วินาที (ติด 1 วินาที ดับ 1 วินาที) โดยประมาณ

  2. ให้พัฒนาซอฟต์แวร์ต่อจากข้อ 1 ด้วยหลักการของ Timer และ Interrupt เพื่อให้ LED (RB2) เกิดการกระพริบทุกๆ 0.5 วินาที (ติด 0.5 วินาที ดับ 0.5 วินาที) โดยประมาณ ทั้งนี้ให้ใช้ Timer 1 (RB1 จะต้องยังคงกระพริบอยู่เหมือนเดิมตามที่ทดลองในข้อ 1)

  3. ให้พัฒนาซอฟต์แวร์ด้วยต่อจากข้อ 1 ด้วยหลักการของ Counter และ Interrupt เพื่อให้ LED (RB2) เกิดการกระพริบทุกๆ 2 วินาที ทั้งนี้ให้ Count จาก Crystal กำเนิดสัญญาณภายนอกที่แจกให้ร่วมกับ Timer 1 (RB1 จะต้องยังคงกระพริบอยู่เหมือนเดิมตามที่ทดลองในข้อ 1)

[Print][Back]