PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   Ai rành timer giải đáp giùm mình vấn đề này? (http://www.picvietnam.com/forum/showthread.php?t=31745)

qloi 30-01-2013 05:49 PM

Ai rành timer giải đáp giùm mình vấn đề này?
 
Code:

#include <16f88.h>
#fuses intrc,nomclr,nowdt
#use delay(clock=4000000)
#bit dout = 5.0

int a,i=0;

#int_timer0
void pwm()
{
  set_timer0(245);
  if(i<a) {R=0;}
  else R=1;
  i++;
  if(i==100) i=0; 
}

void main()
{
  set_tris_a(0);
  enable_interrupts(global);
  enable_interrupts(int_timer0);
  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
  set_timer0(245);
  while(1)
  {
        a=10;
        delay_ms(2000);
        a=100;
        delay_ms(2000);
  }

chương trình chỉ đơn giản là điều biến xung. vấn đề năm ở chổ t không hiểu tại sao với tính toán như trên: t(tràn) = (4/4000000)*2*10 = 20us ; và khi hoàn thành hết 100% khoảng xung trong hàm ngắt là: 20us*100=2ms ~ 500Hz nhưng khi mô phỏng và chạy trên mạch thật đều bị chung 1 vấn đề là F đầu ra khoảng 7-8Hz thôi(có khi dừng hẳn không có xung ở đầu ra). khi t bỏ hàm set_timer(245) tở đầu hàm ngắt thì coi như t(tràn)=(4/4000000)*2*256*100=0.05s ~ 20Hz và xung out xấp xỉ đúng như tính toán. Sau đó t đổi lại hệ số presc=8 và vẫn giữ hàm set_timer0(245) như lúc đầu thì mạch xuất xung hoàn toàn đúng t(tràn) = (4/4000000)*8*10*100=8ms ~100Hz.khi bị lỗi như trường hợp đầu thì t theo dõi thấy trong vòng lặp while ban đầu cho a=10,và hàm delay_ms(2000) không còn đúng nữa (trở nên rất dài khoảng vài phút hoặc không thay chạy nữa y như vdk bị treo khi gặp delay vậy). các bác cho mình hỏi vì sao trên lý thuyết tính toán vậy mà lại không chạy đúng trong khi thay đổi hệ số prescaler cao lên thì đúng. có thể là ngắt xảy ra quá nhanh nó đáp ứng không kịp chăng?

pstin 30-01-2013 07:03 PM

Cái code của bạn hình như có vấn đề...
Bạn nên dùng các "sọt" PWM trên diễn đàn!.
Đối với dao động nội, dễ bị sai số, không đúng,..
Trong CCS thêm lệnh:
setup_oscillator(OSC_4MHZ);
Đối với PWM PIC6F88 thì dùng Timer 2, dùng pin CCP1.
Dùng chân khác và timer0...chạy không đúng là "có lý"!..

bnthang 30-01-2013 08:46 PM

Trích:

Nguyên văn bởi qloi (Post 80736)
Code:

#include <16f88.h>
#fuses intrc,nomclr,nowdt
#use delay(clock=4000000)
#bit dout = 5.0

int a,i=0;

#int_timer0
void pwm()
{
  set_timer0(245);
  if(i<a) {R=0;}
  else R=1;
  i++;
  if(i==100) i=0; 
}

void main()
{
  set_tris_a(0);
  enable_interrupts(global);
  enable_interrupts(int_timer0);
  setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
  set_timer0(245);
  while(1)
  {
        a=10;
        delay_ms(2000);
        a=100;
        delay_ms(2000);
  }

chương trình chỉ đơn giản là điều biến xung. vấn đề năm ở chổ t không hiểu tại sao với tính toán như trên: t(tràn) = (4/4000000)*2*10 = 20us ; và khi hoàn thành hết 100% khoảng xung trong hàm ngắt là: 20us*100=2ms ~ 500Hz nhưng khi mô phỏng và chạy trên mạch thật đều bị chung 1 vấn đề là F đầu ra khoảng 7-8Hz thôi(có khi dừng hẳn không có xung ở đầu ra). khi t bỏ hàm set_timer(245) tở đầu hàm ngắt thì coi như t(tràn)=(4/4000000)*2*256*100=0.05s ~ 20Hz và xung out xấp xỉ đúng như tính toán. Sau đó t đổi lại hệ số presc=8 và vẫn giữ hàm set_timer0(245) như lúc đầu thì mạch xuất xung hoàn toàn đúng t(tràn) = (4/4000000)*8*10*100=8ms ~100Hz.khi bị lỗi như trường hợp đầu thì t theo dõi thấy trong vòng lặp while ban đầu cho a=10,và hàm delay_ms(2000) không còn đúng nữa (trở nên rất dài khoảng vài phút hoặc không thay chạy nữa y như vdk bị treo khi gặp delay vậy). các bác cho mình hỏi vì sao trên lý thuyết tính toán vậy mà lại không chạy đúng trong khi thay đổi hệ số prescaler cao lên thì đúng. có thể là ngắt xảy ra quá nhanh nó đáp ứng không kịp chăng?

Nếu bạn muốn điều rộng xung thì tốt nhất nên dùng modul pwm trong pic, nếu dùng timer thì bạn phải tính tới thời gian thực hiện các dòng lệnh,if else,....các dòng lệnh này cũng mất thời gian, để xác định chính xác thời gian bạn cần xem file asm được dịch từ file .c hoặc dùng oscilloscope để đo xung out.

qloi 31-01-2013 10:32 AM

Trích:

Nguyên văn bởi pstin (Post 80738)
Cái code của bạn hình như có vấn đề...
Bạn nên dùng các "sọt" PWM trên diễn đàn!.
Đối với dao động nội, dễ bị sai số, không đúng,..
Trong CCS thêm lệnh:
setup_oscillator(OSC_4MHZ);
Đối với PWM PIC6F88 thì dùng Timer 2, dùng pin CCP1.
Dùng chân khác và timer0...chạy không đúng là "có lý"!..

ý mình không phải là điều rộng xung. vấn đề nằm ở chổ timer chạy không đúng! nếu giả sử không đem ứng dụng trong điều rộng xung mà đem quét led 7 đoạn bằng timer chẳng hạn thì nếu đúng với hàm trên thị lẻ ra tần số quét của nó là 500hz nhưng nó lại chỉ ra 10 mấy hz nghĩa là led sẽ nháy rất dữ(do mỗi khi tràn và thực hiện hàm ngắt t=(4/4e6)*2*255*100 ~19hz) ngay cả khi sài thạch anh ngoài cũng thế nên không thể do sai số dao động nội được. nếu bỏ hàm set_timer0(245) zô thì đáng lý ra nó phải chạy đúng mà đằng này nó treo không chạy timer nữa mới lạ chứ!.nhưng khi mình thay bộ chia pre=8 và tính lại thì vẫn với tần số và code như trên thì mạch chạy ngon lành?chả hiểu tại sao bác àh

qloi 31-01-2013 02:44 PM

Trích:

Nguyên văn bởi bnthang (Post 80741)
Nếu bạn muốn điều rộng xung thì tốt nhất nên dùng modul pwm trong pic, nếu dùng timer thì bạn phải tính tới thời gian thực hiện các dòng lệnh,if else,....các dòng lệnh này cũng mất thời gian, để xác định chính xác thời gian bạn cần xem file asm được dịch từ file .c hoặc dùng oscilloscope để đo xung out.

tất nhiên là t có tính đến thời gian thực thi trể do thực hiện các lệnh, như trong hàm ngắt trên thì thực hiện không quá 20us trong khi chu kỳ xuất xung tính toán vào khoảng 2ms , quá nhỏ so với 2ms này cho nên tần số ra sai có thể chấp nhận trong khoảng vài chục hz là chuyện thường nhưng ở đây là sai chỉ có vài hz nên không thể do những lệnh đó được bạn àh.rỏ ràng mình thấy lỗi ở chổ gọi hàm set_timer0(245); là không có tác dụng vì khi ngắt xảy ra thì ở hàm phục vụ ngắt thanh ghi timer0 phải được set về giá trị khởi tạo là 245 là nó không làm nên mới dẫn tới sai số rất lớn nhưng mình k hiểu vì sao nó lại không thực thi được hàm này ở bộ chia 2???


Múi giờ GMT. Hiện tại là 04:14 PM.

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