#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 delay_ms(unsigned int ms){ //ฟังก์ชัน delay_ms
unsigned int i;
for(; ms>0; ms--)
for(i=0; i<728; i++)
Nop();
}
void _ISR _T1Interrupt(void) //ฟังก์ชัน interrupt timer1
{
char i; //กำหนดค่าตัวแปรชื่อ I เป็นแบบ ตัวอักษร 8 บิต
if(++tick == 2){ //ถ้า ตัวแปร tick เพิ่มขึ้นทีละ 1 แล้วเท่ากับ 2
_LATE2 = 1; //port E2 ON
_LATE3 = 0; //port E3 OFF
for(i=0;i<50;i++){ //for loop 50 รอบ
_LATE2 = !_LATE2; //กลับสถานะ E2 จาก ON เป็น OFF
_LATE3 = !_LATE3; //กลับสถานะ E3 จาก OFF เป็น ON
delay_ms(300); //delay 300 ms.
}
// for loop นี้ มีไว้เพื่อให้ E2 , E3 เกิดการกลับสถานะไปมาทุกรอบ หรือไฟกระพริบนั่นเอง
_LATE2 = 0; //port E2 OFF
_LATE3 = 0; //port E3 OFF
}
_T1IF = 0; //clear register Timer1 เป็น 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
int main(void)
{
void Timer1_Init(void){ //ฟังก์ชันการทำงานของ Timer1
unsigned int config, period; //กำหนดตัวแปรชื่อ config, period เป็นแบบ จำนวนเต็มบวก 16 บิต
CloseTimer1(); //ปิดการทำงานของ Timer1
ConfigIntTimer1(T1_INT_ON);
WriteTimer1(0); // Clear ค่าใน Timer1 เป็น 0
config = T1_ON & // Start timer1
T1_GATE_OFF & // Disable gate pin for timer1
T1_IDLE_STOP & // Stop timer in idle mode
T1_PS_1_64 & // Presceler 1:64
T1_SYNC_EXT_OFF & // Disable sync external source
T1_SOURCE_INT; // Wait till the timer matches with the period value
period = 57604; ในการนับแต่ละครั้งตามเวลาที่กำหนดไว้ข้างบน ใช้เวลาเท่ากับ ดังนั้นต้องการให้เกิด Interrupt ทุกๆ 0.5 วินาที สามารถหาค่า period =
OpenTimer1(config,period); //เปิดการทำงาน Timer1 ตามค่าที่กำหนดไว้
}
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
Timer1_Init(); //เรียกใช้งานฟังก์ชัน Timer1
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(200); //delay 200 ms.
}
return 0; //Reset ค่าเริ่มต้น
}
โปรแกรมการทำงานหลักของโปรแกรมนี้คือ ไฟวิ่ง ที่พอร์ต B, E0, E1 แต่ทุกๆ วินาที(คือ ตัวแปร tick = 2 ครั้งละ 0.5 วินาที) จะเกิด interrupt ขัดจังหวะการทำงานของโปรแกรมหลัก คือ การทำงานในฟังก์ชัน Timer1 interrupt แล้วจึงกลับมาทำงานตามโปรแกรมหลักเหมือนเดิม