PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 18-04-2009, 11:43 AM   #1
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Giúp em về timer0 với.

Em sử dụng code của anh nhh,với mục đích là "led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi."
Đây là đoạn code:
Code:
#include <16F887.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
   set_timer0(6);
   ++count;
   if(count == 2000)   // 2000*500us = 1000000us = 1s
      {
         count=0;
         rotate_left(&a,1);
      }
}
//Chuong trinh chinh
void main(void)
{
   set_tris_b(0);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); 
   enable_interrupts(global);
   set_timer0(6);// T_dinhthi =delay= 2*(256 - 6)*1us = 500us
//INitTIMER0=6;prescaler=2(do RTCC_div_2
   a = 0x01;
   
   while(true)
   {
      PORTB = a;
   }
}
Nhưng khi mô phỏng thì thấy thời gian không đúng.Chậm hơn 1s nhiều mặc dù đã set tần số của MPlab =tần số khai báo trong chương trình.
Trong chương trình đã tính đựoc thời gian định thì =500us.Cái này có ý nghĩa như thế nào vậy?
TRong chương trình ngắt của timer0 cũng lại gặp dòng lệnh này nữa.DÒng lệnh trong chương trình ngắt này có ý nghĩa gì không?Có bắt buộc là set_timer0(6); giống như trong chuơng trình main()?
Đang rất rối,hy vọng được giúp đỡ.Rất cảm ơn.HIc
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 19-04-2009, 10:54 PM   #2
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Sao không ai chỉ dùm cái?
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-04-2009, 11:12 AM   #3
mtuankct
Đệ tử 6 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 125
:
Trích:
Nguyên văn bởi thaithien View Post
Em sử dụng code của anh nhh,với mục đích là "led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi."
Đây là đoạn code:
Code:
#include <16F887.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
   set_timer0(6);
   ++count;
   if(count == 2000)   // 2000*500us = 1000000us = 1s
      {
         count=0;
         rotate_left(&a,1);
      }
}
//Chuong trinh chinh
void main(void)
{
   set_tris_b(0);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); 
   enable_interrupts(global);
   set_timer0(6);// T_dinhthi =delay= 2*(256 - 6)*1us = 500us
//INitTIMER0=6;prescaler=2(do RTCC_div_2
   a = 0x01;
   
   while(true)
   {
      PORTB = a;
   }
}
Nhưng khi mô phỏng thì thấy thời gian không đúng.Chậm hơn 1s nhiều mặc dù đã set tần số của MPlab =tần số khai báo trong chương trình.
Trong chương trình đã tính đựoc thời gian định thì =500us.Cái này có ý nghĩa như thế nào vậy?
TRong chương trình ngắt của timer0 cũng lại gặp dòng lệnh này nữa.DÒng lệnh trong chương trình ngắt này có ý nghĩa gì không?Có bắt buộc là set_timer0(6); giống như trong chuơng trình main()?
Đang rất rối,hy vọng được giúp đỡ.Rất cảm ơn.HIc
Thời gian trong các chương trình mô phỏng rất có thể không chính xác vì nó không có tính thời gian thực.
Còn nếu delay sử dụng timer thì hoàn toàn có thể tạo được các hàm delay gần như chính xác.
500us là thời gian tràn của timer
muốn tạo ra khoảng thời gian 1s thì timer phải tràn 2000 lần
Giá trị đặt set_timer0(6); là đặt giá trị ban đầu vào timer để trong mỗi chu kỳ thì timer chỉ đếm từ 6 đến 255.
Trong mỗi hàm ngắt thì phải đặt lại giá trị này để đạt được các khoảng thời gian giống nhau cho tất cả các hàm ngắt.
mtuankct vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-04-2009, 09:53 PM   #4
mabubeo22
Nhập môn đệ tử
 
Tham gia ngày: Mar 2009
Bài gửi: 3
:
Trích:
Nguyên văn bởi thaithien View Post
Em sử dụng code của anh nhh,với mục đích là "led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi."
Đây là đoạn code:
Code:
#include <16F887.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
   set_timer0(6);
   ++count;
   if(count == 2000)   // 2000*500us = 1000000us = 1s
      {
         count=0;
         rotate_left(&a,1);
      }
}
//Chuong trinh chinh
void main(void)
{
   set_tris_b(0);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); 
   enable_interrupts(global);
   set_timer0(6);// T_dinhthi =delay= 2*(256 - 6)*1us = 500us
