Hướng dẫn TUT UART PIC16F887

#1
UART TUTORIAL

Gửi đến: Cộng đồng Cơ Điện Tử Việt Nam (codientu.org)
upload_2013-11-16_13-38-22.png

Người gửi: Trịnh Quang (XxẾchCốmxX) quangtvse02100@fpt.edu.vn

Nội dung: Cơ bản kết nối UART PIC 16F887

Tóm tắt:

Tài liệu được thực hiện trong thời gian ngắn, có gì sai hoặc thiếu sót mong mọi người chỉ giáo. Tài liệu được tham khảo từ anh, thầy ManhPD1.
1. Thế nào là giao tiếp UART, giao tiếp UART.

UART là viết tắt của Universal Asynchronous Receiver – Transmitter. Thường là một mạch tích hợp được sử dụng trong việc truyền dẫn dữ liệu nối tiếp giữa máy tính và các thiết bị ngoại vi. Rất nhiều vi điều khiển hiện nay đã được tích hợp UART, vì vấn đề tốc độ và độ điện dụng của UART không thể so sánh với các giao tiếp mới hiện nay nên các dòng PC & Laptop đời mới không còn tích hợp cổng UART.

Như các bạn đã biết giao tiếp SPI và I2C có 1 dây truyền dữ liệu và 1 dây được sử dụng để truyền xung clock (SCL) để đồng bộ trong giao tiếp. Với UART thì không có dây SCL, vấn đề được giải quyết khi mà việc truyền UART được dùng giữa 2 vi xử lý với nhau, đồng nghĩa với việc mỗi vi xử lý có thể tự tạo ra xung clock cho chính nó xử dụng.

Để bắt đầu cho việc truyền dữ liệu bằng UART, một START bit được gửi đi, sau đó là các bit dữ liệu và kết thúc quá trình truyền là STOP bit.
upload_2013-11-16_13-38-46.png

Như hình các bạn có thể thấy. Khi ở trạng thái chờ mức điện thế ở mức 1 (high). Khi bắt đầu truyền START bit sẻ chuyển từ 1 xuống 0 để báo hiệu cho bộ nhận là quá trình truyền dữ liệu sắp xảy ra. Sau START bit là đến các bit dữ liệu D0-D7 (Theo hình vẽ các bit này có thể ở mức High or Low tùy theo dữ liệu). Sau khi truyền hết dữ liệu thì đến Bit Parity để bộ nhận kiểm tra tính đúng đắn của dữ liệu truyền (vấn đề này mình sẽ giải thích rõ hơn trong tài liệu CRC trong thời gian tới). Cuối cùng là STOP bit là 1 báo cho thiết bị rằng các bit đã được gửi xong. Thiết bị nhận sẽ tiến hành kiểm tra khung truyền nhằm đảm báo tính đúng đắn của dữ liệu.

Các thông số cơ bản trong truyền nhận UART:

· Baund rate (tốc độ baund ): Khoảng thời gian dành cho 1 bit được truyền. Phải được cài đặt giống nhau ở gửi và nhận.

· Frame (khung truyền ): Khung truyền quy định về số bit trong mỗi lần truyền.

· Start bit: là bit đầu tiên được truyền trong 1 Frame. Báo hiệu cho thiết bị nhận có một gói dữ liệu sắp đc truyền đến. Bit bắt buộc.

· Data: dữ liệu cần truyền. Bit có trọng số nhỏ nhất LSB được truyền trước sau đó đến bit MSB.

· Parity bit: kiểm tra dữ liệu truyền có đúng không.

· Stop bit: là 1 hoặc các bit báo cho thiết bị rằng các bit đã được gửi xong. Thiết bị nhận sẽ tiến hành kiểm tra khung truyền nhằm đảm bảo tính đúng đắn của dữ liệu. Bit bắt buộc

2. Tổng quan về truyền nhận dữ liệu bằng UART trong PIC16F887

Truyền
Sơ đồ khối bộ truyền UART:

upload_2013-11-16_13-39-4.png


Nguyên tắc hoạt động:

1. Dữ liệu cần truyền được đặt vào thanh ghi TXREG, baund rate được tạo ra, khi TXEN gán bằng 1 dữ liệu từ thanh ghi TXREG đưa vào thanh ghi TSR đồng thời baund rate tác động đến TSR, đẩy dữ liệu cần truyền ra bộ đệm sau đó xuất ra chân TX.

2. Bit TXIF dùng để báo trạng thái trong thanh ghi TXREG, nếu có dữ liệu trong TXREG thì TXIF = 1. Nếu dữ liệu được truyền xuống thanh TSR thì TXIF = 0. Tương tự bit TRMT dùng để báo trạng thái thanh ghi TSR.

