PDA

View Full Version : Kinh nghiệm sử dụng 2 UART trên Pic18


tienchuan
20-03-2012, 12:07 PM
Chào mọi người
E hiện đang làm Project có yêu cầu sử dụng 2 cổng UART để truyền thông thông qua sử dụng ngắt RS232, e chọn pic 18f97j60 để làm.
Yêu cầu của em là đọc dữ liệu ở UART1 rồi dùng UART2 để truyền lên máy tính ( bắt buộc phải sử dụng 2 cổng UART như vậy ạ)
Em thử test trên Hyper, gởi chuỗi giả xuống VĐK, sau cho bắt chuỗi, đẩy lên PC thì nhận được hết.
Nhưng khi test với mạch thì chỉ nhận được chuỗi duy nhất 1 lần.
Vậy cho em hỏi là lỗi này có phải do cấu hình UART sai hay có cần cấu hình gì thêm ko ạ ?
Cảm ơn mọi người đã đọc bài.
Thân chào mọi người.

longtu
20-03-2012, 03:22 PM
Chào mọi người
E hiện đang làm Project có yêu cầu sử dụng 2 cổng UART để truyền thông thông qua sử dụng ngắt RS232, e chọn pic 18f97j60 để làm.
Yêu cầu của em là đọc dữ liệu ở UART1 rồi dùng UART2 để truyền lên máy tính ( bắt buộc phải sử dụng 2 cổng UART như vậy ạ)
Em thử test trên Hyper, gởi chuỗi giả xuống VĐK, sau cho bắt chuỗi, đẩy lên PC thì nhận được hết.
Nhưng khi test với mạch thì chỉ nhận được chuỗi duy nhất 1 lần.
Vậy cho em hỏi là lỗi này có phải do cấu hình UART sai hay có cần cấu hình gì thêm ko ạ ?
Cảm ơn mọi người đã đọc bài.
Thân chào mọi người.

Chuẩn,

Việc sử dụng 2 UART trên PIC cũng đơn giãn thôi. Chuẩn xem phần Help của CCS nhé.

eman
20-03-2012, 04:06 PM
2 hay nhiều UART trên PIC dùng bình thường.
Có thể tienchuan gặp vấn đề này: HyperTerminal chỉ truyền dữ liệu ASCII 7-bit thôi.

tienchuan
20-03-2012, 05:04 PM
Chuẩn,

Việc sử dụng 2 UART trên PIC cũng đơn giãn thôi. Chuẩn xem phần Help của CCS nhé.

Chào a Longtu.
E cũng đã coi phần Help của CCS như a nói rồi mà vẫn thấy họ chỉ nói về phần config thôi a ah, e nghĩ vấn đề của e không biết có phải do xung đột ngắt UART giửa UART nhận (2) và UART gởi(0) a ?
Vì em thấy thắc mắc ở chỗ là code của e đã chạy đúng khi gởi chuỗi giả trên Hyper xuống, nhận và gởi lên PC hiển thị đúng, nhưng khi e kết nối với cảm biến thì lại chỉ gởi được chuỗi dữ liệu đầu tiên.
Thật sự mong các ACE gặp phải tình huống này như e rồi thì chỉ giáo cho e vs ạ :)
Cảm ơn a Longtu+mọi người đã đọc bài
Thân

longtu
20-03-2012, 05:07 PM
Chào a Longtu.
E cũng đã coi phần Help của CCS như a nói rồi mà vẫn thấy họ chỉ nói về phần config thôi a ah, e nghĩ vấn đề của e không biết có phải do xung đột ngắt UART giửa UART nhận (2) và UART gởi(0) a ?
Vì em thấy thắc mắc ở chỗ là code của e đã chạy đúng khi gởi chuỗi giả trên Hyper xuống, nhận và gởi lên PC hiển thị đúng, nhưng khi e kết nối với cảm biến thì lại chỉ gởi được chuỗi dữ liệu đầu tiên.
Thật sự mong các ACE gặp phải tình huống này như e rồi thì chỉ giáo cho e vs ạ :)
Cảm ơn a Longtu+mọi người đã đọc bài
Thân

Chuẩn,

Chuẩn đưa code lên đây nhé. Nhớ là chỉ trích những đoạn code liên quan thôi, dừng có chép hết tấc cả các code lên, sẽ không ai chụi nhìn code đâu.

Thân.

tienchuan
20-03-2012, 05:13 PM
2 hay nhiều UART trên PIC dùng bình thường.
Có thể tienchuan gặp vấn đề này: HyperTerminal chỉ truyền dữ liệu ASCII 7-bit thôi.

@ eman: chào bạn.
Mình dùng chương trình Terminal lấy trên dientuvietnam.net và đã chọn cấu hình 8 bit data, 1 stop, none parity như hình gởi để test thử bạn ah.
Không biết bạn có gặp lỗi này lần nào như mình chưa ? Nếu có chỉ giúp minh với nhé.
Cảm ơn bạn
Thân

