Bài 5: Ngắt Timer 1
Timer rất quan trọng trong kĩ thuật lập trình, nó có thể thay thế hàm main(), tạo khoảng thời gian định thời mà không cần dùng hàm delay(). Ứng dụng tối quan trọng của Timer đó là ngắt, ta có thể tạo ra một khoảng thời gian mong muốn để thực hiện một chuỗi hàm trong ngắt..
Timer1 của Dspic 33fj32mc202 là timer 16 bit
Xét bài toán: Dùng ngắt timer 1 để tạo bật tắt Led đơn với chu kì 0,5s
Tính toán: Giả sử ta dùng tần số dao động của chip là Fosc = 40MHz => Fcy = 20MHz
Ta sử dụng bộ chia tần cho timer là 1:256
Ta có: 0.5 = PR1 * 256 * 1/20.000.000
Suy ra: PR1 = 0,5*20.000.000/256 = 39062.
Đây chính là giá trị hẹn giờ Timer cần đặt
Thực hiện: ta chọn tần số dao động là 40MHz:
#include <p33fj32mc202.h>
// Select Internal FRC at POR
_FOSCSEL(FNOSC_FRC); //su dung dao động nội 7.37MHz
// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); //disable WDT
int main()
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD = 20; // M = 22
CLKDIVbits.PLLPOST=0; // N2 = 2
CLKDIVbits.PLLPRE=0; // N1 = 2 Fosc = 40MHz => Fcy = 20MHz.
// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while(OSCCONbits.LOCK!= 1) {};
Ta có hàm cai dặtd timer 1 như sau:
void Timer1init()
{
_TON = 0; //disable timer 1
_TCKPS = 3; //su dung bo chia tan 1:256
_TCS = 0; //su dung tan so noi
_TGATE = 0; //disable TGATE
TMR1 = 0; //reset register
PR1 = 39062; // set timer
_T1IP = 0x01; //dat muc uu tien
_T1IF = 0; //clear timer1 interrupt flag
_T1IE = 1; //cho phep ngat
_TON = 1; // enable timer1
}
Trong hàm ngắt timer 1: ta thực hiện đảo xung led:
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void)
{
IFS0bits.T1IF = 0; // Clear Timer1 Interrupt Flag
_LATB5 = ~_LATB5;
}
Dùng ociiloscoper để đo xung tại chân led, ta sẽ được khoảng thời gian đảo xung ta 500ms = 0,5s
Hoàn thành!!
Timer1 của Dspic 33fj32mc202 là timer 16 bit
Xét bài toán: Dùng ngắt timer 1 để tạo bật tắt Led đơn với chu kì 0,5s
Tính toán: Giả sử ta dùng tần số dao động của chip là Fosc = 40MHz => Fcy = 20MHz
Ta sử dụng bộ chia tần cho timer là 1:256
Ta có: 0.5 = PR1 * 256 * 1/20.000.000
Suy ra: PR1 = 0,5*20.000.000/256 = 39062.
Đây chính là giá trị hẹn giờ Timer cần đặt
Thực hiện: ta chọn tần số dao động là 40MHz:
#include <p33fj32mc202.h>
// Select Internal FRC at POR
_FOSCSEL(FNOSC_FRC); //su dung dao động nội 7.37MHz
// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF); //disable WDT
int main()
{
// Configure PLL prescaler, PLL postscaler, PLL divisor
PLLFBD = 20; // M = 22
CLKDIVbits.PLLPOST=0; // N2 = 2
CLKDIVbits.PLLPRE=0; // N1 = 2 Fosc = 40MHz => Fcy = 20MHz.
// Initiate Clock Switch to Internal FRC with PLL (NOSC = 0b001)
__builtin_write_OSCCONH(0x01);
__builtin_write_OSCCONL(0x01);
// Wait for Clock switch to occur
while (OSCCONbits.COSC!= 0b001);
// Wait for PLL to lock
while(OSCCONbits.LOCK!= 1) {};
Ta có hàm cai dặtd timer 1 như sau:
void Timer1init()
{
_TON = 0; //disable timer 1
_TCKPS = 3; //su dung bo chia tan 1:256
_TCS = 0; //su dung tan so noi
_TGATE = 0; //disable TGATE
TMR1 = 0; //reset register
PR1 = 39062; // set timer
_T1IP = 0x01; //dat muc uu tien
_T1IF = 0; //clear timer1 interrupt flag
_T1IE = 1; //cho phep ngat
_TON = 1; // enable timer1
}
Trong hàm ngắt timer 1: ta thực hiện đảo xung led:
void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void)
{
IFS0bits.T1IF = 0; // Clear Timer1 Interrupt Flag
_LATB5 = ~_LATB5;
}
Dùng ociiloscoper để đo xung tại chân led, ta sẽ được khoảng thời gian đảo xung ta 500ms = 0,5s
Hoàn thành!!
Nhận xét
Đăng nhận xét