View Full Version : xin hỏi về cách tính chính xác trong timer0 của pic18F4550
vagabondtt1503
05-02-2009, 05:31 PM
#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
...
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
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
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
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/viewtopic.php?t=29387&highlight=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
#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!
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.