//INitTIMER0=6;prescaler=2(do RTCC_div_2
   a = 0x01;
   
   while(true)
   {
      PORTB = a;
   }
}
Nhưng khi mô phỏng thì thấy thời gian không đúng.Chậm hơn 1s nhiều mặc dù đã set tần số của MPlab =tần số khai báo trong chương trình.
Trong chương trình đã tính đựoc thời gian định thì =500us.Cái này có ý nghĩa như thế nào vậy?
TRong chương trình ngắt của timer0 cũng lại gặp dòng lệnh này nữa.DÒng lệnh trong chương trình ngắt này có ý nghĩa gì không?Có bắt buộc là set_timer0(6); giống như trong chuơng trình main()?
Đang rất rối,hy vọng được giúp đỡ.Rất cảm ơn.HIc


theo ý kiến của mình thì bạn nên sửa đoạn if (count==2000) thay bằng if (count>=2000)
lý do là ban đầu chưa khởi tạo count=0 vì vậy trong quá trình hoạt động rất có thể count đã >2000 (ví dụ 2001), như vậy với int16 count thì count bạn cứ chạy tiếp tới hơn 65 nghìn rồi mới quay lại

như vậy khả năng gây trễ do cái này
mabubeo22 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-04-2009, 01:00 AM   #5
mtuankct
Đệ tử 6 túi
 
Tham gia ngày: Apr 2006
Bài gửi: 125
:
@mabubeo22: đúng là nên khởi tạo các giá trị ban đầu cho các biến tuy nhiên với biến thuộc Ram thì giá trị ban đầu theo mình là luôn bằng 0
mtuankct vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-04-2009, 10:22 AM   #6
cskiller
Đệ tử 4 túi
 
Tham gia ngày: Aug 2008
Bài gửi: 89
:
Trích:
Nguyên văn bởi thaithien View Post
Code:
#include <16F887.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
   set_timer0(6);
   ++count;
   if(count == 2000)   // 2000*500us = 1000000us = 1s
      {
         count=0;
         rotate_left(&a,1);
      }
}
//Chuong trinh chinh
void main(void)
{
   set_tris_b(0);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); 
   enable_interrupts(global);
   set_timer0(6);// T_dinhthi =delay= 2*(256 - 6)*1us = 500us
//INitTIMER0=6;prescaler=2(do RTCC_div_2
   a = 0x01;
   
   while(true)
   {
      PORTB = a;
   }
}
Bạn tính thời gian thì ok nhưng lệnh set giá trị timer0 hoàn toàn không thực thi và đồng bộ trong thời gian 1 chu kỳ(1us) nên dẫn đến chương trình bị trễ do cộng dồn 2000 lần ngắt.


Giá trị của biến toàn cục ko được khởi tạo giá trị ban đầu thường bằng 0 khi chip power on lần đầu và bằng giá trị lần cuối được gán nếu chỉ bị reset.
__________________
Quang báo RG/RGB 6/8/12/16 bits màu
Phone No: 0905.034.086
Email: lmquyen@gmail.com
cskiller vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-04-2009, 07:53 PM   #7
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Cho mình hỏi thêm câu nữa là công thức tính thời gian trễ như thế nào.Có phải là :
Delay=((256-InitTMRO)*Prescaler) / Frenquency/4)

NHưng nếu áp dụng công thức này cho chuơng trình tính toán Pic Timer Calculator thì không đúng nữa mà phai trở thành là :
Delay=((256-InitTMRO+1)*Prescaler) / Frenquency/4)

Chuơng trình này bạn có thể lấy tại :
http://www.picvietnam.com/forum/atta...6&d=1128135937

NHư vậy cái nào đúng ?
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-05-2009, 11:52 AM   #8
the_duyet
Đệ tử 1 túi
 
Tham gia ngày: Mar 2008
Nơi Cư Ngụ: Hạ Long City
Bài gửi: 18
:
Send a message via Yahoo to the_duyet
Post

Có thể bạn config con Pic trong chương trình mô phỏng chưa chuẩn, mặc định của chương trình Proteus cho Pic là 1MHz, nhưng nếu bạn dịch nguyên chương trình trên thì nó là 4MHz,vậy nó chậm hơn là phải,bạn xem lai thử chỗ này.
the_duyet vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-05-2009, 10:28 PM   #9
thaithien
Đệ tử 7 túi
 
Tham gia ngày: Aug 2007
Bài gửi: 213
:
Ok,mình đã biết cách chỉnh lại tần số cho con PIC trong Proteus rồi.ĐÚng là mặc định là 1MHZ
thaithien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


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


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam