|
Tài trợ cho PIC Vietnam |
Giao tiếp cổng COM và LPT RS232, RS485 và LPT là những giao tiếp cơ bản và kinh điển khi mới học về vi điều khiển... |
|
Ðiều Chỉnh | Xếp Bài |
01-08-2008, 09:03 AM | #1 |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
cần giúp giao tiếp pc và 18f4680 qua cổng com
mình đã làm giao tiếp qua pc và pic qua cổng com cho các pic 184580 và 18f4550 thì nhận và truyền dữ liệu bình thường nhưng khi dùng pic 18f4680 thì chỉ nhận được data từ pic lên pc còn truyền từ pc xuống thì pic ko nhận được. mình không hiểu vì sao nữa. không biết 18f4680 có cần khai báo gì thêm hay sai xót gì không đạn nào biế chỉ giúp với.
mình đã thử giữa các pic cho cùng 1 chương trình và mạch text nhưng chỉ có 18f4680 là không nhận data từ pc gởi xuống. chỉ giúp mình nhé. |
01-08-2008, 07:08 PM | #2 | |
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 |
|
23-08-2008, 06:21 PM | #3 | |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
max232
Trích:
em có ý này muốn nhờ anh nam chỉ giáo thêm. từ trước đến nay khi giao tiếp pic với pc. khi pc gởi xuống 1 chuỗi data, thì em lập trì cho pic mỗi lần ngắt chỉ nhận 1 byte sau đó nhảy về vị trí cũ, rồi lại nhảy vào ngắt nhận byte khác cho đến khi hết chuỗi data từ pc gởi xuống thì thôi. chuỗi từ pc gởi xuống có bao nhiêu byte thì ngắt bấy nhiêu lần. không biết có cách nào để khi pc gởi xuống 1 chuổi có nhiều byte mà pic chỉ ngắt có 1 lần nhảy vào nhận toàn bộ data rồi mới nhảy ra không hả anh nam. nếu bác nào biết hoặc có ý kiến gì xin chỉ giúp luôn. |
|
23-08-2008, 06:25 PM | #4 | |
Đệ tử 9 túi
|
Trích:
Chúc bạn thành công. |
|
23-08-2008, 09:54 PM | #5 | |
Super Moderator
Tham gia ngày: Feb 2006
Bài gửi: 150
: |
Trích:
PHP Code:
|
|
28-08-2008, 05:31 PM | #6 |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
cảm ơn 2 bạn nhiều. code của bạn minh tuan liệu có ổn không. nếu trong vòng lặp while(1) thời gian làm việc cho vòng này từ 5 đến 10 phút thì khi pc gởi xuống liên tục nhiều byte mà trong khi vòng if(RxR != RxW) {
//xử lý byte nhận được ở đây RxR++; chưa kịp xử lý thì sẽ bị tràn bộ đệm buffer[16]; thì sao. nếu bị tràn thì sẽ bị mất byte thôi. cò nếu tăng buffer[16]; lên thì không biết tăng bao nhiêu cho thích hợp nữa vì nó phụ thuộc vào số byte pc gởi xuống và thời gian xử lý hết vòng while(1) phải không. mong bạn góp ý kiến. bạn haibac có thể nói rỏ hơn pic nào có nhiều bộ đệm trong uart không. cảm ơn hai bạn nhiều! |
28-08-2008, 10:52 PM | #7 | |
Trưởng lão PIC bang
|
Trích:
Bộ đệm có thể tăng lên theo yêu cầu của khối dữ liệu, nếu xử lý không kịp trong vòng while (1). PIC18F4680 có khá nhiều RAM. PIC24/dsPIC hay PIC32 có bộ đệm 4 mức cho module UART. Như thế là đủ cho việc giao tiếp bằng RS-232 rồi. Cho đến giờ, bạn vẫn chưa đưa ra vấn đề cụ thể của bạn, mà chỉ hỏi cách thực hiện những gì mà bạn cho là giải pháp. Tôi cho rằng thời gian hoàn tất một vòng while (1) từ 5 đến 10 phút là không hợp lý, nên viết lại. 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 |
|
28-08-2008, 11:46 PM | #8 |
Đệ tử 4 túi
Tham gia ngày: Aug 2008
Bài gửi: 89
: |
Sử dụng bộ đệm dạng queue vòng trong ngắt #INT_RDA, vừa tận dụng tối đa kích thước buffer mà ko cần reset các buffer counter vừa tiện lợi nhận dạng và xử lý dữ liệu(có thể đọc chuỗi byte hay string từ queue này).
|
29-08-2008, 12:49 AM | #9 | |
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 |
|
29-08-2008, 09:58 AM | #10 | |
Đệ tử 4 túi
Tham gia ngày: Aug 2008
Bài gửi: 89
: |
Trích:
Giả sử RxR = 5, RxW = 10 sau đó nếu PC gởi 11 ký tự thì RxR=RxW=5 nghĩa là ko có nhận được dữ liệu gì ah? Còn nếu PC gởi lớn hơn 11 ký tự thì ... Nên phải sử dụng 2 điều kiện: if(RxW ==(16 + RxR -1)%16) để báo trạng thái buffer tràn. Nếu muốn cho phép ghi đè dữ liệu khi tràn(xóa byte cũ nhất chưa được xử lý) hay không(byte mới nhận bị bỏ qua) thì thêm dòng xử lý sau đó. Good luck.
__________________
Quang báo RG/RGB 6/8/12/16 bits màu Phone No: 0905.034.086 Email: lmquyen@gmail.com |
|
30-08-2008, 10:18 PM | #11 |
Đệ tử 9 túi
|
Em đã làm rồi, để không bị đè dữ liệu không kịp xử lý và để nhận hàng loạt dữ liệu thì có giải pháp sau:
1.Khi setting cho RS232 trên PC thì chọn Flow Control là XON/XOFF. Và phần mềm bên dưới cũng xử lý dùng các kí tự XON/XOFF để điều khiển dòng dữ liệu từ PC truyền xuống. Khi bên PC nhận dc tín hiệu XOFF nó sẽ tự k gửi xuống nữa, khi nhận kí tự XON nó sẽ tiếp tục gửi xuống. 2. Quá trình xử lý thực hiện trong hàm ngắt, chứ không phải trong vòng lặp While trong main. Tất nhiên là biết chính xác độ dài của khối dữ liệu ví dụ là n = 20; Khai báo một mảng dữ liệu ở một bank nào đó. Code:
static bank1 unsigned char data[n]; // Khai báo ở bank 1 static bank1 unsigned char index = 0; // biến đếm Code:
//Send XOFF character if (index == n){ index = 0; // Do something with data } else { data[index] = UART_Data; index++; // increase index }; //Send XON character |
04-09-2008, 10:01 PM | #12 |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
cách của bạn haibac cung hay. nhưng khó quá, thông thường mình chỉ gởi từ pc xuống pic để xử lý thôi còn ngược lại từ pic lên pc để pc xử lý thì chưa biết cách làm.
mình cũng đang gặp vấn đề về địa chỉ eeprom của 18f4680. con này có eeprom 1k nhưng mình tìm datasheet của nó để xem địa chỉ eeprom của nó nhưng không tìm được. bạn nào biết địa chỉ eeprom của nó nằm trong khoảng nào chỉ giúp mình với. vì mình cũng cần lưu data vào eeprom. nhưng khi lưu ở địa chỉ 0xc9 đến 0x160 thì không lưu được ở các địa chỉ này mong các bạn chỉ giúp |
04-09-2008, 11:11 PM | #13 | |
Trưởng lão PIC bang
|
Trích:
Code:
CODEPAGE NAME=eedata START=0xF00000 END=0xF003FF PROTECTED Nếu tự viết hàm thì bạn chú ý mục 7 trong datasheet (Data EEPROM Memory), xem kỹ các ví dụ 7-1 và 7-2. Bạn sẽ thấy là truy xuất vùng nhớ EEPROM bằng cách bật bit EPGD của thanh ghi EECON1, còn địa chỉ thì chỉ có 10 bit, bắt đầu từ 0x0000 và kết thúc tại 0x03FF. 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 thay đổi nội dung bởi: namqn, 04-09-2008 lúc 11:22 PM. |
|
05-09-2008, 10:05 AM | #14 |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
cảm ơn anh nam đã giúp đỡ.
|
10-09-2008, 10:46 PM | #15 |
Đệ tử 6 túi
Tham gia ngày: Jul 2007
Bài gửi: 154
: |
các anh giúp eeprom với.
bài này em gởi từ pc xuống nhiều chuỗi dũa liệu khác nhau. khi gởi chuổi đầu tiên thì data viết vào và đọc ra cho chuôi đầu là đúng. khi gởi tiếp chuổi thứ 2 thì chuổi data của chuổi thứ 2 đọc ra cũng đúng nhưng chuỗi 1 đọc ra lại sai khi gởi chuỗi 3 thì chuối 3 đọc ra đúng còn chuỗi 1 và 2 đọc ra sai. cứ tiếp tục như vậy. chuỗi vừa gởi xuống thì đọc đúng còn các chuỗi khác thì bị sai. trong khi khoảng cách địa chỉ giữa các chuỗi lớn hơn data gởi xuống tôi không rỏ vì sao nữa. ai biết chỉ giúp với. Code:
#include<18F4580.h> #fuses NOLVP,NOWDT,PUT,hs,NOPROTECT,NOBROWNOUT #device 18f4680*=16 ADC=10 high_ints=true #use delay(clock=20000000) #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) #use fast_io(a) #byte porta=0x05 #use fast_io(b) #byte portb=0x06 #use fast_io(c) #byte portc=0x07 #use fast_io(d) #byte portd=0x08 #use fast_io(e) #byte porte=0x09 #define ch1 0x0005 // #define ch2 0x00a5 // khoang cach 160 byte #define ch3 0x0145 #define ch4 0x01e5 #define ch5 0x0285 //====================================================== int8 ram[150]; int8 count = 0; int8 tam,l; //============================================================================== void giao_tiep(); void viet_eeprom(); #INT_EEPROM FAST void viet_eeprom() { int8 ma,j; ma = ram[0]; // mã xác định chuỗi printf(" %u",ma); switch(ma) { case 1: for(j=0;j<139;j++) { write_eeprom(ch1+j,ram[j]); printf(" %u",ram[j]); } break; case 2: for(j=0;j<139;j++) { write_eeprom(ch2+j,ram[j]); printf(" %u",ram[j]); } break; case 3: for(j=0;j<139;j++) { write_eeprom(ch3+j,ram[j]); printf(" %u",ram[j]); } break; case 4: for(j=0;j<139;j++) { write_eeprom(ch4+j,ram[j]); printf(" %u",ram[j]); } break; case 5: for(j=0;j<139;j++) { write_eeprom(ch5+j,ram[j]); printf(" %u",ram[j]); } break; /// printf(" %u",read_eeprom(ch5+j)); dùng vẫn sai } } #INT_RDA void giao_tiep() // doc pc xuong ram roi do vao eeprom { int8 c,i; c = getc(); //-------------------------------- if(c!=250) //1 byte dau tien dung de chon ma chuoi { ram[count] = count; count++; } else { count=0; viet_eeprom(); printf("ok"); } } //////////////////////////////////////////////// void main() { set_tris_b(0); set_tris_a(0); set_tris_c(0x80); set_tris_e(0); set_tris_d(0); enable_interrupts(INT_eeprom); enable_interrupts(INT_RDA); enable_interrupts(global); while(true) { printf("ch1 "); for(l=0;l<139;l++) { tam = read_eeprom(ch1+l); delay_ms(5); printf("/%u",tam); } delay_ms(3000); printf("ch2 "); for(l=0;l<139;l++) { tam = read_eeprom(ch2+l); printf("/%u",tam); } delay_ms(1000); printf("ch3 "); for(l=0;l<139;l++) { tam = read_eeprom(ch3+l); printf("/%u",tam); } delay_ms(1000); printf("ch4 "); for(l=0;l<139;l++) { tam = read_eeprom(ch4+l); printf("/%u",tam); } delay_ms(1000); printf("ch5 "); for(l=0;l<139;l++) { tam = read_eeprom(ch5+l); printf("/%u",tam); } delay_ms(1000); } } thay đổi nội dung bởi: namqn, 11-09-2008 lúc 04:53 PM. |
|
|