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)
-   -   xin hỏi về cách tính chính xác trong timer0 của pic18F4550 (http://www.picvietnam.com/forum/showthread.php?t=3500)

vagabondtt1503 05-02-2009 05:31 PM

xin hỏi về cách tính chính xác trong timer0 của pic18F4550
 
Code:

#include <18F4550.h>
#fuses nomclr,HSPLL,PLL5,CPUDIV2
#use delay(clock=48000000)
#include <lcd_lib_4bit.c>


int16 i = 0;
int16 time = 0;
void init()
{
  SET_TRIS_B(0xFF );
  LCD_init();

   


#INT_TIMER0
void TIMER0_isr(void)
{
        Set_timer0(34286); //vấn đề ở đây,mong được giúp đỡ
        time++;
        LCD_PutCmd(0x01);
        Printf(LCD_putchar," %Lu  ",time);
   

}
void main()
{
  init();
  //Printf(LCD_putchar,"welcome");
 
 SETUP_TIMER_0(RTCC_DIV_256);
 enable_interrupts(INT_TIMER0);
 enable_interrupts(GLOBAL);
 
  while(TRUE)
  {
       
         
     
  }
 

}

mình dùng pic18f4550,dùng timer0 để đếm thời gian nhưng không cách nào đếm chính xác được

Đoạn code trên dùng để đếm thời gian trong 1s,công thức tính overflow timer0 theo mình được biết (tính theo trường hợp trên )

1.bộ chia timer0 mình sử dụng là 1:256
2.chu kỳ lệnh là 4/48 000 000
3.bộ đếm timer sử dụng 16 bit(2^16 = 65536 )

Set_timer0(a);

công thức tính a để timer tràn sau 1 giây theo mình được biết là :

256 * (65536 - a) * 4 / 48 000 000 = 1 (s)
---> a = 18661

nhưng khi set_timer với giá trị 18661 khi test thử ở mạch thật thì chậm hơn hẳn 2/3 so với thời gian thực,sau đó chỉnh lại a = 34286 (như code ở trên) thì đếm đúng 1s,nhưng như vậy thì công thức tính overflow của timer bị sai so với lý thuyết

Mong các bạn giúp mình công thức đúng để áp dụng các trừong hợp khác tốt hơn

Xin chân thành cảm ơn

namqn 05-02-2009 07:48 PM

Trích:

Nguyên văn bởi vagabondtt1503 (Post 22398)
...
mình dùng pic18f4550,dùng timer0 để đếm thời gian nhưng không cách nào đếm chính xác được

Đoạn code trên dùng để đếm thời gian trong 1s,công thức tính overflow timer0 theo mình được biết (tính theo trường hợp trên )

1.bộ chia timer0 mình sử dụng là 1:256
2.chu kỳ lệnh là 4/48 000 000
3.bộ đếm timer sử dụng 16 bit(2^16 = 65536 )

Set_timer0(a);

công thức tính a để timer tràn sau 1 giây theo mình được biết là :

256 * (65536 - a) * 4 / 48 000 000 = 1 (s)
---> a = 18661

nhưng khi set_timer với giá trị 18661 khi test thử ở mạch thật thì chậm hơn hẳn 2/3 so với thời gian thực,sau đó chỉnh lại a = 34286 (như code ở trên) thì đếm đúng 1s,nhưng như vậy thì công thức tính overflow của timer bị sai so với lý thuyết

Mong các bạn giúp mình công thức đúng để áp dụng các trừong hợp khác tốt hơn

Xin chân thành cảm ơn

Thạch anh mà bạn sử dụng ở mạch thật có tần số bao nhiêu?

Thân,

vagabondtt1503 05-02-2009 07:53 PM

Trích:

Nguyên văn bởi namqn (Post 22402)
Thạch anh mà bạn sử dụng ở mạch thật có tần số bao nhiêu?

Thân,

Tần số thạch anh em sử dụng là 20MHz,thx anh

namqn 05-02-2009 08:03 PM

Trích:

Nguyên văn bởi vagabondtt1503 (Post 22403)
Tần số thạch anh em sử dụng là 20MHz,thx anh

Thạch anh 20 MHz thì bạn dùng PLL5 là đúng rồi, khi đó tần số ngõ vào của PLL là 4 MHz. Tôi cho là bạn nên xem lại giá trị CPUDIV2. Theo tính toán của tôi, nếu a = 34286 tương ứng với thời gian 1 giây thì tần số xung nhịp của PIC sẽ là 32 MHz. Do đó, tôi cho rằng giá trị cấu hình CPUDIV2 trong CCS C sẽ ứng với tần số xung nhịp = 96 MHz / 3 (chứ không phải là 96 MHz / 2 như bạn đang nghĩ). Bạn hãy kiểm tra lại xem.

Thân,

vagabondtt1503 05-02-2009 09:08 PM

cảm ơn anh đã trả lời,em sẽ kiểm tra lại

vagabondtt1503 05-02-2009 09:28 PM

sau khi kiểm tra lại thì trong help của CCS C có ghi rõ là CPUDIV2 : System Clock by 2.tức là vẫn chia 2.kiểm tra trên mạch thật thì cấu hình như trên thì 32Mhz chỉ đúng trong trường hợp tràn timer sau 1 giây.hix.Mong nhận được sự giúp đỡ của mọi người

namqn 05-02-2009 10:22 PM

Trích:

Nguyên văn bởi vagabondtt1503 (Post 22409)
sau khi kiểm tra lại thì trong help của CCS C có ghi rõ là CPUDIV2 : System Clock by 2.tức là vẫn chia 2.kiểm tra trên mạch thật thì cấu hình như trên thì 32Mhz chỉ đúng trong trường hợp tràn timer sau 1 giây.hix.Mong nhận được sự giúp đỡ của mọi người

Vì tôi không dùng CCS C (ngay cả cài bản demo bây giờ cũng không dùng được, vì đã hết thời gian dùng thử), nên bạn đọc luồng sau trong diễn đàn của CCS C, theo đó, CPUDIV1 mới ứng với 48 MHz (tức là 96 MHz / 2):
http://www.ccsinfo.com/forum/viewtop...ghlight=cpudiv

Bạn xem thêm Register 25-1 (mục 25.1) trong datasheet của PIC18F4550, phần tương ứng với chế độ HSPLL. Theo tôi, CPUDIV2 tương ứng với <CPUDIV1:CPUDIV0> = '01' (96 MHz / 3), còn CPUDIV1 tương ứng với <CPUDIV1:CPUDIV0> = '00' (96 MHz / 2).

Bạn cứ thử với CPUDIV1 và a = 18661 xem.

Thân,

vagabondtt1503 06-02-2009 01:55 AM

cảm ơn anh đã giúp đỡ

headman8x 15-05-2011 03:26 AM

Pic8f4550
 
Trích:

Nguyên văn bởi vagabondtt1503 (Post 22398)
Code:

#include <18F4550.h>
#fuses nomclr,HSPLL,PLL5,CPUDIV2
#use delay(clock=48000000)
#include <lcd_lib_4bit.c>


int16 i = 0;
int16 time = 0;
void init()
{
  SET_TRIS_B(0xFF );
  LCD_init();

   


#INT_TIMER0
void TIMER0_isr(void)
{
        Set_timer0(34286); //vấn đề ở đây,mong được giúp đỡ
        time++;
        LCD_PutCmd(0x01);
        Printf(LCD_putchar," %Lu  ",time);
   

}
void main()
{
  init();
  //Printf(LCD_putchar,"welcome");
 
 SETUP_TIMER_0(RTCC_DIV_256);
 enable_interrupts(INT_TIMER0);
 enable_interrupts(GLOBAL);
 
  while(TRUE)
  {
       
         
     
  }
 

}

mình dùng pic18f4550,dùng timer0 để đếm thời gian nhưng không cách nào đếm chính xác được

Đoạn code trên dùng để đếm thời gian trong 1s,công thức tính overflow timer0 theo mình được biết (tính theo trường hợp trên )

1.bộ chia timer0 mình sử dụng là 1:256
2.chu kỳ lệnh là 4/48 000 000
3.bộ đếm timer sử dụng 16 bit(2^16 = 65536 )

Set_timer0(a);

công thức tính a để timer tràn sau 1 giây theo mình được biết là :

256 * (65536 - a) * 4 / 48 000 000 = 1 (s)
---> a = 18661

nhưng khi set_timer với giá trị 18661 khi test thử ở mạch thật thì chậm hơn hẳn 2/3 so với thời gian thực,sau đó chỉnh lại a = 34286 (như code ở trên) thì đếm đúng 1s,nhưng như vậy thì công thức tính overflow của timer bị sai so với lý thuyết

Mong các bạn giúp mình công thức đúng để áp dụng các trừong hợp khác tốt hơn

Xin chân thành cảm ơn

Bạn vagabondtt1503 thân mến .
theo mình thì công thức tính như trên là đúng rồi.
bạn nên đăt fuses bits như sau với thạch anh 20Mhz :
#FUSES HSPLL,PLL5 ,CPUDIV1,...tùy chọn sẽ cho kết quả chính xác 1 giây.
công thức tính thời gian ngắt tràn timer0 ở chế độ 16 bits.
Overflow time = 4 x TOSC x Prescaler x(65535 - TMR0) .

với tần số thạch anh ngoài là 20Mhz thì Tosc = 1/20000000 = 0.05 us.
như vậy nếu dùng timer0 ở chế độ 16 bits thì :
Overflow timer = 4*0.05 * 256 *( 65535-set_timer0(a) ) = ??
a= 46000 ==>> Overflow time= 51.2*(65535-46000) = 999936 us =1 sec.


thân chào!


Múi giờ GMT. Hiện tại là 04:24 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