frequencymeter
Code:
#include <16f628.H> |
Cảm ơn bạn Necati đã Post lên chương trình mà tôi và nhiều anh em đang quan tâm. Tôi muốn hỏi thêm là nếu muốn đo 1 tần số sóng mang nằm trong tín hiệu điều chế thì giải quyết như thế nào. Giả sử có 1 tín hiệu cần điều chế có f = 2KHz độ rộng xung là 2us, tín hiệu sóng mang có f0 = 20MHz, nghĩa là trong 2us của tín hiệu điều chế sẽ có 20*2 = 40 chu kỳ xung của sóng mang trong đó. Bài toán ở đây là đo được tần số 20MHz từ tín hiệu đã điều chế đó.
Rất mong anh Necati và các anh em trong diễn đàn giúp đỡ! Thanks alot! |
Tôi đọc kỹ thì thấy chương trình của anh Necati cũng đo tần số liên tục, nhưng sử dụng thêm Timer0 để định thời 1 giây, và Timer1 cũng để lấy giá trị đếm số lần xuất hiện xung vào. Tất nhiên, chương trình viết rất chuyên nghiệp, đó cũng là điều mà tôi và nhiều anh em cần học hỏi thêm rất nhiều. Chân thành cảm ơn anh!
|
Xin hỏi tại sao chương trình dùng ngắt timer0 em làm giống nhu hướng dẫn mà nó không chịu chạy?
|
#include<18F4450.h>
#fuses NOWDT,PUT,HS,NOPROTECT #use delay(clock=20000000) #use fast_io(b) #byte portb=0x6 #define led pin_B0 int8 a; void ngat() { delay_ms(1000); a=a<<1; // dich trai a 1bit if(a==256) a=1; } main() { a=1; set_tris_b(0); while(true) { ngat(); output_b(a); } } Cách này thì PIC18F4550 cũng dịch leds vô tư. Nhưng mà muốn dùng TIMER0 như của bác nhh . Khi mình làm không hiểu tại sao lại không thể chạy. Nhờ bác chỉ giáo giùm nhé! #include <18F4550.h> #fuses NOWDT,PUT,XT,NOPROTECT #use delay(clock=20000000) . Mình đã sửa lại code của nhh như vậy để phù hợp với PIC18F4550, nhưng không hiểu sao vẫn không chạy đơợc. Bạn có thể hướng dẫn kỹ hơn về Interrup và Timer không, cảm on bạn nhiều. |
Úi code của bạn sai rồi nếu muốn sử dụng được ngắt thì trong hàm main bạn phải thực hiện cho phép ngắt timer_0 và ngắt toàn cục (global) hoạt động, định xung nhịp cho timer, và hàm ngắt() phải được đặt ngay bên dưới chỉ thị #int_timer0 để trình dịch có thể hiểu được đây là hàm phục vụ ngắt, hàm ngắt() này bạn không thể gọi đến giống như một hàm thông thường đuợc mà nó chỉ được máy gọi đến khi có xuất hiện cờ tràn timer_0, mà khi đã sử dụng ngắt timer (tức ngắt định thời) thì bạn không nên dùng delay trong nó (rất dở),vì ngắt timer được tạo ra để thay thế hoàn hảo cho delay, code của bạn mình sửa như sau :
#include<18F4450.h> #fuses NOWDT,PUT,HS,NOPROTECT #use delay(clock=4000000) int16 count=0; int8 a=1; #int_timer0 void ngat(){ ++count; if(count==2000) {count=0;a=a<<1;} // dich trai a 1bit if(a==256) {a=1;count=0; }} void main(){ enable_interrupts(global); enable_interrupts(int_timer0); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); //xung timer = xung máy/2 while(true) { output_b(a); }} như vậy ở hàm trên ta sẽ thấy sau mỗi lần tràn ngắt timer_0 (sau hai xung máy) biến đếm count sẽ tăng lên 1 đơn vị và cứ thế cho đến khi đạt giá trị 2000 (đây là giá trị mà bạn cần phải tính để chọn đúng thời gian cần làm làm trễ) khi đó biến a sẽ đuợc dịch bit sang trái,....rồi tiếp tục... chắc khúc này bạn hiểu rồi há. |
Giải thích như bạn thaithienanh là đúng đấy. Bạn phải khai báo thủ tục ngắt cho đúng và trong chương trình chính phải cho phép ngắt (hoặc không) đúng ý đồ thuật toán.
Tiện đây các bạn cho hỏi có cách nào đo được biên độ điện áp của xung vuông có độ rộng xung (thời gian tồn tại mức) nhỏ cỡ 0.4us không? Tôi định dùng ADC thông thường với xung clock nội (thạch anh 20MHz) và dùng thêm các chân phát hiện mức (sườn lên) của xung rồi cho phép lấy ADC nhưng không biết với độ rộng xung hẹp như vậy có khả thi không? Anh em nào biết phương pháp thì giúp tôi với. Thanks! ----------------------------------------------------------------------- An Hiệp |
Pic18f4450
Trích:
|
cho em hỏi, em đang làm thí nghiệm pic16f84a, làm led chớp tắt theo ý muốn nhưng em muốn dùng 1 biến trở để chỉnh tốc độ delay thì phải làm sao? nhờ các anh chỉ giáo! và em muốn dùng time 0 được không?
(xin lỗi mấy anh, mục này mà em hỏi F84a) |
Trích:
Thân, |
quét led 7 segment.
Cảm ơn anh thaithienanh nhiều, mình đã làm được rồi.Đã OK phần ngắt. Chiều nay mới quét và hiển thị 2x7 segment leds. Cho nó đếm, đã dần hiểu đựoc7 lập trình vi điầu khiển. Mong đựoc7 các bác chỉ giáo nhiều hơn nữa.
đây là chưong7 trình mà mình mới viết, mai sẽ sử dụng ngắt và timer để làm lại. Code:
#include<18F4550.h> |
Trích:
|
Em làm mạch đo nhiệt độ sử dụng LM335Z để hiển thị LCD .
Code:
#include <16F877A.h> khi chay chương trình thì giá trị nhiệt độ hiển thị chỉ quanh các giá trị 50,52,54,56,48,58 em cũng không biết tại sao .Xin các bậc tiền bối giải đáp hộ . |
Các sư huynh dúp em với đau đầu quá mà vẫn chưa tìm ra nguyên nhân ???
Cho em hỏi thêm là trong CCS để truy cập đến các thanh ghi thì làm thế nào nhỉ . |
Bạn kiểm tra lại Vref trên LM335 thử xem. Chương trình trên ứng với Vref = 5V. Nếu Vref có giá trị khác bạn phải tính lại các số cho biểu thức
" value=(value-558.5)/2.048;" Với 5V thì: 5V = 1024 muc (ADC 10bit 2^10 = 1024) => 10mV tuong ung voi 2.048 muc ADC 0oC = 273oK => 0oC ung voi muc dien the 2.73V ung voi 559 muc ADC Nhiet do = dien the Analog/10 - 273 Tuong ung Nhiet do = (adc -559)/2.024 Còn truy cập thanh ghi thì có lẽ giống như khai báo địa chỉ port I/O lúc đầu VD: #byte portb = 0x06; Lúc này ta có thể gán giá trị vào portb: portb = 0xFF; hay đọc giá trị từ portb ra ngoài: data = portb; Đối với các thanh ghi khác chắc cũng như vậy. Đặt tên thanh ghi, định nghĩa địa chỉ và truy xuất Bạn thử xem <<< chưa thử :D |
Múi giờ GMT. Hiện tại là 02:51 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