PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Hỏi về timer0,1,2 của pic16f877A? (http://www.picvietnam.com/forum/showthread.php?t=1242)

dvnccbmacbt 02-07-2007 11:41 PM

Hỏi về timer0,1,2 của pic16f877A?
 
Em chưa hiểu về cơ chế hoạt động của timer2 trong con pic16f877A.
Có bác nào giải thích giúp em với. Em dùng CCS C. Cụ thể như thế này. Nạp một giá trị ban đầu ( period ) cho nó và giá trị ( postscale ). Qua trình làm việc nó xử lý với 2 giá trị này này như thế nào? Có phải nó cũng bắt đầu đếm từ period đến 255, tràn và tiếp tục đếm từ period đến 255 và tràn cho đến khi nào số lần tràn bằng số postscale thì ngắt. Khi ngắt thì ta cũng thiết lập lại giá trị timer2 trong hàm ngắt.? Em hiểu như vậy có đúng không, các bác chỉ bảo cho?

Cho em hỏi thêm : Chế độ đếm đồng bộ và không đồng bộ ở timer1 là như thế nào? Em không hiểu gì cả? Chế độ đếm của timer0 là đồng bộ hay không đồng bộ? Các bác giúp em với. Cảm ơn các bác nhiều!

nhh 03-07-2007 05:25 AM

1 Attachment(s)
Bạn xem chương trình đây thì rõ, lâu quá rồi, ko tìm thấy link cũ.

Jerry 04-07-2007 04:35 PM

Timer 2 có 2 thanh ghi là PR2 và TMR2.
Khi chức năng timer của Timer2 được kích hoạt thì thanh ghi TMR2 sẽ đếm từ 0 cho đến khi "khớp" với giá trị đặt trước trong thanh ghi PR2 thì tràn. Lúc này nếu cho phép ngắt timer2 thì sẽ xảy ra 1 ngắt.

Hoạt động của timer2 còn liên quan đến prescaler và postscaler. Để cho bạn hiểu 1 cách đơn giản nhất thì có thể nói prescaler và postscaler là 1 hệ số nhân. timer 2 sẽ ngắt sau 1 khoảng thời gian = PR2*prescaler*postscaler. Ví dụ: PR2 = 124 (dec); prescaler = 10 (dec); postscaler = 16 (dec) thì timer2 sẽ tràn sau 1 khoảng thời gian là 124*10*16 = 19840 us (micro second)

dvnccbmacbt 05-07-2007 11:10 AM

to Jerry: Cảm ơn bạn nhiều. cho mình hỏi thêm. Mình dùng CCS C. Câu lệnh set_timer2(value); có ý nghĩa gì? Giá trị value này được đưa và thanh ghi PR2 phải không?
Code:

3.Timer2

Thanh ghi tác động:

Các lệnh:

       
Code:

       
setup_TIMER_2(mode, period, postscale);
set_TIMER2(value);                // xác định giá trị ban đầu (8bit) cho Timer2
get_TIMER2();                      // trả về số nguyên  8bit


Với mode gồm (co the ket hop bang dau "|"):

T2_DISABLED
T2_DIV_BY_1
T2_DIV_BY_4
T2_DIV_BY_16

period là số nguyên từ 0-255, xác định giá trị xung reset
postscale là số nguyên 1-16, xác định reset bao nhiêu lần trước khi ngắt.


Jerry 07-07-2007 04:50 PM

Lệnh set_TIMER2(value) chính là lệnh đặt giá trị cho PR2. Mình ít viết chương trình bằng C lắm. ASM thì mình thạo hơn. Cũng nhờ ASM nên mình hiểu khá kỹ về cấu trúc phần cứng của vi điều khiển PIC. Viết bằng C thì không hiểu nhiều về phần cứng đâu, tuy nhiên C có lợi thế khi xây dựng những project lớn

KHACTHO 04-12-2008 07:14 PM

cho em hoi ve cái set_timer0(6)có ý nghĩa như thê nao mong cac bac giúp đơ.em cam on nhieu nha

tungtot_vl 05-12-2008 02:18 PM

pic
 
Trích:

Nguyên văn bởi KHACTHO (Post 21152)
cho em hoi ve cái set_timer0(6)có ý nghĩa như thê nao mong cac bac giúp đơ.em cam on nhieu nha

set_timer0(6) là thiết lập giá trị đếm ban đầu của timer. khi đó biến đếm bắt đầu đếm từ 6 cho đến 255 thì tràn và nhảy vào ngắt, sau khi ngắt xong lại quay về giá trị đếm ban đầu là 6 để đếm tiếp

lequocbao 06-12-2008 11:35 AM

Vậy là muốn sử dụng timer0 thì mình chỉ cần:
setup_TIMER_2(mode, period, postscale);
khi gặp câu lệnh:
set_TIMER2(value);
là timer 0 sẽ bắt đầu đếm phải không bạn?

Cho mình hỏi luôn là mình sử dụng thạch anh 4Mhz mà muốn tính số lần ngắt trên 1s thì mình phải tính như thế nào?(mục đích là mình muốn khi kích hoạt timer0 sau 1s thì mình sẽ làm việc khác đó mà!)
Mình có tham khảo trong mục help(mình sử dụng ccs c) thì với thạch anh 20Mhz thì số lần ngắt trên 1s là 76 nhưng mình không hiểu lắm về cách tính ra con số 76.Đại khái là:
20000000/(4*256*256) =76

thanhviet 06-12-2008 12:31 PM

cac bac nao giai thich dum cach chon TMOD trong 8051 dc ko , minh ko hieu o cho 20,02 ,10,01 ,13...vd:
MOV TMOD,#02( minh hieu la timer0 ,che do 2 roi) ,nhung con cai nay thi sao
MOV TMOD,#20(Cac so khac nh:10,01,13,

lequocbao 06-12-2008 04:35 PM

Hỏi ở đây thì hơi bị lộn tiệm rồi đó nha!
Nhưng đang rãnh nên khuyến mãi luôn.
vd:
20 có nghĩa là 00100000 binary đó bạn.
thì tương ứng thanh ghi Tmod sẽ có 8bit : 4 bit cao dành cho timer0 và 4 bit thấp dành cho timer1(có thể ngược lại ,mình không nhớ chính xác)
4 bit đó là:CT\ , GATE,M0,M1.
CT\:hình như là chọn chức năng timer hay là counter gì đó.
GATE:quên chức năng của bit này rồi(pác nào nhớ nhắc hộ)
M0,M1:chọn chế độ cho timer.(có 4 chế độ)

Tóm lại là từng bit 1 có chức năng cụ thể.Nếu bạn muốn hiểu rõ thêm thì hôm sau mình tìm được tài liệu sẽ trả lời đầy đủ hơn.
Tại tài liệu để đâu không nhớ tìm chưa ra nên có cái nhớ cái không. bạn thông cảm hì hì...

trungduc 07-12-2008 10:41 AM

Dùng timer0 làm counter ?
 
Xin chào mọi người !
Tôi đang tìm hiểu về timer, cụ thể là dùng timer0 làm counter ( bsf option_reg,t0cs ) thế nhưng quan sát LED thì nó cứ đếm từ 0 -> 255 mà chẳng quan tâm gì đến nút nhấn ở chân RA4 (16f877a). Anh em nào có đoạn code kiểu này cho mình tham khảo với. Mình chỉ biết ASM thôi.
Xin cảm ơn!

tungtot_vl 07-12-2008 05:33 PM

pic
 
Trích:

Nguyên văn bởi lequocbao (Post 21194)
Vậy là muốn sử dụng timer0 thì mình chỉ cần:
setup_TIMER_2(mode, period, postscale);
khi gặp câu lệnh:
set_TIMER2(value);
là timer 0 sẽ bắt đầu đếm phải không bạn?

Cho mình hỏi luôn là mình sử dụng thạch anh 4Mhz mà muốn tính số lần ngắt trên 1s thì mình phải tính như thế nào?(mục đích là mình muốn khi kích hoạt timer0 sau 1s thì mình sẽ làm việc khác đó mà!)
Mình có tham khảo trong mục help(mình sử dụng ccs c) thì với thạch anh 20Mhz thì số lần ngắt trên 1s là 76 nhưng mình không hiểu lắm về cách tính ra con số 76.Đại khái là:
20000000/(4*256*256) =76

ngắt 1s
#include <16F877A.h>
#device 18F4680*=16 ADC=10
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(c)
#byte portc=0x07
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void timer0()
{
set_timer0(56); // T = 2*(256 - 56)*1us = 400us (nếu dùng thạch anh 20M thi thay 1us thành 0,2us)
++count;
if(count == 2500) // 2500*400us = 1000000us = 1s
{
count=0;
rotate_left(&a,1);
}
}
//Chuong trinh dich led
void main()
{ set_tris_c(0);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
enable_interrupts(global);

a = 0x01;
while(true)
{
portc = a;
}
}

tungtot_vl 07-12-2008 05:33 PM

pic
 
tự tìm hiểu nhé

KHACTHO 09-12-2008 11:24 AM

Trích:
Nguyên văn bởi lequocbao View Post
Vậy là muốn sử dụng timer0 thì mình chỉ cần:
setup_TIMER_2(mode, period, postscale);
khi gặp câu lệnh:
set_TIMER2(value);
là timer 0 sẽ bắt đầu đếm phải không bạn?

Cho mình hỏi luôn là mình sử dụng thạch anh 4Mhz mà muốn tính số lần ngắt trên 1s thì mình phải tính như thế nào?(mục đích là mình muốn khi kích hoạt timer0 sau 1s thì mình sẽ làm việc khác đó mà!)
Mình có tham khảo trong mục help(mình sử dụng ccs c) thì với thạch anh 20Mhz thì số lần ngắt trên 1s là 76 nhưng mình không hiểu lắm về cách tính ra con số 76.Đại khái là:
20000000/(4*256*256) =76
ngắt 1s
#include <16F877A.h>
#device 18F4680*=16 ADC=10
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(c)
#byte portc=0x07
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void timer0()
{
set_timer0(56); // T = 2*(256 - 56)*1us = 400us (nếu dùng thạch anh 20M thi thay 1us thành 0,2us)
++count;
if(count == 2500) // 2500*400us = 1000000us = 1s
{
count=0;
rotate_left(&a,1);
}
}
//Chuong trinh dich led
void main()
{ set_tris_c(0);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
enable_interrupts(global);

a = 0x01;
while(true)
{
portc = a;
}
}
tungtot_vl vẫn chưa có mặt trong diễn đàn
NHƯ VẬY CON SỐ 2 Ở (T=2*(256-56)*1US)Ơ ĐÂU RA VẬY

gghh 09-12-2008 07:04 PM

hi
 
delay 1s dùng thạch anh 4Mhz
Code:

#INCLUDE<16F877A.H>
#INCLUDE<DEF_16F877A.H>
#USE DELAY(CLOCK=4000000)
#INT8  H;
#INT_TIMER1
VOID NGAT_TIMER1()
{
  SET_TIMER1(15536);
  H++;
  IF(H==20)  //20*50000us = 1000000us = 1s
  {
      lệnh;
      H=0;
  }
}
void main()
{
  SETUP_TIMER_1(T1_INTERNAL);
  ENABLE_INTERRUPTS(GLOBAL);
  ENABLE_INTERRUPTS(INT_TIMER1);
  SET_TIMER1(15536);      //T_dinhthoi = (65536-15536)*1us = 50000us
  while(1)
  {
    lệnh;
    }
}



Múi giờ GMT. Hiện tại là 10:43 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam