Lab6. การใช้งาน Timer2 และ Timer3


#include <p30f2010.h>                   //เปิดใช้งานไลบรารี dspic30F2010                  
#include<timer.h>                              //เปิดใช้งานไลบรารี timer.h

_FOSC(CSW_FSCM_OFF & XT_PLL4);            // โหมดการทำงาน แบบ XT คริสตอล 4 - 10 MHz มี PLLx4 คือ ทวีคูณความถี่ของ clock 4 เท่า
_FWDT(WDT_OFF);                                            //ปิดการทำงาน  watchdog Timer

#define TRUE                      1                              //กำหนดค่าตัวแปรชื่อ TRUE เป็น 1
typedef unsigned char byte;
byte tick=0;                                                           //กำหนดค่าตัวแปรชื่อ tick เป็น 0

void _ISR _T3Interrupt(void)                              //ฟังก์ชัน interrupt timer3
{
                char i;                                     //กำหนดค่าตัวแปรชื่อ I เป็นแบบ ตัวอักษร 8 บิต
                if(++tick == 2){                     //ถ้า ตัวแปร tick เพิ่มขึ้นทีละ 1 แล้วเท่ากับ 2
                _LATE2 = 1;                          //port E2 ON
                _LATE3 = 0;                          //port E3 OFF
                for(i=0;i<10;i++){                 //for loop 50 รอบ
                _LATE2 = !_LATE2;             //กลับสถานะ E2 จาก ON เป็น OFF
                _LATE3 = !_LATE3;             //กลับสถานะ E3 จาก OFF เป็น ON
                delay_ms(50);                      //delay 50 ms.
                }
                // for loop นี้ มีไว้เพื่อให้ E2 , E3 เกิดการกลับสถานะไปมาทุกรอบ หรือไฟกระพริบนั่นเอง
                _LATE2 = 0;          //port E2 OFF
                _LATE3 = 0;          //port E3 OFF
                }
                _T3IF = 0;              //clear register Timer3 เป็น 0
}
byte Rotate_Left(byte *x, byte i)        //ฟังก์ชั่นเลื่อนข้อมูลไปทางซ้าย
{
                for(; i>0; i--)
                *x = (*x<<1)|(*x>>7);          //เลื่อนข้อมูล *x ไปทางซ้ายทีละ 1 หรือ เลื่อนข้อมูล *x ไปทางขวาทีละ 7
                return(*x);                              //Reset ค่า *x เมื่อครบการทำงาน for loop
}                                                               //ถ้ากำหนดตัวแปร i = 1 ก็จะเลื่อนไปทีละ 1 หรือ I = 2 ก็จะเลื่อนไปทีละ 2
void Timer23_Init(void){     //ฟังก์ชันการทำงานของ Timer1

unsigned int config, period;             //กำหนดตัวแปรชื่อ config, period เป็นแบบ จำนวนเต็มบวก 16 บิต
CloseTimer23();                  //ปิดการทำงานของ Timer23
                ConfigIntTimer23(T2_INT_ON);                      
                WriteTimer23(0);                                 // Clear ค่าใน Timer23 เป็น 0
               
                config = T1_ON &                               // Start timer2
                                                T2_GATE_OFF &                 // Disable gate pin for timer2
                                                T2_IDLE_STOP &                // Stop timer in idle mode
                                                T2_PS_1_64 &                     // Presceler 1:64
                                                T2_SYNC_EXT_OFF &                       // Disable sync external source
                                                T2_SOURCE_INT;               // Wait till the timer matches with the period value
period = 57604;                                  ในการนับแต่ละครั้งตามเวลาที่กำหนดไว้ข้างบน ใช้เวลาเท่ากับ         ดังนั้นต้องการให้เกิด Interrupt ทุกๆ 0.5 วินาที สามารถหาค่า  period =
                OpenTimer23(config,period);         //เปิดการทำงาน Timer23 ตามค่าที่กำหนดไว้
}
int main(void)
{
                byte r1 = 1, dout = 1;          //กำหนดค่า r1, dout เป็น 0x01

                TRISB = 0;             //กำหนดพอร์ต B เป็น output
                _TRISE0 = 0;        //กำหนดพอร์ต E0 เป็น output
                _TRISE1 = 0;        //กำหนดพอร์ต E1 เป็น output
                _TRISE2 = 0;        //กำหนดพอร์ต E2 เป็น output
                _TRISE3 = 0;        //กำหนดพอร์ต E3 เป็น output

                LATB = 0;              //port B OFF
                _LATE0 = 0;          //port E0 OFF
                _LATE1 = 0;          //port E1 OFF

                ADPCFG = 0XFF;                                //ปิดการใช้งานโมดูล A to D
                Timer23_Init();                      //เรียกใช้งานฟังก์ชัน Timer23

                while(1)                                
                {              
                if(dout < 0x40){//ถ้า dout < 0x40 (10000000) แน่นอนว่าน้อยกว่าเพราะว่า dout = 0x01 (00000001)
                LATE = 0;              //port E0 OFF
                LATB = dout;        // port B = dout
                }
                else{                       // ถ้า dout = 0x40
                LATB = 0;              //port B = 0
                LATE = dout >> 6;               // port E = dout >> 6 หรือ dout = 00000001
                }
//ฟังก์ชัน if  else นี้เพื่อทำให้ค่า dout = 0x01 ตลอดเวลาเพื่อทำให้เกิดไฟวิงตลอดเวลา
                dout = Rotate_Left(&r1,1);                 //dout จะทำให้เกิด การเลื่อนบิตไปทางซ้าย (ไฟวิ่ง) ทีละ 1 B0-B6, E0, E1 ตามลำดับ
                delay_ms(100);                    //delay 100 ms.
                }
return 0;                 //Reset ค่าเริ่มต้น
}
โปรแกรมการทำงานหลักของโปรแกรมนี้คือ ไฟวิ่ง ที่พอร์ต B, E0, E1 แต่ทุกๆ 1 วินาที(คือ ตัวแปร tick = 2 ครั้งละ 0.5 วินาที) จะเกิด interrupt ขัดจังหวะการทำงานของโปรแกรมหลัก คือ การทำงานในฟังก์ชัน Timer23 interrupt แล้วจึงกลับมาทำงานตามโปรแกรมหลักเหมือนเดิม