มกราคม 18, 2018, 10:51:55 am *
ยินดีต้อนรับคุณ, บุคคลทั่วไป กรุณา เข้าสู่ระบบ หรือ ลงทะเบียน
ส่งอีเมล์ยืนยันการใช้งาน?

เข้าสู่ระบบด้วยชื่อผู้ใช้ รหัสผ่าน และระยะเวลาในเซสชั่น
   หน้าแรก   ช่วยเหลือ เข้าสู่ระบบ สมัครสมาชิก  
หน้า: [1]   ลงล่าง
  พิมพ์  
ผู้เขียน หัวข้อ: Delay functions (HI-TECH C for PIC)  (อ่าน 6504 ครั้ง)
0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8270


ShadowWares


| |
« เมื่อ: สิงหาคม 13, 2010, 11:01:46 am »

หลังจากที่ได้เขียนบทความเกี่ยวกับการเขียนโปรแกรมไมโครคอนโทรลเลอร์ PIC ด้วย HI-TECH C Compiler ไปไม่กี่ตอน มีผู้ที่สนใจเขียนอีเมล์มาถามผมว่า "ไม่มีฟังชั่นหน่วงเวลาเหมือน Compiler ตัวอื่นหรือ?", "ทำไมพอเรียกใช้แล้วคอมไฟล์ไม่ผ่าน?", "ทำไมเวลาไม่ตรง?", ...

การใช้งานฟังก์ชั่นหน่วงเวลา หรือ Delay function ของ HI-TECH C for PIC จะต้องทำการบอก Compiler ก่อนว่าความถี่ของคริสตอลมีค่าเท่าไร่ โดยการใช้การ define ดังนี้:

Code:
#define _XTAL_FREQ 4000000
// บอก Compiler ให้รับรู้ว่าความถี่ของคริสตอลมีค่า 4000000Hz หรือ 4MHz

การเรียกใช้งานฟังก์ชันหน่วงเวลา สามารถทำได้เหมือการเรียกใช้งานฟังก์ชันทั่วๆ ไป HI-TECH C for PIC มีฟังก์ชันหน่วงเวลา 3 ฟังก์ชั้นคือ
__delay_ms(), __delay_us() และ _delay() การใช้งานจะต้องทำการระบุค่าการหน่วงเวลาให้ฟังก์ชั้นทั้งสามตัวนี้ด้วย เช่น:


Code:
__delay_ms(100);
// หน่วงเวลา 100mS

Code:
__delay_ms(100);
// หน่วงเวลา 100uS

Code:
_delay(100);
// หน่วงเวลา 100 cycles

 __delay_ms(), __delay_us() กับ _delay คือการทำให้ CPU ประมวลผลอะไรบางอย่างไปเรื่อยๆจนครบตามค่าที่กำหนด ในที่นี้ค่าที่กำหนด หรือค่าที่ส่งผ่านไปยังฟังชันคือ 100 ตัวเลขนี้หมายความว่า:
 __delay_ms(100); หน่วยเวลา 100mS เวลาชัดเจน
 _delay(100); หน่วยเวลา 100 cycles  ไม่รู้เวลา (ถ้าไม่คำนวณ)

มาถึงตรงนี้ แน่นอนว่า  __delay_ms() น่าใช้กว่า เพราะกำหนดเวลาได้แบบตรงไปตรงมา แต่ค่าตำสุดที่เป็นไปได้ของ  __delay_ms() คือ 1mS ถ้าน้อยกว่านี้ ต้องหันไปใช้  _delay() แทน

สิ่งที่ควรทราบ:
- การใช้  _delay() ไม่จำเป็นต้องประกาศหรือ define _XTAL_FREQ ให้ Compiler รับรู้ เพราะ Compiler ไม่ต้องคำนวณอะไรในเชิงเวลา
- ในความเป็นจริงเนื้อในของ __delay_ms() คือ _delay() การเรียก __delay_ms() นั้น Compiler จะทำการคำนวณหาค่าจำนวน cycle ที่เหมาะสมเพื่อไปกำหนดให้ _delay() นั่นเอง
- _delay() ไม่มีอะไรมากไปกว่าการวนลูป เช่น _delay(100); หมายความว่า:

Code:
  MOVLW 0x21
   MOVWF 0x70
L: DECFSZ 0x70, F
   GOTO L

หมายความว่า CPU ทำการกำหนดค่าเริ่มต้นที่เหมาะสม (พร้อมการชดเชยเชิงเวลา) ขึ้นมา และทำการวนลูปลดค่าดังกล่าวลงมาเรื่อยๆ จนถึง 0 เมื่อกระบวนการนี้เสร็จสิ้น นั่นหมายความว่าครบ 100 Cycles แล้วนั่นเอง
บ่อยครั้งจะเห็น code ในระดับภาษา Assembly ที่มีการเคลียร์ค่าของ Watchdog เพราะอย่างที่บอกไปว่า การหน่วงเวลาคือการวนลูปไปเรื่อยๆ จนกว่าจะครบเวลาตาที่ได้กำหนด และถ้าโชคไม่ดีระหว่างที่วนลูปอยู่นั้น Watchdog เกิดการ Overflow หรือ Timeout ขึ้นมา ตัว CPU จะถูก Reset ทำให้การทำงานผิดพลาด

รายละเอียดมีให้ศึกษาอีกพอสมควร ถ้าสนใจเชิงลึกมากกว่านี้ ถามได้เลยครับ หรือไม่ก็หาคู่มือการใช้งานมาศึกษา :)
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
PICPlayer
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 15



| |
« ตอบ #1 เมื่อ: มีนาคม 04, 2011, 03:52:56 pm »

โอ้ว... มัวเขียน for loop อยู่มาตั้งนาน มีแบบนี้ให้ใช้ด้วยหรือนี่
ขอบพระคุณมากๆ ครับ
บันทึกการเข้า
หน้า: [1]   ขึ้นบน
  พิมพ์  
 
กระโดดไป: