การใช้งานไทเมอร์ใน ไมโครคอนโทรลเลอร์ MCS-51

homenewsarticleproductwebboardpaymentdeliverydownloadcontact
 
 

การใช้งานไทเมอร์ใน ไมโครคอนโทรลเลอร์ MCS-51

ไมโครคอนโทรลเลอร์ MCS-51 มีไทเมอร์/เคาน์เตอร์ขนาด 16 บิต 2 ตัว คือไทเมอร์ 0 และไทเมอร์ 1 ส่วนในไมโครคอนโทรลเลอร์อนุกรม 8052 ซึ่งออกมาทีหลังจะมีไทเมอร์/เคาน์เตอร์ 3 ตัว นั้นคือมีไทเมอร์ 2 เพิ่มขึ้นมา ไทเมอร์/เคาน์เตอร์แต่ละตัวสามารถเลือกใช้งานเป็นไทเมอร์ หรือเคาน์เตอร์ก็ได้ และทำงานได้อย่างเป็นอิสระต่อกัน ในการทำงานเป็นไทเมอร์นั้นจะใช้หลักการเพิ่มค่ารีจิสเตอร์ไทเมอร์ ทุก ๆ Machine Cycle ซึ่งมีช่วงเท่ากับ 12 คาบสัญญาณนาฬิกาที่ถูกสร้างขึ้นจากคริสตอลที่ต่อใช้งานให้กับไมโครคอนโทรลเลอร์นั้นเอง สำหรับบทความนี้จะอธิบายรายละเอียด และตัวอย่างการใช้งานไทเมอร์ 0 และ 1 เท่านั้นนะครับ สำหรับไทเมอร์ 2 สามารถอ่านรายละเอียดได้ที่บทความการใช้พอร์ตอนุกรมของไมโครคอนโทรลเลอร์ MCS-51 ครับ
ในการใช้งานไทเมอร์ 0 และ 1 ของ MCS-51 นั้น เราต้องรู้จัก รีจิสเตอร์ที่สำคัญที่ใช้ควบคุมการทำงานของไทเมอร์เสียก่อน ซึ่งมีรายละเอียดดังนี้

รีจิสเตอร์ไทเมอร์: เป็นรีจิสเตอร์ขนาด 8 บิต มี 4 ตัวด้วยกันคือTL0 อยู่ที่ตำแหน่ง 8AH, TH0 อยู่ที่ตำแหน่ง 8CH, TL1 อยู่ที่ตำแหน่ง 8BH และ TH1 อยู่ที่ตำแหน่ง 8DH โดยปกติจะทำงานเป็นคู่กัน นั้นคือไทเมอร์ 0 ใช้รีจิสเตอร์ TL0 และ TH0 ส่วนไทเมอร์ 1 ใช้รีจิสเตอร์ TL1 และ TH1 ซึ่งทำให้กลายเป็นรีจิสเตอร์ขนาด 16 บิต ในการทำงานเป็นไทเมอร์ เมื่อไทเมอร์ถูกเปิดค่าในรีจิสเตอร์ไทเมอร์จะเพิ่มขึ้นทุก ๆ Machine Cycle จนกว่าจะเกิดการโอเวอร์โฟลว

รีจิสเตอร์ TCON เป็นรีจิสเตอร์ขนาด 8 บิต อยู่ที่ตำแหน่ง 88H สามารถเข้าถึงได้ในระดับบิต มีโครงสร้างดังแสดงในรูปที่ 1

รีจิสเตอร์ TCON

รูปที่ 1 โครงสร้างรีจิสเตอร์ TCON

TF1 (Timer 1 overflow Flag): เป็นบิตที่ใช้ในแสดงการเกิดโอเวอร์โฟลวของไทเมอร์ 1 โดยบิต TF1 จะถูกเซตเป็น “1” อัตโนมัติ เมื่อเกิดโอเวอร์โฟลวจากไทเมอร์ 1 และจะถูกเคลียร์โดยกระบวนการทางฮาร์ดแวร์ เมื่อเกิดการอินเตอร์รัปต์จากไทเมอร์ 1 ขึ้น

TR1 (Timer 1 run Control bit): ใช้ควบคุม เปิด ปิด การทำงานของไทเมอร์ 1 สามารถเซต หรือเคลียร์ได้โดยซอฟท์แวร์ โดยถ้าต้องการให้ไทเมอร์ 1 ทำงานต้องเซตบิตนี้ให้เป็น “1”

TF0 (Timer 0 overflow Flag): เป็นบิตที่ใช้ในแสดงการเกิดโอเวอร์โฟลวของไทเมอร์ 0 โดยบิต TF0 นี้จะถูกเซตเป็น “1” อัตโนมัติ เมื่อเกิดโอเวอร์โฟลวจากไทเมอร์ 0 และจะถูกเคลียร์โดยกระบวนการทางฮาร์ดแวร์ เมื่อเกิดการอินเตอร์รัปต์จากไทเมอร์ 0 ขึ้น

TR0 (Timer 0 run Control bit): ใช้ควบคุม เปิด ปิด การทำงานของไทเมอร์ 0 สามารถเซต หรือเคลียร์ได้โดยซอฟท์แวร์ โดยถ้าต้องการให้ไทเมอร์ 0 ทำงานต้องเซตบิตนี้ให้เป็น “1”

สำหรับบิต IE1, IT1, IE0, และ IT0 นั้นใช้สำหรับกระบวนการอินเตอร์รัปต์จากภายนอก ซึ่งจะ กล่าวถึงในโอกาสหน้านะครับ

รีจิสเตอร์TMOD (Timer/Counter Mode Control Register) เป็นรีจิสเตอร์ขนาด 8 บิต อยู่ที่ตำแหน่ง 89H ไม่สามารถเข้าถึงได้ในระดับบิตได้ แบ่งออกเป็น 2 ส่วนคือ ส่วน 4 บิตล่างใช้กำหนดโหมดการทำงานของไทเมอร์ 0 และ 4 บิตบนใช้กำหนดการทำงานของไทเมอร์ 1 มีโครงสร้างดังแสดงในรูปที่ 2

รีจิสเตอร์ TMOD

รูปที่ 2 โครงสร้างรีจิสเตอร์ TMOD

GATE: ใช้เลือกการควบคุมการทำงานของไทเมอร์ โดยถ้าเป็น “0” จะเป็นการควบคุมทางซอฟท์แวร์ นั้นคือไทเมอร์จะทำงานเมื่อบิต TR ในรีจิสเตอร์ TCON เป็น “1” แต่ในกรณีที่บิต GATE เป็น “1” จะเป็นการควบคุมทางฮาร์แวร์ นั้นคือไทเมอร์จะทำงานเมื่อบิต TR ในรีจิสเตอร์ TCON เป็น “1” และ ขาอินพุต INT ของไมโครคอนโทลเลอร์มีสถานะลอจิกเป็นเป็น “1” ด้วย

C/T (Timer or Counter selector) ใช้เลือกการทำงานของไทเมอร์/เคาน์เตอร์ โดยถ้าเป็น “0” จะทำงานเป็นไทเมอร์ แต่ถ้าเป็น “1” จะทำงานเป็นเคาน์เตอร์
M1, M0 (Mode selector bit) ใช้เลือกโหมดการทำงานของไทเมอร์/เคาน์เตอร์โดยถ้า เป็น“00” ทำงานในโหมด 0, “01” ทำงานในโหมด 1, “10” ทำงานในโหมด 2, “11” ทำงานในโหมด 3

การทำงานในโหมด 0 เป็นการทำงานเป็นไทเมอร์/เคาน์เตอร์ 13 บิต นั้นคือใช้งานรีจิสเตอร์ TL 5 บิต และ TH 8 บิต ดังนั้นเมื่อค่าในรีจิสเตอร์ TL และ TH เพิ่มขึ้นจนเป็น “1” หมดทั้ง 13 บิต บิต TF ภายในรีจิสเตอร์ TCON ก็จะถูกเซต เพื่อแสดงการเกิดโอเวอร์โฟลว

การทำงานในโหมด 1 เป็นการทำงานเป็นไทเมอร์/เคาน์เตอร์ 16 บิต นั้นคือใช้งานรีจิสเตอร์ TL และ TH ครบทั้ง 8 บิต ดังนั้นเมื่อค่าในรีจิสเตอร์ TL และ TH เพิ่มขึ้นจนเป็น “1” หมดทั้ง 16 บิต บิต TF ภายในรีจิสเตอร์ TCON ก็จะถูกเซต เพื่อแสดงการเกิดโอเวอร์โฟลว
การทำงานในโหมด 2 เป็นการทำงานเป็นไทเมอร์/เคาน์เตอร์ 8 บิต แบบตั้งค่าอัตโนมัติ (Auto Reload) โดยรีจิสเตอร์ TL ทำงานเป็นตัวนับ ส่วนรีจิสเตอร์ TH ทำงานเป็นตัวเก็บค่าเริ่มต้นของการนับ เมื่อเริ่มต้นการทำงานค่ารีจิสเตอร์ TL จะถูกเซตให้เหมือนกับค่าในรีจิสเตอร์ TH และเริ่มการนับแบบ 8 บิต เมื่อนับจนเกิดโอเวอร์โฟลว (ค่าในรีจิสเตอร์ TL เป็น “1” หมดทุกบิต) จะทำให้บิต TF ภายในรีจิสเตอร์ TCON จะถูกเซต ส่วนรีจิสเตอร์ TL ก็จะถูกเซตให้เหมือนกับค่าในรีจิสเตอร์ TH และเริ่มต้นการนับใหม่อีกครั้ง

การทำงานในโหมด 3 จะสามารถใช้ได้เฉพาะกับไทเมอร์ 0 เท่านั้น โดยมีการทำงานของ TH0 และ TL0 แยกกันอิสระ TL0 สามารถเลือกการทำงานเป็นได้ไทเมอร์ หรือเคาน์เตอร์ ได้ตามปกติ ถูกควบคุมจากบิตภายในรีจิสเตอร์ TCON และขาสัญญาณ INT0 และเมื่อเกิดโอเวอร์โฟลวเกิดขึ้นจะเกิดการเซตบิต TF0 ส่วนรีจิสเตอร์ TH0 นั้นถูกควบคุมการทำงานโดยบิต TR1 ในรีจิสเตอร์ TCON เท่านั้น และถ้าเกิดการโอเวอร์โฟลวขึ้น จะทำให้เกิดการเซตบิต TF1
ในการทดลองนี้เราได้ต่อ LED กับพอร์ต 0.0 เพื่อแสดงสถานะของพอร์ต และให้ไทเมอร์ 0 ทำงานในโหมด 1 ซึ่งเป็นการนับแบบ 16 บิต โดยทำงานเป็นตัวจับเวลาเพื่อให้พอร์ต 0.0 ขับ LED ติดค้าง 1 วินาที และดับ 1 วินาทีสลับกันไป โปรแกรมสามารถเขียนได้ตามด้านล่างนี้นะครับ

#include <t89c51rd2.h>
#include <stdio.h>
unsigned char temp,i,a;
void Delay(unsigned char time) // Delay 10 ms
{
unsigned char count;
for(count=0;count<time;count++)
{
TH0=0xC3; // Initial TH0 for Delay 10 ms
TL0=0xFF; // Initial TL0 for Delay 10 ms
TR0=1;
TF0=0;
while (TF0==0);
TR0=0;
}
}
void main()
{
TMOD=0x01; //Configure timer0 for mode 1 operation
P0=0x00;
while(1)
{
P0_0=~P0_0;
Delay(100); // Delay 1 s
}
}

จากโปรแกรมจะเห็นได้ว่า เมื่อเริ่มโปรแกรมเราต้องเขียนค่าลงรีจิสเตอร์ TMOD เพื่อตั้งให้ไทเมอร์ 0 ทำงานเป็นไทเมอร์ในโหมด 1 เสียก่อนนั้นคือ TMOD=0x01 ซึ่งเมื่อดูในระดับบิตนั้นคือ GATE = 0 ควบคุมการทำงานเปิด ปิดไทเมอร์ด้วยกระบวนการทางซอฟท์แวร์ (ควบคุมด้วยการเซต หรือเคลียร์บิต TR ในรีจิสเตอร์ TCON), C/T = 0 ให้ทำงานเป็นไทเมอร์, M1 M0 = “01” ทำงานในโหมด 1 จากนั้นก็วนลูปเพื่อให้ P0.0 ติด 1 วินาที และดับ 1 วินาทีสลับกันโดยใช้การหน่วงเวลาของฟังก์ชัน Delay ขั้น

ภายในฟังก์ชัน Delay เป็นการใช้ไทเมอร์ 0 หน่วงเวลาซึ่งมีความละเอียด 10 ms นั้นก็คือจะเกิดการโอเวอร์โฟลวขึ้นในช่วงเวลา 10 ms เนื่องจากในการทดลองนี้ได้ใช้คริสตอลความถี่ 18.432 Mhz ดังนั้นช่วงของ Machine Cycle จึงเท่ากับ 12/18.432 ไมโครวินาที ในการให้เกิดการโอเวอร์โฟลวในช่วงเวลา 10 ms นั้น ต้องมีการเพิ่มค่าในรีจิสเตอร์ไทเมอร์ 15,360 ครั้ง (10 msec/Machine Cycle) ถ้าเราแปลงเป็นเลขฐาน 16 จะได้ 0x3C00 และเนื่องจากการนับเป็นการนับขึ้นโดยเพิ่มค่าในรีจิสเตอร์ไทเมอร์ ดังนั้นเราจะสามารถหาค่าเริ่มต้นของรีจิสเตอร์ไทเมอร์ได้ ซึ่งจะเท่ากับ 0xFFFF-0x3C00 = 0xC3FF ดังนั้นจึงต้องกำหนดค่าเริ่มต้นของรีจิสเตอร์ TH0 และ TL0 ให้เป็น 0xC3 และ 0xFF ตามลำดับ เมื่อกำหนดค่าเริ่มต้นของรีจิสเตอร์ไทเมอร์ 0 แล้ว ก็เปิดไทเมอร์ 0 โดยการเซตบิต TR0 ให้เป็น “1” จากนั้นก็รอจนกว่าจะเกิดการโอเวอร์โฟลวซึ่งบิต TF1 จะเป็น “1”  จึงค่อยปิดไทเมอร์ ซึ่งจะเป็นช่วงเวลา 10 ms พอดี ในการหน่วงเวลาระยะที่มากกว่านี้ ก็สามารถทำได้โดยวนลูปจับเวลาหลายครั้ง ดังจะเห็นในฟังก์ชัน Delay

ไฟล์โค๊ดภาษา C สามารถดาวน์โหลดได้ที่ http://www.mind-tek.net/c/Timer.c หรือดาวน์โหลดไฟล์ hex ไปทดสอบกันได้ที่ http://www.mind-tek.net/hex/Timer.hex นะครับ ท้ายสุดนี้ หวังว่าผู้อ่านจะได้รับความรู้ ไม่มากก็น้อย และสามารถนำไปประยุกต์ใช้กับงานต่าง ๆ ได้นะครับ


 

73/206 Ratchathanee Paholyothin Rd. Klonghnung Klonghloung Pathumthanee 12120 Tel: 66-02516-5999 Fax:66-02516-8484 Email:webmaster@mind-tek.net