Như vậy các bước cho quá trình gửi dữ liệu bao gồm:

1. Khởi tạo baund rate: ở thanh ghi SPBRG
Cho phép quá trình truyền thông không đồng bộ bằng cách thiết lập SPEN = 1; SYNC = 0;

2. Cho phép truyền dữ liệu bằng cách thiết lập bit TXEN = 1;

3. Khi cần truyền dữ liệu thì cần set dữ liệu đó lên TXREG.

Thanh ghi quy định chế độ truyền.
upload_2013-11-16_13-39-28.png

CSRC:

TX9: Cho phép truyền nhận chế độ 9 bit

TX9 = 1; // Hoạt động với chế độ 9 bit.
TX9 = 0; // Hoạt động với chế độ 8 bit.
TXEN: Cho phép truyền UART
TXEN = 1; // Cho phép
TXEN = 0; // Không cho phép
SYNC: Cho phép chế độ đồng bộ
SYNC = 1; // Truyền chế độ đồng bộ.
SYNC = 0; // Truyền chế độ bất đồng bộ.
BRGH: Chọn chế độ baund rate
BRGH = 1; // Tốc độ cao (bất đồng bộ).
BRGH = 0; // Tốc độ thấp (bất đồng bộ).
TRMT: Trạng thái thanh ghi truyền.
TRMT = 1; // Thanh ghi TSR trống
TRMT = 0; // Thanh ghi TSR có dữ liệu.
TX9D: Dữ liệu bit thứ 9 trong chế độ truyền 9 bit.
 
Sửa lần cuối:
#2
Nhận

Sơ đồ khối bộ nhận UART:

upload_2013-11-16_13-43-18.png


Nguyên tắc hoạt động:

Khi có dữ liệu được truyền đến chân RX và bit SPEN được cho phép thì dữ liệu sẽ được đồng bộ với khối tạo xung, vì baund rate giữa 2 khối bằng nhau nên xung baund rate mang từng bit vào thanh ghi RSR, khi một farm được truyền hoàn tất (xuất hiện bit stop) thì dữ liệu được truyền xuống thanh ghi RCREG, bit thứ 9 được truyền xuống RX9D, nếu có lỗi thì các bit OERR, FERR dùng để thông báo. Quá trình nhận cũng tạo ra ngắt RCIF = 1, bằng cách thiết lập bit RCIE = 1 mỗi khi có dữ liệu truyền đến thì sẽ sinh ra ngắt và PIC sẽ tạm dừng chương trình hiện thời để xử lý dữ liệu vừa nhận được.

Như vậy các bước cho quá trình nhận dữ liệu bao gồm:


1. Khởi tạo baund rate: ở thanh ghi SPBRG
Cho phép quá trình truyền thông không đồng bộ bằng cách thiết lập SPEN = 1; SYNC = 0;
2. Cho phép ngắt quá trình nhận dữ liệu CREN = 1;
3. Cho phép ngắt toàn cục: CIE = 1; PEIE = 1;
4. Xử lý các phần khác của chương trình khi có ngắt xảy ra thì xử lý dữ liệu.


Thanh ghi quy định chế độ nhận.

upload_2013-11-16_13-43-31.png


SPEN: Khởi tạo cổng nối tiếp
SPEN = 1; // Cho phép cổng nối tiếp
SPEN = 0; // Không cho phép​

RX9: Cho phép nhận 9bit
RX9 = 1; // Cho phép nhận 9bit
RX9 = 0; // Nhan 8bit​

CREN: Cho phép nhận liên tục
CREN = 1; // Cho phép
CREN = 0; // Không cho phép​

ADDEN: Bit cho phép phát hiện địa chỉ (sử dụng ở chế độ truyền nhận bất đồng bộ 9 bit )
ADDEN = 1; // Cho phép phát hiện địa chỉ , cho phép ngắt và tải bộ đệm nhận khi RSR<8> được set.
ADDEN = 0; // Không cho phép phát hiện địa chỉ , tất cả byte được nhận và bit thứ 9 dùng làm bit parity.​

FERR: Bit báo lỗi frame
FERR == 1; // Có lỗi.
FERR == 0; // Không có lỗi.​

OERR: Lỗi OVERRUN
OEER == 1; // Có lỗi
OEER == 0; // Không lỗi​

RX9D: Lưu dữ liệu nhân của bit thứ 9

Thanh ghi TXREG: Dùng để chứa dữ liệu truyền đi.
Thanh ghi RCREG: Dùng để lưu dữ liệu từ ngoài vào.
Thanh ghi SPBRG: Thiết lập baud rate của PIC


3. BaudRate và Công thức tính Baud Rate.

