Bạn nào có kinh nghiệm dùng chức năng capture của PIC để đo độ rộng xung xin chia xẻ một chút kinh nghiệm.
Thông báo
Collapse
No announcement yet.
Sử dụng chức năng capture của PIC
Collapse
X
-
Để đo độ rộng xung PIC có hỗ trợ mode capture. Trong mode này PIC sử dụng một timer để hoạt động, timer này hoạt động mỗi khi có cạnh lên (hay xuống) của tín hiệu ngoài và kết thúc khi có cạnh xuống (hay lên) của tính hiệu ngoài. Giá trị timer sẽ được tự động lưu vào một thanh ghi tạm để chờ bạn lưu.
Datasheet của PIC nói rất rõ, bạn vào www.microchip.com tải về.
Mode này rất hay dùng để xác định tần số của xung hay dùng để xác định vận tốc của động cơ.
Chào thân.
-
Tín hiệu vào được đưa tới chân CPPx, việc sử dụng Capture phải được cấu hình với bộ CPPx tương ứng. Chức năng Capture hoạt động based on một timer và thường là Timer2.Nguyên văn bởi PICĐể đo độ rộng xung PIC có hỗ trợ mode capture. Trong mode này PIC sử dụng một timer để hoạt động, timer này hoạt động mỗi khi có cạnh lên (hay xuống) của tín hiệu ngoài và kết thúc khi có cạnh xuống (hay lên) của tính hiệu ngoài. Giá trị timer sẽ được tự động lưu vào một thanh ghi tạm để chờ bạn lưu.
Datasheet của PIC nói rất rõ, bạn vào www.microchip.com tải về.
Mode này rất hay dùng để xác định tần số của xung hay dùng để xác định vận tốc của động cơ.
Chào thân.
Theo nghĩa chân phương capture là bắt giữ, vậy chế độ Capture hoạt động cũng như vậy. Ngay khi phát hiện sườn lên (hoặc xuống là do ta thiết lập) trên chân CPPx, giá trị hiện tại của Timer2 sẽ được lưu trữ lại.
Vậy, để đo độ rộng xung ta có thể làm như sau :
Thứ nhất : dùng hai bộ CPP1 và CPP2 với cùng chức năng Capture, tín hiệu vào được đưa tới cả hai chân CPP1 và CPP2 của PIC. CPP1 thiết lập với sườn lên còn CPP2 với sườn dưới. Như vậy, khi gặp sườn lên của xung-CPP1 sẽ lưu trữ, khi gặp sườn xuống thì CPP2 sẽ lưu trữ. Kết quả thu được từ hiệu hai giá trị này sẽ cho ta độ rộng của xung cần đo tính theo chu kỳ lệnh. Để kịp thời, ta có thể sử dụng ngắt cho CPP2 để ngay khi kết thúc xung ta có thể đo giá trị sử dụng cho các mục đích khác.
Thứ hai : ta chỉ dùng một bộ CPP1 thôi, ban đầu thiết lập bắt giữ sườn lên. Ngay sau khi xảy ra ngắt, ta lại thiết lập nó theo sườn xuống. Cũng từ hai kết quả này ta sẽ thu được độ rộng của xung.
Vài điều trao đổi, mong các bác chỉ giáo.
Comment
-
Đo tần số
Qua giới thiệu của PIC và Zero2one thì cũng khá dễ hiểu. Cái này mình cũng nắm được. Bây giờ quan trọng mình muốn đo tần số, tức là phải đo cả thời gian xung ở mức cao (T1) và thời gian xung ở mức thấp (T2)
T=T1+T2
f=1/T
Vậy phải cấu hình cho chế độ Capture thế nào, hai bạn có thể giải thích một cách cụ thể được không?Càng biết nhiều càng thấy mình biết ít.
Comment
-
Vậy thì bạn không cần phải đo cạnh lên và cạnh xuống nữa, mà chỉ cần đo các cạnh lên, lúc đó bạn lập tức có ngay T = T1 + T2.
Trong bài toán rời rạc, tần số hay là thời gian là như nhau, nếu bạn sử dụng nó để tiếp tục tính tóan, thì nên chuzển tất cả sang miền thời gian, còn nếu bạn dùng nó để hiển thị kết quả tần số, thì bạn thực hiện phép chia để lấy kết quả.
Tuy nhiên, một điểm khá hay mà bạn nên lưu ý, đó là thay vì thực hiện phép chia thì bạn nên thực hiện phép nhân.
Bạn lưu ý rằng thời gian ở đây là chu kỳ máy, chứ không phải thời gian theo đơn vị giây.
Chúc vui.Falleaf
Công ty TNHH Thương mại và Giao nhận R&P
58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
mail@falleaf.net - VP: (04) 36408561 - (08) 38119870
Comment
-
Dùng 1 hay 2 capture
* Theo falleaf nói tôi vẫn thấy có thắc mắc :
Nếu dùng chỉ dùng CCP1 , ta chỉ đo theo sườn lên như vậy có thể làm như sau :
- Thiết lập ngắt theo sườn lên
- Đặt biến count=0 (đếm lần ngắt)
Trong Ct ngắt kiểm tra xem ngắt lần thứ nhất hay lần 2:
Nếu ngắt lần 1 thì T1=giá trị hiện thời của timer
count=count+1;
Nếu ngắt lần 2 thì T2 =giá trị hiện thời của timer
gán lại count=0;
Như vậy T=T2-T1 chứ nhỉ? vì nó là khoảng lấy khoảng thời gian giữa 2 lần xuất hiện sườn lên của xung mà.
* Còn nếu sử dụng cả CCP1 và CCP2 và đưa xung vào cả 2 chân của CCP1 và CCP2 thì khi sườn lên xuất hiện, theo như falleaf nói liệu sẽ phân biệt thế nào, giá trị đọc ở thanh ghi của CCP1 và CCP2 sẽ là như nhau chứ nhỉCàng biết nhiều càng thấy mình biết ít.
Comment
-
Nếu chỉ quan tâm tới tần số (chu kỳ) của xung thôi thì falleaf nói chính xác. Chỉ cần hai sườn lên hoặc hai sườn xuống liên tiếp nhau mà Capture thu được thì đủ xác định được tần số.
Ngắt capture cho phép bạn lưu tức thời giá trị của capture, nếu không khi có capture xảy ra lần nữa thì giá trị trước đó sẽ bị đè lên.
Nếu không cần biết dutycycle của xung thì ta chi cần dùng 1 capture thôi không cần dùng hai cái như bạn ATYLA đâu.
Còn việc thiết lập cụ thể thì tùy thuộc vào con nào, datasheet ghi rất rõ mà bạn xem hiểu liền hè.
Chào bạn.
Comment
-
ban can ve lai so do xung.
Mot xung chi co 1 canh len, va mot canh xuong.
Chu ky nhiem vu bat dau bang 1 xung len va ket thuc bang 1 xung xuong.
Chy ky nghi bat dau bang 1 xung xuong (cua chu ky nhiem vu truoc do), va mot xung len (cua chu ky nhiem vu tiep theo sau).
Nhu vay, chi can xac dinh khoang cach giua 2 xung len, co nghia la khoang cach ve thoi gian giua hai xung lien tiep nhau, do chinh la chu ky cua tin hieu.
Va tu chu ky do, ban suy ra tan so.
Ban can phai ve ra giay, khong nen ngoi tuong tuong, mat thoi gian, khong duoc ich loi gi.
Nguoi Duc co mot cau noi: Cang nghi cang sai, tot hon la biet no chu dung nen nghi ve no.Falleaf
Công ty TNHH Thương mại và Giao nhận R&P
58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
mail@falleaf.net - VP: (04) 36408561 - (08) 38119870
Comment
-
Noi tin hieu can do vao chan CCP1 va CCP2.
Chon CCP1 mode falling, CCP2 rissing.
Dat che do ngat cho CCP1 va CCP2.
Dat timer1 tuy theo do chinh xac cua tin hieu ban can do
khai bao bien
long value;
int CCP2(void)
{
value = CCP2 - CCP1;
settimer1(0);
}
Khi do do rong xung se la value X thoi gian cua 1 xung clock cap cho timer1.
Chux thanh cong.Nhà sản xuất chuyên nghiệp các sản phẩm OEM cho gia dụng và công nghiệp.
Biến tần
Máy giặt
Lò vi sóng
Bếp từ.
Tủ lạnh.
Điều hòa
Comment
-
Làm như vậy là theo cách truyền thống có hướng dẫn bác Minh Hà à, cách do tần số làm như mình làm là tốt nhất, bởi vì chỉ cần 1 chân, ngoài ra không cần dùng ngắt cũng có thể làm được. Không nên sử dụng ngắt quá nhiều, cái gì cần thì dùng, không cần thì thôi.
Ngay cả khi không dùng ngắt thì giá trị vẫn được lưu tại đó. Khi nào cần tính thì lôi ra tính là xong.Falleaf
Công ty TNHH Thương mại và Giao nhận R&P
58/57 Nguyễn Minh Hoàng - Phường 12 - Quận Tân Bình - TP.HCM
mail@falleaf.net - VP: (04) 36408561 - (08) 38119870
Comment
-
Đo tấn số dùng capture
#include <16F876A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT, NOPROTECT
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
int16 CCP1Value;
int16 CCP1OldValue;
BOOLEAN CCP1Captured;
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
CCP1Captured = TRUE;
}
//--------------------------------------------------------------------------
void Init_ccp(void)
{
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
CCP1Value = 0;
CCP1OldValue = 0;
CCP1Captured = TRUE;
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
void main()
{
float Freq;
Init_ccp();
printf("Frequence test:\r\n");
while (TRUE) {
if (CCP1Captured) {
// F = 1/T
// Timer1 prescaler DIV_BY_8
// Pic16F876 4Mz -> 0.000001 * 8
Freq = 1.0/((float)CCP1Value*8e-6);
printf("Freq:%f\r\n",Freq);
CCP1Captured = FALSE;
}
}
}Càng biết nhiều càng thấy mình biết ít.
Comment
-
Re: Đo tấn số dùng capture
Tui có mấy ý kiến be bé, góp ý cùng bác ATYLA:Nguyên văn bởi ATYLA#include <16F876A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT, NOPROTECT
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
int16 CCP1Value;
int16 CCP1OldValue;
BOOLEAN CCP1Captured;
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
CCP1Captured = TRUE;
}
//--------------------------------------------------------------------------
void Init_ccp(void)
{
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
CCP1Value = 0;
CCP1OldValue = 0;
CCP1Captured = TRUE;
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
}
//--------------------------------------------------------------------------
void main()
{
float Freq;
Init_ccp();
printf("Frequence test:\r\n");
while (TRUE) {
if (CCP1Captured) {
// F = 1/T
// Timer1 prescaler DIV_BY_8
// Pic16F876 4Mz -> 0.000001 * 8
Freq = 1.0/((float)CCP1Value*8e-6);
printf("Freq:%f\r\n",Freq);
CCP1Captured = FALSE;
}
}
}
+Dòng lệnh: CCP1Value = CCP_1 - CCP1OldValue;
nếu chỉ viết như vậy thì khi bô định thời đếm đến 65535 thì sẽ tràn. Bởi vậy sẽ ko chính xác khi tính toán. Biểu thức trên sẽ bị sai. Biểu thúc trên đúng khi bộ định thời ko tràn. Vì cách lập trình gán liên tiếp này sẽ tràn.
+Khắc phuc bằng cách
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1;
settimer1(0); //nạp giá trị = 0 vào timer
CCP1Captured = TRUE;
}
Nhưng cách này sẽ sai só, vài chục chu kỳ, nên phải bù = phần mềm, kiểu như:
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1+Ofset;//Ofset là do delay khi vào ngắt+phục vụ ngắt.
settimer1(0); //nạp giá trị = 0 vào timer
CCP1Captured = TRUE;
}
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1;
settimer1(0); //nạp giá trị = 0 vào timer
CCP1Captured = TRUE;
}
Một cách hay hơn là:
#int_CCP1
CCP1_isr()
{
CCP1Value = CCP_1 - CCP1OldValue;
CCP1OldValue = CCP_1;
CCP1Captured = TRUE;
}
Nhưng lại cài đặt thêm 1 timer1, khi tràn nó sẽ thông báo cho mình. Căn cứ vào đó minh có thể lam chủ được CCP1Value = CCP_1 - CCP1OldValue; một cách chính xác hơn căn cứ vào nó tràn hay ko
#int_CCP1
CCP1_isr()
{
if(đã tran timer)
{
CCP1Value =CCP_1+ (65536-CCP1OldValue ) ;
}else
{
CCP1Value = CCP_1 - CCP1OldValue;
}
CCP1OldValue = CCP_1;
CCP1Captured = TRUE;
}
Ý tưởng là như vậy, các bác cho ý kiến-------------------
Comment
-
Tràn bộ định thời
Thực ra theo tôi bộ định thời tràn hay ko thì đâu có ảnh hưởng gì, tôi chỉ cần thêm câu lệnh:
if(ccp_1>ccpoldvalue)
{}
là xong.
Vì khi tràn 655535 sẽ chuyển về đếm từ 0, chương trình nó sẽ bỏ qua thời điểm tràn mà ko thực hiện phép trừ nữa (vẫn gửi lên PC giá trị trước đó).
Bác CHIBANG nghĩ sao?Càng biết nhiều càng thấy mình biết ít.
Comment
-
Re: Tràn bộ định thời
1-Giả sử giá trị cppoldvalue là 3000; nhưng do thời gian capture quá dài, bởi thế ví dụ giá trị timer 1 tăng dần: 3000,3001,3002,...65535,0,1,...3000,3001, tại thời điểm này nếu có capture thì vẫn đảm bảo: if(ccp_1>ccpoldvalue){} nhưng thực tế lại khác hẳn. Đó là chưa nói chuyện nó tràn nhiều lần mà capture vẫn đảm bảo if(ccp_1>ccpoldvalue){}Nguyên văn bởi ATYLAThực ra theo tôi bộ định thời tràn hay ko thì đâu có ảnh hưởng gì, tôi chỉ cần thêm câu lệnh:
if(ccp_1>ccpoldvalue)
{}
là xong.
Vì khi tràn 655535 sẽ chuyển về đếm từ 0, chương trình nó sẽ bỏ qua thời điểm tràn mà ko thực hiện phép trừ nữa (vẫn gửi lên PC giá trị trước đó).
Bác CHIBANG nghĩ sao?
2-Hơn nữa, cho dù thời gian capture là bé đi, bác lại thỉnh thoảng bỏ phí mất 1 giá trị khi tràn.
Bởi thế theo em, bác cài đặt ngắt timer đó luôn. Khi nó tràn mình biết ngay, làm 1 biến để lưu trữ số lần tràn.-------------------
Comment
Bài viết mới nhất
Collapse
-
bởi mèomướpDạ chú rủ cô ấy đi ăn uống, cà phê, xem phim...nhớ nắm tay, rồi thì ôm hôn,...trong vòng 1 tuần mà ko nắm tay được, 1 tháng mà ko ôm đc thì dẹp ngay và luôn ạ. Nhắn tin, gọi điện ít thôi ạ, trả lời quá lâu hoặc ko trả lời cũng dẹp ngay ạ. Nên thể hiện chú là người có điều kiện nữa ạ...
-
Channel: Tâm tình dân kỹ thuật
hôm nay, 18:50 -
-
bởi songchodep76Cảm ơn bác đã nhiệt thành chia sẻ kinh nghiệm bản thân mình cho mọi người.
Tuy nhiên, theo tiếp xúc hạn hẹp của em với mosfet thì vấn đề bác đo vôn ở cực D và thấy đỉnh nó 70V/55V Vds max, như thí nghiệm và trong hình của bác...-
Channel: Hướng dẫn sử dụng diễn đàn
Hôm qua, 09:46 -
-
Trả lời cho Yêu thơ mê nhạc, mời các bác vào đây!bởi dinhthuong92Cho tới thời điểm này, quả thật Đình Thường đây quá thất vọng, không hào hứng với Suno-AI lắm bởi ra lệnh Creat mấy chục lần với các thay đổi thì mới chọn được 2 bản hát đúng giai điệu tầm 80% để cắt ghép tạo thành bài hát...
-
Channel: Tâm tình dân kỹ thuật
06-02-2026, 17:01 -
-
Trả lời cho Yêu thơ mê nhạc, mời các bác vào đây!bởi dinhthuong92Kính chào cả nhà, nhân dịp Tết đang về, sắp 23 tháng chạp rồi, xin gởi lời chúc xuân qua bài hát sau ạ:
Bao nhiêu hân hoan
Chúc Mừng Năm Mới, xuân sang!
Nơi nơi hát vang
nâng chén vui chúc câu An Lành.
Vạn Sự đều Hanh Thông,
Rạng...-
Channel: Tâm tình dân kỹ thuật
06-02-2026, 16:46 -
-
bởi ittcChán quá các bác, em nhạt nhẽo quá nên tán em nào cũng tạch, tuyệt vọng vô cùng, nay lại được mấy anh đồng nghiệp cty đối tác mách cho em gái kia sinh năm 2K đầu, em chả biết nhóm đối tượng này phải tán ra sao bây giờ ?
Tính ra em...-
Channel: Tâm tình dân kỹ thuật
06-02-2026, 00:18 -
-
bởi bqvietCó thể, ví dụ phần phản hồi gồm vi mạch cách ly quang, zener thứ cấp, transistor và điện trở phản hồi dòng ... Bất kỳ linh kiện nào nhóm đó hỏng dẫn tới mất đường phản hồi. TNY chính hãng phát hiện được chuyện đó nhưng linh kiện...
-
Channel: Điện tử công suất
05-02-2026, 18:36 -
-
bởi Nexus 6Pcho e hỏi, khi mạch có linh kiện nào đó hư thì có làm hỏng led đắt tiền (osram) không?
-
Channel: Điện tử công suất
05-02-2026, 10:42 -
-
bởi chinhnguyen9· Thí nghiệm 1 (Mạch boost, Vcc=12V, kích bằng dao động PƯM, duty 10%):
* Không có snubber + không tải: Xuất hiện hiện tượng dao động tắt dần tại cực D Mosfet (ringing). Hình 1 cho thấy trong chu kỳ đầu, điện áp spike lên tới hàng trăm V, điện...-
Channel: Hướng dẫn sử dụng diễn đàn
04-02-2026, 09:16 -
-
bởi Nexus 6Pe dùng KiCad 9.0 và đã xuất được file PDF mạch in gòi bác...
-
Channel: Điện tử công suất
03-02-2026, 16:25 -
-
bởi bqvietBấm chuột vào các tệp sẽ bật ra chương trình tương ứng. Nên dùng bản KiCAD sau
https://kicad-downloads.s3.cern.ch/a...ll_version.exe-
Channel: Điện tử công suất
03-02-2026, 14:57 -

Comment