Saturday, April 15, 2017

MCU - Bài 1: Ngắt TImer0 Trong Vi Điều Khiển 16F877A

Timer có chức năng rất quan trọng trong vi điều khiển. Chúng ta có thể tạo thời gian trễ rất chính xác dựa trên hệ thống xung clock.
Vi điều khiển 16F877A của hãng Microchip cũng được tích hợp đến 3 timer (Timer0, Timer1, và Timer2). Cách thức hoạt động của 3 timer này có phần khác nhau tôi xin giới thiệu lần lượt từng timer.
Để hiểu và sử dụng được các timer này điều hết sức cần thiết là các bạn cần có Datasheet của PIC 16F877A . Tải ở đây  http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf.

TIMER 0
I ) Đặc Tính:
  1. 8-bit timer/ counter
  2. Có thể đợc và ghi được
  3. Lựa chọn để sự dụng giữa xung nội 8Mhz và xung ngoại
  4. Ngắt tràn từ FFh tới 00h
để sự dụng được Timer0 ta cần khai báo các bit điều khiển trong thanh ghi OPTION_REG. 


hình 1
bit 6: INTEDG
bit 5: T0CS: lựa chọn nguồn xung cho timer. 
         -T0CS = 1 kích hoạt xung clock cho VDK từ chân RA4/T0CKI
         -T0CS = 0 kích hoạt xung clock nội CLK0 (=Fosc/4)
bit 4: T0SE: lựa chọn cạnh lên hay xuống của nguồn xung clock thạch anh trên chân T0CKI
         -T0SE = 1 High to Low
         -T0SE = 0 Low to High
bit 3: PSA chọn chế độ hoạt động của bộ Prescaler timer
         -PSA = 1 hệ số Prescaler PS2:PS0 được dùng cho bộ WDT thời gian thực
         -PSA = 0 hệ số Prescaler PS2:PS0 được dùng cho ứng dụng Timer
bit 2 -> 0: PS2:PS0 tỉ số Prescaler
       
hình 2
hình 3
II ) Ngắt Timer 0

Ta khai báo các bit trong thanh ghi INTCON để kích hoạt ngắt như sau:

hình 4
để kích hoạt ngắt timer 0 chỉ cần cài đặt các bit trong thanh ghi INTCON sau:
bit 7- GIE: ngắt toàn cục, bit này khi được kích lên 1 sẽ kích hoạt tất cả các ngắt trong VDK
bit 5- TMR0E =1 kích hoạt ngắt timer 0
bit 2- TMR0IF : khi ngắt timer 0 xảy ra khi thanh ghi tràn từ giá trị FFh về 00h, đặt giá trị đầu cho thanh ghi bất kỳ giá trị nào bạn muốn từ 0-255.

III ) Cách Tính Tần số Và Chu Kỳ Cho Timer 0

1 ) Công thức tính đối với chế độ xung clock ngoại

folk: giá trị thạch anh sử dụng
Prescale : đặt 3 bit PS2 PS1 PS0 theo bảng hình 2
TMR0: thanh ghi timer0 8 bit giá trị từ 0-255
count: được hiểu là mỗi lần tràn của timer0.

ví dụ: cho hệ số Prescale là 1:256, giá trị reset timer TMR0 =0 ta được tần số là 2Hz, chu Kỳ 0.5 giây,
số lần tràn để được tần số và chu kỳ như trên là 8 lần.


2 ) công thức tính đối với chế độ xung clock nội (8Mhz cho 16F877A)



Code mẫu thực được viết trên CCS:
file định nghĩa chân cho PIC 16F877A 

// register definitions

#define W 0
#define F 1

// register files
#byte INDF          =0x00
#byte TMR0          =0x01
#byte PCL           =0x02
#byte STATUS        =0x03
#byte FSR           =0x04
#byte PORTA         =0x05
#byte PORTB         =0x06
#byte PORTC         =0x07
#byte PORTD         =0x08
#byte PORTE         =0x09

#byte EEDATA        =0x10C
#byte EEADR         =0x10D
#byte EEDATH        =0x10E
#byte EEADRH         =0x10F
#byte ADCON0     =0x1F
#byte ADCON1     =0x9F
#byte ADRESH     =0x9F
#byte ADSESL     =0x9F

#byte PCLATH        =0x0a
#byte INTCON        =0x0b
#byte CCP1CON        =0x17
#byte CCP2CON        =0x1D
#byte CCPR1L      =0x15
#byte CCPR1H      =0x16
#byte CCPR2L      =0x1B
#byte CCPR2H      =0x1C
#byte T2CON    =0x12
#byte T1CON    =0x10
#byte PR2      =0x92
#byte TMR2     =0x11
#byte TMR1L    =0x0E
#byte TMR1H    =0x0F
#byte PIR1    =0x0c
#byte PIR2    =0x0d
#byte PIE1    =0x8c
#byte PIE2    =0x8d

#byte OPTION_REG    =0x81
#byte TRISA         =0x85
#byte TRISB         =0x86
#byte TRISC         =0x87
#byte TRISD         =0x88
#byte TRISE         =0x89

#byte EECON1        =0x18C
#byte EECON2        =0x18D

//DINH NGHIA BIT
#bit RA5   =0x05.5
#bit RA4   =0x05.4
#bit RA3   =0x05.3
#bit RA2   =0x05.2
#bit RA1   =0x05.1
#bit RA0   =0x05.0

#bit RB7   =0x06.7
#bit RB6   =0x06.6
#bit RB5   =0x06.5
#bit RB4   =0x06.4
#bit RB3   =0x06.3
#bit RB2   =0x06.2
#bit RB1   =0x06.1
#bit RB0   =0x06.0

#bit RC7   =0x07.7
#bit RC6   =0x07.6
#bit RC5   =0x07.5
#bit RC4   =0x07.4
#bit RC3   =0x07.3
#bit RC2   =0x07.2
#bit RC1   =0x07.1
#bit RC0   =0x07.0

#bit RD7   =0x08.7
#bit RD6   =0x08.6
#bit RD5   =0x08.5
#bit RD4   =0x08.4
#bit RD3   =0x08.3
#bit RD2   =0x08.2
#bit RD1   =0x08.1
#bit RD0   =0x08.0

#bit RE2   =0x09.2
#bit RE1   =0x09.1
#bit RE0   =0x09.0


#bit TRISA5   =0x85.5
#bit TRISA4   =0x85.4
#bit TRISA3   =0x85.3
#bit TRISA2   =0x85.2
#bit TRISA1   =0x85.1
#bit TRISA0   =0x85.0

#bit TRISB7   =0x86.7
#bit TRISB6   =0x86.6
#bit TRISB5   =0x86.5
#bit TRISB4   =0x86.4
#bit TRISB3   =0x86.3
#bit TRISB2   =0x86.2
#bit TRISB1   =0x86.1
#bit TRISB0   =0x86.0

#bit TRISC7   =0x87.7
#bit TRISC6   =0x87.6
#bit TRISC5   =0x87.5
#bit TRISC4   =0x87.4
#bit TRISC3   =0x87.3
#bit TRISC2   =0x87.2
#bit TRISC1   =0x87.1
#bit TRISC0   =0x87.0

#bit TRISD7   =0x88.7
#bit TRISD6   =0x88.6
#bit TRISD5   =0x88.5
#bit TRISD4   =0x88.4
#bit TRISD3   =0x88.3
#bit TRISD2   =0x88.2
#bit TRISD1   =0x88.1
#bit TRISD0   =0x88.0

#bit TRISE2   =0x89.2
#bit TRISE1   =0x89.1
#bit TRISE0   =0x89.0

// INTCON Bits for C
#bit gie    = 0x0b.7
#bit peie = 0x0b.6
#bit tmr0ie = 0x0b.5
#bit INTE = 0x0b.4
#bit RBIE = 0x0b.3
#bit tmr0if    = 0x0b.2
#bit INTF    = 0x0b.1
#bit rbif    = 0x0b.0
// timer 2 T2CON
#bit TOUTPS3    =0x12.6
#bit TOUTPS2    =0x12.5
#bit TOUTPS1    =0x12.4
#bit TOUTPS0    =0x12.3
#bit TMR2ON     =0x12.2
#bit T2CKPS1    =0x12.1
#bit T2CKPS0    =0x12.0
// timer 1 T1CON
#bit T1CKPS1    =0x10.5
#bit T1CKPS0    =0x10.4
#bit T1OSCEN    =0x10.3
#bit T1SYNC     =0x10.2
#bit TMR1CS     =0x10.1
#bit TMR1ON     =0x10.0
// PIR1 for C
#bit pspif  = 0x0c.7
#bit adif    = 0x0c.6
#bit rcif    = 0x0c.5
#bit txif    = 0x0c.4
#bit sspif    = 0x0c.3
#bit ccp1if    = 0x0c.2
#bit tmr2if    = 0x0c.1
#bit tmr1if    = 0x0c.0

//PIR2 for C
#bit cmif    = 0x0d.6
#bit eeif    = 0x0d.4
#bit bclif  = 0x0d.3
#bit ccp2if    = 0x0d.0

// PIE1 for C
#bit adie    = 0x8c.6
#bit rcie    = 0x8c.5
#bit txie    = 0x8c.4
#bit sspie    = 0x8c.3
#bit ccp1ie    = 0x8c.2
#bit tmr2ie    = 0x8c.1
#bit tmr1ie    = 0x8c.0

//PIE2 for C
#bit osfie    = 0x8d.7
#bit cmie    = 0x8d.6
#bit eeie   = 0x8d.4

// OPTION Bits
#bit not_rbpu   = 0x81.7
#bit intedg     = 0x81.6
#bit t0cs       = 0x81.5
#bit t0se       = 0x81.4
#bit psa        = 0x81.3
#bit ps2        = 0x81.2
#bit ps1        = 0x81.1
#bit ps0        = 0x81.0

// EECON1 Bits
#bit eepgd   = 0x18c.7
#bit free      = 0x18C.4
#bit wrerr     = 0x18C.3
#bit wren       = 0x18C.2
#bit wr         = 0x18C.1
#bit rd         = 0x18C.0
// CCP1CON REGISTER
#bit CCP1X   = 0x17.5
#bit CCP1Y   = 0x17.4
#bit CCP1M3   = 0x17.3
#bit CCP1M2   = 0x17.2
#bit CCP1M1   = 0x17.1
#bit CCP1M0   = 0x17.0
// CCP2CON REGISTER
#bit CCP2X   = 0x1D.5
#bit CCP2Y   = 0x1D.4
#bit CCP2M3   = 0x1D.3
#bit CCP2M2   = 0x1D.2
#bit CCP2M1   = 0x1D.1
#bit CCP2M0   = 0x1D.0
//ADCON0
#bit CHS0    =0x1F.3
#bit CHS1    =0x1F.4
#bit CHS2    =0x1F.5

#include <def_877A.h>
int8 count=0;
#INT_TIMER0
void  RTCC_isr(VOID){   
   count++;   
   TMR0 = 6;//sampling time (internal clock)=(256 - 6) * 4 * 100 * 2/ 8mhz = 25ms   
   IF (count == 100){      
      k = 1;      
      count = 0;   
   }   
   TMR0IF = 0;
}
void main(){
//=======================Set up Timer0 =======================//   
//OPTION_REG   
//prescaler   
   PS2 = 0;   
   PS1 = 0;   
   PS0 = 0;   
//Choose Timer mode (not WDT)   
   PSA = 0;   
//TMR0 Source CRYTAL   
   T0SE = 0; //Increment on low - to - high transition on T0CKI pin   
   T0CS = 0; //Transition on T0CKI pin / Internal instruction cycle clock (CLKO)  
//Timer0 Module REGISTER/ đặt giá trị đầu cho Timer0   
   TMR0 = 6; //initiation value   
//Interrupt Timer 0
   TMR0IE = 1;
//=========================== Global interrupt ==========================//
   PEIE = 1; //Peripheral Interrupt Enable bit
   GIE = 1;  //Global Interrupt Enable bit
while (1){
   if (k == 1) {
     //code thuc thi
     k=0;
   }
` }
}
  

Còn tiếp ...

No comments:

Post a Comment