Ðăng Nhập

View Full Version : Điều khiển LED qua USB


TANDEM
07-04-2009, 11:23 AM
Nay đệ muốn điều khiển 10 LED thông qua cổng USB theo kiểu: trên màn hình máy tính có giao diện, sau khi qua cổng USB thì có PIC P16F877A viết bởi CCS. Vấn đề này không mới, song bản thân chưa có nhiều hiểu biết sâu sắc. Vì vậy, muốn tham khảo các sư huynh:
Mô hình thực hiện vấn đề này như thế nào. Rất mong hồi âm!

namqn
07-04-2009, 06:17 PM
Nay đệ muốn điều khiển 10 LED thông qua cổng USB theo kiểu: trên màn hình máy tính có giao diện, sau khi qua cổng USB thì có PIC P16F877A viết bởi CCS. Vấn đề này không mới, song bản thân chưa có nhiều hiểu biết sâu sắc. Vì vậy, muốn tham khảo các sư huynh:
Mô hình thực hiện vấn đề này như thế nào. Rất mong hồi âm!
Đơn giản nhất là bạn dùng mô hình sau:

Máy tính <=> USB-to-serial converter <=> PIC16F877A => LED

Giao diện trên máy tính chỉ cần dùng giao tiếp RS-232 qua cổng COM ảo của bộ USB-to-serial converter. PIC16877A chỉ cần dùng giao tiếp RS-232, và xuất dữ liệu ra LED. Những vấn đề này đều đã được đề cập ở picvietnam.

Cần chú ý là PIC16F877A không hỗ trợ giao tiếp USB, do đó nếu bạn muốn dùng trực tiếp giao tiếp USB (sẽ tốn nhiều thời gian và công sức) thì nên chuyển sang một PIC18 có hỗ trợ module ngoại vi USB như PIC18Fx450, hoặc PIC18Fx455, hoặc PIC18Fx550.

Thân,

TANDEM
07-04-2009, 06:21 PM
Sao không thấy huynh nào giúp mình vậy?

TANDEM
07-04-2009, 06:28 PM
Cám ơn namqn! Quả thật “Giao diện trên máy tính chỉ cần dùng giao tiếp RS-232 qua cổng COM ảo của bộ USB-to-serial converter.” Đây là vấn đề tôi còn “Gà mờ” lắm, viết giao diện như thế nào? Bạn có thể cho tôi một đọan mẫu được không?

phungtung
07-04-2009, 06:56 PM
You must find by yourself!

lequocbao
07-04-2009, 07:08 PM
Cám ơn namqn! Quả thật “Giao diện trên máy tính chỉ cần dùng giao tiếp RS-232 qua cổng COM ảo của bộ USB-to-serial converter.” Đây là vấn đề tôi còn “Gà mờ” lắm, viết giao diện như thế nào? Bạn có thể cho tôi một đọan mẫu được không?

Bạn kiếm chổ nào gần nhà học một khóa cấp tốc về Visual Basic trước cái đã.

TANDEM
07-04-2009, 08:44 PM
Quả thật, đệ là dân ngoại đạo, cho nên lờ mờ về IT lắm, nay gặp vấn đề này cũng tự mình muốn mày mò để làm song khó quá. Bữa trước, đệ có đọc cái TUT “Hướng dẫn giao tiếp máy tính từ A đến Z”của minhtuan04 trên diễn đàn điện tử, tối về “vọc ” như hướng dẫn thì thành công liền với mô phỏng Protues. Có điều, bây giờ đệ muốn thay C# bởi Visual Basic, thay 8051 bởi PIC P16F887A. Với Pic thì đệ mới học và cũng có thể thao tác được với vài bài tập đơn giản, song với Visual Basic thì khó quá, cho nên bây giờ đệ muốn “ăn” xong phần “Máy tính <=> USB-to-serial converter” như lời trưởng lão PIC bang đã nói. Mong các huynh chỉ giúp!

namqn
07-04-2009, 09:16 PM
Quả thật, đệ là dân ngoại đạo, cho nên lờ mờ về IT lắm, nay gặp vấn đề này cũng tự mình muốn mày mò để làm song khó quá. Bữa trước, đệ có đọc cái TUT “Hướng dẫn giao tiếp máy tính từ A đến Z”của minhtuan04 trên diễn đàn điện tử, tối về “vọc ” như hướng dẫn thì thành công liền với mô phỏng Protues. Có điều, bây giờ đệ muốn thay C# bởi Visual Basic, thay 8051 bởi PIC P16F887A. Với Pic thì đệ mới học và cũng có thể thao tác được với vài bài tập đơn giản, song với Visual Basic thì khó quá, cho nên bây giờ đệ muốn “ăn” xong phần “Máy tính <=> USB-to-serial converter” như lời trưởng lão PIC bang đã nói. Mong các huynh chỉ giúp!
Bạn cứ xem cái USB-to-serial converter là một cổng COM, và đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=869