tienchuan
20-03-2012, 05:21 PM
Sr a Longtu, e luần quần miết nên quên đính kềm code để minh họa ạh :D
Đây là đoạn code config UART của em:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,bits=8,stop=1,parity=n,stream=ID1) //GPRS_PORT
#use rs232(baud=4800, xmit=PIN_G1, rcv=PIN_G2,bits=8,stop=1,parity=n,stream=ID2) //GPS_PORT

Còn đây là đoạn code e sử dụng chính :

char user_str[11]="test,test,";
char gps_str[100]="";
char gps_str_send[80];
char gps_buffer[100]="";
int8 chk_gprs=0;
int8 index= 0;


#int_rda2
void ngat_gps(void)
{
char c1;
c1=fgetc(ID2);

switch(c1)
{
case '$': {
index=0;

}
break;

case 13: check_gprmc();
break;
default: {
gps_buffer[index]=c1;
index++;
}
break;
}

}

//------------------------------------------------------------------------------
void check_gprmc(void)
{
if ((gps_buffer[1]=='G')&&(gps_buffer[2]=='P')&&(gps_buffer[3]=='R')&&(gps_buffer[4]=='M')&&(gps_buffer[5]=='C'))
{
strcpy(gps_str,gps_buffer);
fprintf(ID1,gps_str);
}
else {};
}

longtu
20-03-2012, 08:25 PM
Chuẩn,

A khuyên em thế này:
- Với ngắt nói chung em nên viết chương trình để xử lý thật nhanh chóng và thoát ra khỏi ngắt ngay. Ví dụ ở code của em, em sử dụng ngắt RDA2 để nhận data từ vệ tinh qua GPS module. Data này là liên tục và tương đối dài(có thể khoảng 70 bytes). Nếu như em xử lý không nhanh chóng có thể sẽ bị mất dữ liệu hay thậm chí làm ảnh hưởng đến chương trình(ví dụ: treo chương trình ...do chưa thoát được ngắt).
- Em gọi chương trình check_gprmc(); trong ngắt RDA2 là rất không nên, vì trong chương trình này chứa lệnh: fprintf(truyền data lên PC) trong khi em vẫn chưa thoát ra ngắt RDA2(nhận data từ PC)

Thêm nữa lệnh strcpy(gps_str,gps_buffer); em cũng sữ dụng ngay trong ngắt RDA2. Em nên sự dụng này bên ngoài ngắt. Em chỉ nên xử lý dữ liệu nhận được từ PC và lưu vào bộ nhớ tạm mà thôi, không làm việc gì khác trong Ngắt.

Anh nhắc lại, việc sử dụng 2 hay nhiều ngắt UART trong PIC không có vấn đề gì hết đâu, chi đơn giãn như vi dụ minh họa trong CCS. Việc còn lại là khéo léo xử lý để chương trình chạy xuông sẻ thôi.

Thân.

tienchuan
26-09-2014, 05:40 PM
hic, bài này lâu quá mình quên cập nhựt, chắc do hồi đó lu bu sửa đồ án, h có bạn hỏi nên mình up lại phần source, chỉ tham khảo thôi chứ viết code quá dở :D
Thanks a Longtu đã hỗ trợ e nhiệt tình :)
//------------------------------------------------------------------------------
//------------------------ CHECK "CONNECT OK" STRING GPRS-----------------------
//------------------------------------------------------------------------------
#int_rda
void ngat_gprs(void)
{
char c1;
c1=fgetc(ID1);
switch(c1)
{
case 10:
{
indexx=0;
}
break;
case 13:
{
//chk_gprs=0;
check_connect();
}
break;
default:
{
connect_buffer[indexx]=c1;
indexx++;
}
break;
}
}
//------------------------------------------------------------------------------
void check_connect(void)
{
if((connect_buffer[0]=='C')&&(connect_buffer[1]=='O')&&(connect_buffer[2]=='N')
&&(connect_buffer[3]=='N')&&(connect_buffer[4]=='E')&&(connect_buffer[5]=='C')
&&(connect_buffer[6]=='T')&&(connect_buffer[8]=='O')&&(connect_buffer[9]=='K'))
{
chk_gprs=1;
indexx=0;
}
else
{
//chk_gprs=0;
//indexx=0;
}
}
//------------------------------------------------------------------------------
//------------------------- GET GPS DATA STRING -------------------------------
//------------------------------------------------------------------------------
#int_rda2
void ngat_gps(void)
{
char c2;
c2=fgetc(ID2);
switch(c2)
{
case '$':
{
index=0;
}
break;

case 13:
{
chk_gps=0;
check_gprmc();
}
break;
default:
{
gps_buffer[index]=c2;
index++;
}
break;
}
}
//------------------------------------------------------------------------------
void check_gprmc(void)
{
//disable_interrupts(int_rda2);// edit
if((gps_buffer[0]=='G')&&(gps_buffer[1]=='P')&&(gps_buffer[2]=='R')
&&(gps_buffer[3]=='M')&&(gps_buffer[4]=='C'))

{
strcpy(gps_str,gps_buffer);
chk_gps=1;
//enable_interrupts(int_rda2);// edit
index=0;
}
else
{
chk_gps=0;
//enable_interrupts(int_rda2);//edit
index=0;
};
}