การสร้างฟังก์ชันนับเวลาทุก ๆ 1 มิลลิวินาที
ในการทำงานกับไมโครคอนโทรลเลอร์บ้างครั้งเราคง
อยากที่จะได้ฟังก์ชันที่สามารถนับเวลาทุก 1
มิลลิวินาทีและนับต่อเนื่องไปเรื่อย ๆ
จนกว่าเราจะปิดเครื่องหรือรีเซตจึงกลับมาเริ่มตันนับเวลาใหม่
ฟังก์ชันนับเวลาแบบนี้มีประโยชน์มาก
เมื่อเราต้องการให้โปรแกรมยังคงทำงานส่วนอื่น ๆ ไปก่อน
จนกว่าจะได้เวลาที่ต้องการแล้วค่อยทำงานในส่วนของเวลาที่ได้กำหนดไว้
จากนั้นก็กลับไปทำงานอื่นตามเดิมจนกว่าจะได้เวลาครบตามที่กำหนดอีกครั้ง
ฟังก์ชันที่เราสร้างขึ้นมานี้ ให้ชื่อว่า millis()บางท่านอาจจะคุ้น ๆ กับชื่อฟังก์ชันนี้ ถ้าท่านเคยได้เล่นไมโครคอนโทรลเลอร์ที่ใคร ๆ ก็บอกว่าง่าย จะมีฟังก์ชันนี้มาให้แล้ว แต่ถ้าท่านอยากรู้ว่า dsPIC30F ก็สามารถทำฟังก์ชันดังกล่าวได้ง่าย ๆ เช่นเดียวกัน (ตามตัวอย่างบทความนี้) และอยากรู้ว่าง่ายอย่างไรลองมาลงคอร์สเรียนกับเราครับ เรื่องที่ยากสำหรับไมโครคอนโทรลเลอร์จะกลายเป็นเรื่องที่ง่ายในทันที :)
โค้ดโปรแกรมก็ตามนี้ครับ (โค้ดสำหรับไมโครคอนโทรลเลอร์ dsPIC30F)
ฟังก์ชันที่เราสร้างขึ้นมานี้ ให้ชื่อว่า millis()บางท่านอาจจะคุ้น ๆ กับชื่อฟังก์ชันนี้ ถ้าท่านเคยได้เล่นไมโครคอนโทรลเลอร์ที่ใคร ๆ ก็บอกว่าง่าย จะมีฟังก์ชันนี้มาให้แล้ว แต่ถ้าท่านอยากรู้ว่า dsPIC30F ก็สามารถทำฟังก์ชันดังกล่าวได้ง่าย ๆ เช่นเดียวกัน (ตามตัวอย่างบทความนี้) และอยากรู้ว่าง่ายอย่างไรลองมาลงคอร์สเรียนกับเราครับ เรื่องที่ยากสำหรับไมโครคอนโทรลเลอร์จะกลายเป็นเรื่องที่ง่ายในทันที :)
ความรู้ทั่วไป
การนับเวลาด้วยโมดูล
Timer1 มีสิ่งที่ต้องทำความเข้าใจดังนี้คือ
- ค่า PLLx (Phase Lock Loop) หรือตัวคูณความถี่ มีค่าเท่ากับ 1, 4, 8, และ 16
- ค่า Prescaler หรือตัวหารความถี่ มีค่าเท่ากับ 1, 8, 64 และ 256
- internal instruction cycle clock เท่ากับ Fosc/4
- Timer1 มีขนาด 16 บิต นับได้สูงสุดเท่ากับ 65535 ค่า และเมื่อนับจนถึงค่าสูงสุด (65535) จะกลับไปเริ่มต้นนับศูนย์ใหม่ การกลับไปนับเริ่มต้นใหม่นี้ เรียกว่าการเกิดโอเวอร์โฟลว์ของการนับ
- การนับหนึ่งครั้งของ Timer1 จะใช้เวลาเท่ากับ T = 1/f = 1/(Fosc/4) และเมื่อเกี่ยวข้องกับค่า PLLx และ Prescaler จะได้สมการการนับดังนี้
T = 1/ [(Fosc X PLLx) / (4 X
Prescaler)]
- เมื่อมีการเปิดใช้งานอินเตอร์รัปต์ ทุก ๆ การเกิดโอเวอร์โฟลว์จะเกิดอินเตอร์รัปต์
โค้ดโปรแกรมก็ตามนี้ครับ (โค้ดสำหรับไมโครคอนโทรลเลอร์ dsPIC30F)
1 :
/*****************************************
2 : Author: prajin palangsantikul
3 : Course: dsPIC Microcontroller
4 : WWW: www.appsofttech.com
5 :
*****************************************/
6 : #include
7 : #include
8 :
9 : _FOSC(CSW_FSCM_OFF
& XT);
10 : _FWDT(WDT_OFF);
11 :
12 : #define PLLx
1 // XT
13 : #define Fosc
7372800 // 7.3728MHz
14 : #define Pre
256 // Prescaler
15 : #define Tc
((4.0*Pre)/(Fosc*PLLx)) // Timer Count
16 : #define To
(Tc*1000) // Timer Overflow (ms)
17 : #define T1ms
(1/To) // Count 1 ms
18 :
19 : volatile unsigned long t_millis = 0;
20 : unsigned long millis();
21 :
22 : const long interval = 1000;
23 : int ledState = 0;
24 : unsigned long previousMillis = 0;
25 :
26 : // Setup function
27 : void setup(void)
28 : {
29 : OpenTimer1(T1_ON
&
30 :
T1_IDLE_CON &
31 :
T1_GATE_OFF &
32 :
T1_PS_1_256 &
33 :
T1_SYNC_EXT_OFF &
34 :
T1_SOURCE_INT,
35 : T1ms);
36 :
37 :
ConfigIntTimer1(T1_INT_ON);
38 :
39 : _TRISD0 = 0; // Set RD0 Output
40 : }
41 :
42 : // Main function
43 : int main(void)
44 : {
45 : char ledState;
46 : unsigned long
currentMillis;
47 :
48 : setup();
49 :
50 : while(1) { // Loop
51 : currentMillis =
millis();
52 :
53 : if(currentMillis
- previousMillis >= interval) {
54 : previousMillis
= currentMillis;
55 :
56 : if (ledState ==
0)
57 : ledState = 1;
58 : else
59 : ledState = 0;
60 :
61 : _LATD0 =
ledState;
62 : }
63 : }
64 : }
65 :
66 : unsigned long millis()
67 : {
68 : return
t_millis;
69 : }
70 :
71 : // Timer1 Interrupt
72 : void _ISR _T1Interrupt(void)
73 : {
74 :
t_millis++;
75 : _T1IF =
0;
76 : }
ขอบคุณครับ กำลังศึกษาเรื่องนี้อยู่พอดี
ตอบลบขอบคุณครับผม
ตอบลบ