Việc ứng dụng thì thực ra khá đơn giản, chỉ cần dùng địa chỉ cổng COM ảo thay cho địa chỉ cổng COM trong hướng dẫn trên.

Về chi tiết cách tạo giao diện thì bạn có thể tham khảo thêm tutorial sau (viết cho VC++):
http://www.picvietnam.com/forum/showthread.php?t=274

Cả hai tutorial đều sử dụng MSComm control của Microsoft. Bạn có thể tham khảo cách dùng MSComm trong VB ở đây:
http://www.users.on.net/~cit/html/visual_basic_mscomm_control.html

Thân,

TANDEM
07-04-2009, 10:49 PM
Cám ơn bác namqn! Em sẽ làm theo hướng dẫn, mắc chỗ nào em sẽ thảo luận với bác sau.

TANDEM
07-04-2009, 11:26 PM
Bác namqn à! như em biết thì địa chỉ cổng COM1 là 3F8 và COM2 là 2F8. Vậy địa chỉ của cổng COM ảo là bao nhiêu vậy?

namqn
08-04-2009, 12:43 AM
Bác namqn à! như em biết thì địa chỉ cổng COM1 là 3F8 và COM2 là 2F8. Vậy địa chỉ của cổng COM ảo là bao nhiêu vậy?
Bạn không cần địa chỉ kiểu đó đâu. Cổng COM ảo thường khác với COM1 .. COM4. Bạn chỉ cần xem nó xuất hiện ở máy của bạn dưới tên nào, giả thiết là COMx, rồi bạn dùng x đó trong câu lệnh thiết lập port (tức là thay MSComm1.CommPort = 1 thành MSComm1.CommPort = x). Thế thôi.

Nếu MSComm không thể mở cổng với giá trị x quá lớn thì bạn tìm cách thiết lập địa chỉ của cổng COM ảo thành một trong các giá trị COM1 .. COM4 (vì máy tính của bạn chắc sẽ không có đến 4 cổng COM). Các bộ USB-to-serial dùng chip của FTDI chắc chắn có thể thay đổi được địa chỉ theo cách vừa nói.

Thân,

TANDEM
08-04-2009, 01:02 AM
Em hỏi thế này bác namqn ơi, khi nào thì PIC nhận ra rằng dữ liệu đã được gửi xuống từ PC vậy?

TANDEM
08-04-2009, 02:22 AM
Cám ơn bác "Trưởng lão PIC bang" hôm nay đệ mở được to con mắt hơn rồi! Chúc các bác ngủ ngon!

TANDEM
22-04-2009, 10:43 PM
Báo cáo với các sư huynh về dự án của đệ: "Điều khiển LED qua USB". Hiện nay đệ đã làm xong mô hình mà Trưởng lão PIC bang khuyến cáo 'Máy tính <=> USB-to-serial converter <=> PIC16F877A => LED', tuy nhiên đệ chỉ mới mô phỏng bằng Proteus và chưa giả lập được cổng COM. Còn một điều nữa là khi check các LED thì LED đã được check trước lại tắt, đệ không biết giải quyết thế nào? Nhờ các huynh chỉ giáo!

TANDEM
26-04-2009, 03:59 PM
Bác Nam ơi, bác giúp em cái vấn đề mà em đang mắc với!

namqn
26-04-2009, 05:04 PM
Bác Nam ơi, bác giúp em cái vấn đề mà em đang mắc với!
Tôi đã xem qua sơ đồ mô phỏng của bạn, bạn không cần dùng các cổng NOT U3 và U4. Phần mềm trên PC của bạn dùng COM5, trong khi COMPIM lại được thiết lập COM4.

Bạn chỉ mô phỏng PC <=> RS-232 <=> PIC => LED, không rõ bạn phát biểu "chưa giả lập được cổng COM" là có ý nghĩa gì.

Thân,