Như mình đã nêu trên, UART khác với I2C ở điểm là nó không có dây CLK. Vậy để 2 thiết bị truyền và nhận dữ liệu hiểu được độ dài của mỗi bit tín hiệu để gửi và nhận chính xác tín hiệu thì ta cần phải thiết lập được độ dài của bit tín hiệu. Ta có thể hiểu nó là baund rate.

Công thức tính:

upload_2013-11-16_13-43-50.png


Các bạn có thể tìm hiểu rõ hơn ở Datasheet của PIC mục EUSART Baud Rate Generator. Mình xin phép không đi sâu vào vấn đề này. Phần code thư viện mình đính kèm có sẵn code tính baund rate. Các bạn chỉ cần khai báo đúng tần số thạch anh mình dùng. Nó sẽ tính ra baund rate giúp các bạn. Hoặc các bạn có thể dùng tools PicBaud mình kiếm được ở trên mạng để tính thuận tiện. Mình gửi file đính kèm.

upload_2013-11-16_13-44-10.png
 
Sửa lần cuối:
#3
Ví dụ giao tiếp UART PIC vs PIC
Mô phỏng:

upload_2013-11-16_13-45-17.png


Ý tưởng: Bản sẽ sử dụng 2 con PIC. Một con chịu trách nhiệm nhận lệnh bật hoặc tắt đèn bất kì (mình gọi Master) sau đó gửi lệnh đó qua cho con PIC thứ 2 (mình gọi là Slave) bằng UART, Slave sau khi nhận được lệnh sẽ bật tắt đèn theo yêu cầu từ Master. Slave và Master có tần số thạch anh khác nhau.

Code for Master:

upload_2013-11-16_13-45-39.png


Code for Slave:

upload_2013-11-16_13-45-54.png


Lưu ý: Các bạn cần phải chỉnh lại các thông số trong 2 file thư viện uart.c và uart.h để 2 pic có thể hiểu nhau.
File thư viện và code mình đính kèm.
 

Đính kèm

#4
Project mấu (Mình sẽ up sau) Có lẽ còn comment code và chỉnh sửa code
Sơ lược qua.
Project làm đồng hồ thời gian thực kết nối với PC qua UART.
PC sẽ gửi lệnh set thời gian cho PIC hoạt động và hiển thị Time trên PIC (code bằng C#)
PIC nhận lệnh từ PC xuống và set Time để chạy tiếp.

Phần mềm PC có chức năng tự nhận cổng COM đúng thiết bị. Tự động kết nối lại khi mất kết nối

Mình có comment hơi sơ sài. Có gì các bạn cứ đăng câu hỏi:
Đầu tiên là phải có 1 chương trình để tạo cổng COM ảo. (Ví dụ: VSPE hay Virual Serial Port Driver)
Tạo 2 cổng COM ảo kết nối với nhau theo kiểu pair
Mở file Mach.DSN đổi Cổng của port ảo thành 1 trong 2 cổng bạn mới tạo.
Mở phần mềm code cho PC lên rồi bấm Open thôi :) auto nhận port :)
2013-11-17_121922.jpg


Giao diện phần mềm PC
2013-11-17_121948.jpg


Phần mềm trên PC mình ko chau chuốt cho lắm vì cái vụ thầy thách đố là cái auto nhận port làm mình hơi mất thời gian.

Do thời gian code ngắn nên đôi khi phần mềm trên PC còn xảy ra lỗi (chưa ngồi đặt try catch hay test gì cả ) nên có gì các bạn thông cảm.

Điểm bài này của mình là 9.5
Thầy thách làm đc auto nhận port thì đc 10. Thế mà 9.5 :-s:-s:-s

Quên chút: HITECH dùng phiên bản 9.83 và phần mềm PC sử dụng visual 2013 + .Net 3.5
 

Đính kèm

Sửa lần cuối:

mta_cdt

Super Moderator
Thành viên BQT
#7
Rất cảm ơn bạn 1 bài viết rất ý nghĩa.
 
#8
Bạn có thể giúp mình 1 chút về ngắt RS232 trên PC mình viết bằng phần mềm Visual C#... mình tạo timer trễ 50ms để nhận cũng được nhưng như vậy thì k được hay, nếu có ngắt nhận thì ngon
 
#9
Bạn có thể giúp mình 1 chút về ngắt RS232 trên PC mình viết bằng phần mềm Visual C#... mình tạo timer trễ 50ms để nhận cũng được nhưng như vậy thì k được hay, nếu có ngắt nhận thì ngon
Bạn xem code project của mình đấy. Thử ngâm cứu xem. Nếu không được thì inbox mình
Mình hướng dẫn cho
 

Quảng cáo Google