19-05-2007, 03:29 AM | #196 |
Nhập môn đệ tử
Tham gia ngày: Oct 2006
Bài gửi: 10
: |
frequencymeter
Code:
#include <16f628.H> #use delay(clock=4000000)// #fuses NOPROTECT,NOWDT,PUT,noBROWNOUT,noLVP,NOMCLR,xt #BYTE PORT_A=0X05 #BYTE PORT_B=0X06 /***entegreterbiyecisi@yahoo.com***//***entegreterbiyecisi@yahoo.com***/ // LCD STUFF #define LCD_RS PIN_b0 #define LCD_EN PIN_b1 #define LCD_D4 PIN_b2 #define LCD_D5 PIN_b3 #define LCD_D6 PIN_b4 #define LCD_D7 PIN_b5 #define FIRST_LINE 0x00 #define SECOND_LINE 0x40 #define CLEAR_DISP 0x01 #define CURS_ON 0x0e #define CURS_OFF 0x0c /***entegreterbiyecisi@yahoo.com***/ #use standard_io ( a ) #use standard_io ( b ) /***entegreterbiyecisi@yahoo.com***/ // proto statements void LCD_Init ( void ); void LCD_SetPosition ( unsigned int cX ); void LCD_PutChar ( unsigned int cX ); void LCD_PutCmd ( unsigned int cX ); void LCD_PulseEnable ( void ); void LCD_SetData ( unsigned int cX ); /***entegreterbiyecisi@yahoo.com***//***entegreterbiyecisi@yahoo.com***/ /*************************entegreterbiyecisi@yahoo.com******************************/ int32 ab=0,hz=0; int1 stept_say=0,data_bitti=0,step,aa=0; int16 sayi=0,tr=20; /*************************entegreterbiyecisi@yahoo.com******************************/ #int_timer1 tas(){ ab++; } #int_timer0 sn(){sayi=0; set_timer0(61);//(255-60)*195*20=1000000us=dahili 1sn icin if(tr){ tr--;} else{delay_us ( 698 ); output_low(pin_a0); disable_interrupts (global); disable_interrupts(int_timer0); disable_interrupts(int_timer1); sayi=get_timer1(); aa=1; hz=sayi+(65536*ab); tr=20; }} /*************************entegreterbiyecisi@yahoo.com******************************/ void main() { setup_timer_1(t1_external|t1_div_by_1); setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256); enable_interrupts(int_timer0); // timer0 enable_interrupts(int_timer1); enable_interrupts(global); lcd_init(); SET_TRIS_A(0b00100000); SET_TRIS_B(0b11000000); set_timer0(61); set_timer1(0); LCD_SetPosition(first_LINE+0); printf(lcd_putchar,"\NECATi KIYLIOGLU "); LCD_SetPosition(second_LINE+1); printf(lcd_putchar,"\ 0532 613 65 87"); delay_ms (500); LCD_PutCmd ( CLEAR_DISP ); sayi=0; hz=0; /*************************entegreterbiyecisi@yahoo.com******************************/ while(true){ if(aa==1){ //LCD_PutCmd ( CLEAR_DISP ); LCD_SetPosition(first_LINE+0); printf(lcd_putchar,"\FREQUENCYMETER "); if(999>=hz){ LCD_SetPosition(second_LINE+0); printf(lcd_putchar,"\FRQ=%ldHz ",hz);} ////////////////////////////////////////// if(hz>=1000){ if(999999>=hz){ LCD_SetPosition(second_LINE+0); printf(lcd_putchar,"\FRQ=%3.3wKhz ",hz);}} ///////////////////////////////////////////// if(hz>=1000000){ LCD_SetPosition(second_LINE+0); printf(lcd_putchar,"\FRQ=%2.6wMhz ",hz);} //////////////////////////////////////////// delay_ms (1); set_timer1(0); enable_interrupts(int_timer0); enable_interrupts(int_timer1); enable_interrupts (global); aa=0; ab=0; } }} /*************************entegreterbiyecisi@yahoo.com******************************/ /***entegreterbiyecisi@yahoo.com***/ //lcd basla void LCD_Init ( void ){ LCD_SetData ( 0x00 ); output_low ( LCD_RS ); LCD_SetData ( 0x03 ); // init with specific nibbles to start 4-bit mode LCD_PulseEnable(); LCD_PulseEnable(); LCD_PulseEnable(); LCD_SetData ( 0x02 ); // set 4-bit interface LCD_PulseEnable(); // send dual nibbles hereafter, MSN first LCD_PutCmd ( 0x2C ); // function set (all lines, 5x7 characters) LCD_PutCmd ( 0x0C ); // display ON, cursor off, no blink LCD_PutCmd ( 0x01 ); // clear display LCD_PutCmd ( 0x06 ); // entry mode set, increment } /***entegreterbiyecisi@yahoo.com***/ void LCD_SetPosition ( unsigned int cX ) { // this subroutine works specifically for 4-bit Port A LCD_SetData ( swap ( cX ) | 0x08 ); LCD_PulseEnable(); LCD_SetData ( swap ( cX ) ); LCD_PulseEnable(); } /***entegreterbiyecisi@yahoo.com***/ void LCD_PutChar ( unsigned int cX ) { // this subroutine works specifically for 4-bit Port A output_high ( LCD_RS ); LCD_SetData ( swap ( cX ) ); // send high nibble LCD_PulseEnable(); LCD_SetData ( swap ( cX ) ); // send low nibble LCD_PulseEnable(); output_low ( LCD_RS ); } /***entegreterbiyecisi@yahoo.com***/ void LCD_PutCmd ( unsigned int cX ) { // this subroutine works specifically for 4-bit Port A LCD_SetData ( swap ( cX ) ); // send high nibble LCD_PulseEnable(); LCD_SetData ( swap ( cX ) ); // send low nibble LCD_PulseEnable(); } /***entegreterbiyecisi@yahoo.com***/ void LCD_PulseEnable ( void ) { output_high ( LCD_EN ); delay_us ( 100 ); output_low ( LCD_EN ); delay_ms ( 5 ); } /***entegreterbiyecisi@yahoo.com***/ void LCD_SetData ( unsigned int cX ) { output_bit ( LCD_D4, cX & 0x01 ); output_bit ( LCD_D5, cX & 0x02 ); output_bit ( LCD_D6, cX & 0x04 ); output_bit ( LCD_D7, cX & 0x08 ); } /***entegreterbiyecisi@yahoo.com***/ //lcd son //////////////////////////////////////////////////////////////////////////// thay đổi nội dung bởi: namqn, 19-05-2007 lúc 08:30 PM. |
21-05-2007, 10:07 AM | #197 |
Đệ tử 1 túi
Tham gia ngày: May 2007
Bài gửi: 15
: |
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! |
21-05-2007, 10:34 AM | #198 |
Đệ tử 1 túi
Tham gia ngày: May 2007
Bài gửi: 15
: |
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!
|
22-05-2007, 05:18 PM | #199 |
Nhập môn đệ tử
|
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?
__________________
Già vẫn học. Chọc thì cười. |
22-05-2007, 05:36 PM | #200 |
Nhập môn đệ tử
|
#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.
__________________
Già vẫn học. Chọc thì cười. |
22-05-2007, 08:52 PM | #201 |
Đệ tử 7 túi
|
Ú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á.
__________________
_____________________________Tri nhân tri tự bất tri tâm_____________________________ _ _ _ _ _ _ _ _ Yêu mến tất cả anh em Picvietnam.com _ _ _ _ _ _ _ _ . . . . . . . . . . . . . . . . Để post đuợc một câu hỏi rõ ràng xin tham khảo link sau : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . http://www.picvietnam.com/forum/showthread.php?t=1263. . . . . . . . . . . . . . . . |
23-05-2007, 11:37 AM | #202 |
Đệ tử 1 túi
Tham gia ngày: May 2007
Bài gửi: 15
: |
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 |
23-05-2007, 04:38 PM | #203 | |
Nhập môn đệ tử
|
Pic18f4450
Trích:
__________________
Già vẫn học. Chọc thì cười. |
|
23-05-2007, 09:23 PM | #204 |
Đệ tử 2 túi
Tham gia ngày: Mar 2007
Bài gửi: 45
: |
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)
__________________
Cổng trường Đại học cao vời vợi Đồng ruộng mênh mong đón em về! |
23-05-2007, 11:07 PM | #205 | |
Trưởng lão PIC bang
|
Trích:
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
24-05-2007, 07:15 PM | #206 |
Nhập môn đệ tử
|
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> #fuses NOWDT,PUT,HS,NOPROTECT #use delay(clock=10000000) #use fast_io(b) #use fast_io(a) #byte portb=0x6 BYTE CONST LED_MAP[10] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x58,0x00,0x10}; int8 a,i,j; void ngat() { a++; if(a>=100) a=0; } void main() {set_tris_a(0); a=0; set_tris_b(0); while(true) { i=0;while(i<=200) {i++; output_b(led_map[a/10]); output_high(PIN_B7); output_low(PIN_A0); delay_ms(3); output_high(PIN_A0); output_b(led_map[a%10]); output_low(PIN_A1); delay_ms(3); output_high(PIN_A1); } ngat(); } return; }
__________________
Già vẫn học. Chọc thì cười. thay đổi nội dung bởi: falleaf, 24-05-2007 lúc 07:24 PM. |
24-05-2007, 10:28 PM | #207 |
Đệ tử 3 túi
Tham gia ngày: Jun 2005
Bài gửi: 56
: |
Làm như anh namqn là ok roài, nhưng con 16F84A không có comparator nên bạn sẽ phải thêm một con comparator ngoài, ví dụ LM393
|
29-05-2007, 06:38 PM | #208 |
Đệ tử 1 túi
Tham gia ngày: Dec 2006
Bài gửi: 20
: |
Em làm mạch đo nhiệt độ sử dụng LM335Z để hiển thị LCD .
Code:
#include <16F877A.h> #include <DEFS_16F877A.h> #device*=16 adc=10 #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(clock=20000000) #define RS RB3 #define RW RB4 #define E RB5 #byte lcd_data = PORTD // Dia chi PORTD int8 hight,low,i; float value; void convert_bcd(int8 a){ low=a%10; hight=a/10; low+=0x30;//doi ra ma ASCII de hien thi LCD hight+=0x30; } byte lcd_read_byte() { byte read_byte; set_tris_D(0xFF); // PORTD = input RW = 1; delay_cycles(1); E = 1; delay_cycles(1); read_byte = lcd_data; E = 0; set_tris_D(0x00); // PORTD = output return(read_byte); } /* Goi 1byte den LCD */ void lcd_send_byte( byte address, byte n ) { RS = 0; while ( bit_test(lcd_read_byte(),7) ) ; RS = address; delay_cycles(1); RW = 0; delay_cycles(1); E = 0; lcd_data = n; delay_cycles(1); E = 1; delay_us(2); E = 0; } /* Khoi tao ban dau cho LCD */ void lcd_init() { byte const lcd_init_string[4] = {0x38, 0x0C, 1 , 6}; byte i; set_tris_D(0x00); RS = 0; RW = 0; E = 0; delay_ms(15); for(i=1;i<=3;++i) { lcd_data = 3; delay_cycles(1); E = 1; delay_us(2); E = 0; delay_ms(5); } lcd_data = 2; delay_cycles(1); E = 1; delay_us(2); E = 0; delay_ms(5); for(i=0;i<=3;++i) { lcd_send_byte(0,lcd_init_string[i]); } } void lcd_gotoxy( BYTE x, BYTE y) { BYTE address; if(y!=1) address=0x40; else address=0; address+=x-1; lcd_send_byte(0,0x80|address); } void lcd_putc( char c) { switch (c) { case '\f' : lcd_send_byte(0,1); delay_ms(2); break; case '\n' : lcd_gotoxy(1,2); break; case '\b' : lcd_send_byte(0,0x10); break; default : lcd_send_byte(1,c); break; } } main() { set_tris_B(0); set_tris_D(0); set_tris_A(0xFF); lcd_init(); delay_ms(100); lcd_gotoxy(3,1); lcd_putc("hello"); lcd_gotoxy(1,2); lcd_putc("Welcom Everybody"); delay_ms(2000); lcd_send_byte(0,1);//xoa LCD lcd_send_byte(0,6); setup_adc(ADC_CLOCK_INTERNAL); setup_adc_ports(AN0); set_adc_channel(0); delay_ms(100); value=(float)read_adc(); value=(value-558.5)/2.048; convert_bcd((int8)value); delay_us(20); lcd_putc("nhiet do:"); while(1) { value=(float)read_adc(); value=(value-558.5)/2.048; convert_bcd((int8)value); delay_ms(1000); lcd_gotoxy(2,4); lcd_putc(hight); lcd_putc(low); lcd_putc(" do C"); //delay_ms(1000); } } 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ộ .
__________________
Học mà không yêu là phí hoài tuổi trẻ Yêu mà không học là bán rẻ tương lai. thay đổi nội dung bởi: hawinter, 30-05-2007 lúc 01:55 PM. |
29-05-2007, 10:18 PM | #209 |
Đệ tử 1 túi
Tham gia ngày: Dec 2006
Bài gửi: 20
: |
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ỉ .
__________________
Học mà không yêu là phí hoài tuổi trẻ Yêu mà không học là bán rẻ tương lai. thay đổi nội dung bởi: hawinter, 29-05-2007 lúc 10:59 PM. |
30-05-2007, 09:28 PM | #210 |
Đệ tử 4 túi
Tham gia ngày: Aug 2006
Bài gửi: 61
: |
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ử |
|
|
Similar Threads | ||||
Ðề tài | Người gửi | Chuyên mục | Trả lời | Bài mới |
TUT ve I2C ( pic16f877a ) | mafd_47a | MPASM | 26 | 07-05-2024 08:55 AM |
TUT về USART trong PIC16F877A | mafd_47a | MPASM | 11 | 04-05-2024 04:43 AM |
Lập nhóm PIC16F877A | nhh | Cơ bản về vi điều khiển và PIC | 285 | 08-03-2017 11:08 PM |
Bộ so sánh và PWM cho PIC16F877A | anhquangngai | Cơ bản về vi điều khiển và PIC | 24 | 08-09-2012 09:00 AM |
Pic16f877a TỪ DỄ TỚi KhÓ | ntc | Cơ bản về vi điều khiển và PIC | 373 | 23-05-2009 10:24 PM |