TANDEM
26-04-2009, 10:27 PM
Trước hết, em xin chân thành cám ơn anh Nam đã bớt chút thời gian chỉ giáo!
Vì em mô phỏng bởi Proteus nên em dùng phần mềm "Virtual Serial Port Driver" để nối 2 cổng ảo, một COM5 trên PC và một COM4 trên COMPIM. Có lẽ em phải tiến hành từng phần nhỏ một (trước hết là qua cổng COM) chính vì thế mà em muốn nói là chưa giả lập được cổng COM!!?

Nguyên văn bởi anh Nam:
Bạn đang thao tác trực tiếp trên các bit của thanh ghi PORTD, điều này có thể dẫn đến hiện tượng như bạn đã thấy, do hiệu ứng read-modify-write của các lệnh thao tác bit trong PIC.

Bạn nên dùng một thanh ghi đệm, khởi tạo giá trị của nó bởi giá trị của PORTD, sau đó cập nhật các bit của thanh ghi đệm này và ghi vào PORTD, mỗi khi bạn muốn cập nhật 1 bit nào đó của PORTD.

Việc này em chưa biết cách thực hiện trong CCS, anh có thể tỷ mỷ cho em một chút được không?
Anh thông cảm, em sẽ học cách cho vào Tag sau.

8051topic
26-04-2009, 10:33 PM
Mình có một ý nhỏ: bạn đã làm được với 8051 vậy bạn đã làm trên mạch thật chưa? Nếu rồi thì bạn thiết kế giao diện trên VB cho chạy được với 8051 đi (cho chắc phần VB là OK_bạn thiết lập trên VB là COM5 thì trên phần mềm chuyển đổi cũng là COM5).
Sau đó bạn viết code cho PIC (cho 8051 nhận bao nhiêu byte thì cho PIC nhận bấy nhiêu byte).

TANDEM
26-04-2009, 11:00 PM
Mình đã làm với PIC và tất cả đã chạy nghĩa là "PC và PIC đã bắt tay với nhau", tuy nhiên như mình nói là khi chương trình chạy thì nó không theo ý đồ của mình?

namqn
27-04-2009, 12:47 AM
Trước hết, em xin chân thành cám ơn anh Nam đã bớt chút thời gian chỉ giáo!
Vì em mô phỏng bởi Proteus nên em dùng phần mềm "Virtual Serial Port Driver" để nối 2 cổng ảo, một COM5 trên PC và một COM4 trên COMPIM. Có lẽ em phải tiến hành từng phần nhỏ một (trước hết là qua cổng COM) chính vì thế mà em muốn nói là chưa giả lập được cổng COM!!?

Trích:
"Bạn đang thao tác trực tiếp trên các bit của thanh ghi PORTD, điều này có thể dẫn đến hiện tượng như bạn đã thấy, do hiệu ứng read-modify-write của các lệnh thao tác bit trong PIC.

Bạn nên dùng một thanh ghi đệm, khởi tạo giá trị của nó bởi giá trị của PORTD, sau đó cập nhật các bit của thanh ghi đệm này và ghi vào PORTD, mỗi khi bạn muốn cập nhật 1 bit nào đó của PORTD."

Việc này em chưa biết cách thực hiện trong CCS, anh có thể tỷ mỷ cho em một chút được không?
Anh thông cảm, em sẽ học cách cho vào Tag sau.
Nếu đã dùng COMPIM của Proteus, bạn hoàn toàn có thể dùng Virtual Terminal của Proteus để mô phỏng luôn terminal, hoặc dùng một phần mềm giả lập terminal trên máy tính (như HyperTerminal chẳng hạn) để kết nối với cổng nối tiếp đã được COMPIM giả lập. Khi đó bạn thiết lập địa chỉ COMx bằng bao nhiêu cho COMPIM thì sẽ dùng đúng địa chỉ đó trong Virtual Terminal của Proteus hay phần mềm giả lập terminal.

Về phần thao tác trực tiếp trên thanh ghi PORTD, cụ thể hơn một chút nữa là như sau:
- Bạn khai báo thêm biến PORTD_img, và sửa chương trình xử lý ngắt như dưới đây:
char ch, PORTD_img;

#INT_RDA
Receive_isr()
{
if (kbhit())
{
ch = getc();

if (ch=='a') PORTD_img |= 0x01; //Bat bit RD0
if (ch=='b') PORTD_img |= 0x02; //Bat bit RD1
if (ch=='c') PORTD_img |= 0x04; //Bat bit RD2
if (ch=='d') PORTD_img |= 0x08; //Bat bit RD3
if (ch=='e') PORTD_img |= 0x10; //Bat bit RD4

if (ch=='f') PORTD_img &= 0xFE; //Tat bit RD0
if (ch=='g') PORTD_img &= 0xFD; //Tat bit RD1
if (ch=='h') PORTD_img &= 0xFB; //Tat bit RD2
if (ch=='i') PORTD_img &= 0xF7; //Tat bit RD3
if (ch=='j') PORTD_img &= 0xEF; //Tat bit RD4

PORTD = PORTD_img;
}
}

- Trong main(), bạn khởi tạo PORTD_img = 0 cùng với PORTD = 0.

- Bạn không cần dùng mấy dòng #define may1 RD0 ... #define may5 RD4

Thân,

TANDEM
27-04-2009, 08:57 AM
Cám ơn anh Nam nhiều lắm! Em sẽ thử lại và báo cáo với anh sau.

TANDEM
27-04-2009, 07:55 PM
Em đã làm theo hướng dẫn của anh (có sửa lại một chút khi set bit ở portD) và sau đó chương trình đã chạy như ý muốn. Có điều các lệnh sau em chưa hiểu:

PORTD_img |= 0x01;
...............
PORTD_img &= 0xFE;
...............
PORTD = PORTD_img;

Nếu được,anh có thể giải thích rõ cơ chế của đoạn code được không? Em xin cám ơn!

namqn
27-04-2009, 08:20 PM
Em đã làm theo hướng dẫn của anh (có sửa lại một chút khi set bit ở portD) và sau đó chương trình đã chạy như ý muốn. Có điều các lệnh sau em chưa hiểu:

PORTD_img |= 0x01;
...............
PORTD_img &= 0xFE;
...............
PORTD = PORTD_img;

Nếu được,anh có thể giải thích rõ cơ chế của đoạn code được không? Em xin cám ơn!
Cơ chế của đoạn code đã được tôi nói ở một post trước đó:
Bạn nên dùng một thanh ghi đệm, khởi tạo giá trị của nó bởi giá trị của PORTD, sau đó cập nhật các bit của thanh ghi đệm này và ghi vào PORTD, mỗi khi bạn muốn cập nhật 1 bit nào đó của PORTD.

Vì bạn chưa có khả năng chuyển ý tưởng đó thành code nên tôi mới viết giúp bạn đoạn code trên.

Vào thời điểm này, có lẽ bạn chưa cần tìm hiểu sâu hơn về hoạt động read-modify-write, nhưng nếu bạn dứt khoát phải tìm hiểu, thì vấn đề này đã được tôi và nhiều thành viên khác thảo luận cũng lâu rồi. Bạn hãy dùng công cụ "Tìm kiếm" ở thanh mênu của diễn đàn với từ khóa "read-modify-write" để tìm các bài viết liên quan.

Thân,

TANDEM
27-04-2009, 11:00 PM
Em nhờ anh Nam giải thích giúp ký hiệu "|=" và "&=" với ạ!

namqn
28-04-2009, 12:49 AM
Em nhờ anh Nam giải thích giúp ký hiệu "|=" và "&=" với ạ!
x |= y là cách viết tắt của x = x | y.

Tương tự, x &= y là cách viết tắt của x = x & y. | là phép toán OR logic, còn & là phép toán AND logic (trong trường hợp bạn chưa biết).

Đề nghị bạn đọc luồng rất ngắn sau:
http://www.picvietnam.com/forum/showthread.php?t=3151

Thân,

hoaithanh910
26-04-2010, 09:17 AM
MẤy anh Ơi cho em xin ĐoẠn cosd ĐiỀu khiỂn sÁng tẮt mỘt led vỚi. HiỆn em Đang dÙng con 8951.giao tiẾp mÁy tÍnh qua cỔng rs232.cẢm Ơn mẤy anh nhiỀu nha!

leeshin456
02-05-2010, 08:36 PM
mấy anh ơi hình như đang lạc đề thì phải!
đây là mục giao tiếp usb nếu làm như vậy thì chúng ta sẽ chẳng có được kinh nghiệm gì về giao tiếp USB cả.

chuotdientu
28-07-2010, 02:33 PM
Đoạn chương trình sau (viết bằng VB6) tớ viết để điều khiển 8 chú led đơn, dùng PIC18F4550 giao tiếp với máy tính qua USB (không phải Virtual Com), trong giao diện có kèm schematic, các bạn có thể tham khảo.

liunguyenspk
12-03-2013, 10:46 AM
sao mình dow về ko có file VB bạn ơi? share cho mình cái code mình tham khảo nhé,mình tính làm trên AVR