Lập trình C cho hệ thống nhúng (P5- Serial Interface trong V850E)
Bài đăng này đã không được cập nhật trong 3 năm
1.Giới thiệu về UART
Bài viết này sẽ giới thiệu cho các bạn về các khái niệm về truyền thông nối tiếp UART và cách sử dụng truyền thông nối tiếp trên V850.
Định nghĩa
Thuật ngữ USART trong tiếng anh là viết tắt của cụm từ: Universal Synchronous & Asynchronous serial Reveiver and Transmitter, nghĩa là bộ truyền nhận nối tiếp đồng bộ và không đồng bộ. Cần chú ý rằng khái niệm USART (hay UART nếu chỉ nói đến bộ truyền nhận không đồng bộ) thường để chỉ thiết bị phần cứng (device, hardware), không phải chỉ một chuẩn giao tiếp.
Data Frame
Một ví dụ về một data frame gồm 8-bit data , start bit,LSB first , parity bit , 1 stop bit
Baud rate (tốc độ Baud)
Bạn thấy rằng để việc truyền và nhận không đồng bộ xảy ra thành công thì các thiết bị tham gia phải thống nhất nhau về khoảng thời dành cho 1 bit truyền, hay nói cách khác tốc độ truyền phải được cài đặt như nhau trước, tốc độ này gọi là tốc độ Baud. Theo định nghĩa, tốc độ baud là số bit truyền trong 1 giây. Ví dụ nếu tốc độ baud được đặt là 19200 thì thời gian dành cho 1 bit truyền là 1/19200 ~ 52.083us
Start bit
Start là bit đầu tiên được truyền trong một frame truyền, bit này có chức năng báo cho thiết bị nhận biết rằng có một gói dữ liệu sắp được truyền tới. Ở module USART trong AVR, đường truyền luôn ở trạng thái cao khi nghỉ (Idle), nếu một chip AVR muốn thực hiện việc truyền dữ liệu nó sẽ gởi một bit start bằng cách đường truyền xuống mức 0. start là bit bắt buộc phải có trong khung truyền.
Data
data hay dữ liệu cần truyền là thông tin chính mà chúng ta cần gởi và nhận. Data không nhất thiết phải là gói 8 bit, với AVR bạn có thể quy định số lượng bit của data là 5, 6, 7, 8 hoặc 9 (tương tự cho hầu hết các thiết bị hỗ trợ UART khác). Trong truyền thông nối tiếp UART, bit có ảnh hưởng nhỏ nhất (LSB – Least Significant Bit, bit bên phải) của data sẽ được truyền trước và cuối cùng là bit có ảnh hưởng lớn nhất (MSB – Most Significant Bit, bit bên trái).
Parity bit
parity là bit dùng kiểm tra dữ liệu truyền đúng không (một cách tương đối). Có 2 loại parity là parity chẵn (even parity) và parity lẻ (odd parity). Parity chẵn nghĩa là số lượng số 1 trong dữ liệu bao gồm bit parity luôn là số chẵn. Ngược lại tổng số lượng các số 1 trong parity lẻ luôn là số lẻ. Việc một tính chẵn lẽ cho một parity sẽ do VĐK thự hiện. Parity bit không phải là bit bắt buộc và vì thế chúng ta có thể loại bit này khỏi khung truyền .
Stop bits
stop bits là một hoặc các bit báo cho thiết bị nhận rằng một gói dữ liệu đã được gởi xong. Sau khi nhận được stop bits, thiết bị nhận sẽ tiến hành kiểm tra khung truyền để đảm bảo tính chính xác của dữ liệu. Stop bits là các bits bắt buộc xuất hiện trong khung truyền, trong AVR USART có thể là 1 hoặc 2 bits (Trong các thiết bị khác Stop bits có thể là 2.5 bits).
2. Sử dụng I2C với micro controller V850
Để có thể hiểu được cách sử dụng UART trong VĐK V850 , chúng ta sẽ tham khảo một đoạn chương trình ngắn về truyền thông UART liên tục sau đây.Và dĩ nhiên trong code sẽ có comment về ý nghĩa của mỗi dòng nhưng để hiểu rõ được hơn hết thì không có cách nào khác là tham khảo manual cho VĐK đó.
Functions khởi tạo cho khối UART
Trong V850 có 2 khối điều khiển truyền thông nối tiếp UART : UARTA và UARTB.Chúng ta sẽ sử dụng khối UARTA trong lần này. *Tiến hành khởi tạo các port để thiết lập các chân truyền nhận cho UARTA
/*───────────────────────────────────
* Uarta_Port_Set Function
* ───────────────────────────────────
*/
void uarta_port_set(void)
{
/* Set alternate-function pin to UARTA I/O pin. */
/* Set TXDA0 output and RXDA0 input. */
PFC4 = 0x03;
PFCE4 = 0x00;
PMC4 = 0x03; /* bit 1:TXDA0 receive data output */
/* 1: TXDA0 output, 0: I/O port */
/* bit 0:RXDA0 transmit data input */
/* 1: RXDA0 input, 0: I/O port */
return;
}
Tiếp theo là khởi tạo các giá trị thiết lập cần thiết cho việc truyền thông UART như baud rate, data length , stopbits.. bằng thanh ghi thiết lập chức năng UARTA0
/*───────────────────────────────────
* Uarta_Set Function
* ───────────────────────────────────
*/
void uarta_set(void)
{
/* Baud rate setting: 9600 bps */
UA0CTL1 = 0x03; /* Base clock (fuclk) selection: fxx/16 */
UA0CTL2 = 0xD0; /* UARTA0 baud rate (serial transfer speed) clock selection */
/* I/O setting of TADA0 and RXDA0 pins */
/* Transfer data normal output, transfer data normal input */
UA0OPT0 = 0x14; /* bit 1: Transfer data output method */
/* bit 0: Transfer data input method */
/* UARTA serial operation control register */
/* UARTA0 operation enabled, MSB first, odd parity, data length: 8 bits, stop bit: 1 */
UA0CTL0 = 0x8A; /* bit 7: UARTA operation control */
/* 1: UARTA operation enabled, 0: UARTA operation disabled */
/* bit 6: Transmit operation control */
/* 1: Transmit operation enabled, 0: Transmit operation disabled */
/* bit 5: Receive operation control */
/* 1: Receive operation enabled, 0: Receive operation disabled */
/* bit 4: Transfer direction selection */
/* 1: LSB transfer first, 0: MSB transfer first */
/* bit 3, bit 2: Parity selection during transmission or reception */
/* 11: Output even parity and check as even parity, 10: Output odd parity and check as odd parity */
/* 01: Output 0 parity and receive as 0 parity, 00: Parity not output and receive without parity */
/* bit 1: Specify data character length of one-frame transmit/receive data. */
/* 1: 8 bits, 0: 7 bits */
/* bit 0: Specify stop bit length of transmit data. */
/* 1: 2 bits, 0: 1 bit */
return;
}
Function bắt đầu hoạt động của khối UART
Những thiết lập ở phần khởi tạo trên sẽ giúp cho chúng ta định hình được khổi UART sẽ hoạt động dựa trên những thông số nào.Nhưng nếu như chúng ta chưa cho phép khối UART hoạt động thì nó sẽ vẫn chưa hoạt động. Để hoạt động được chúng ta phải cho phép việc truyền nhận cũng chính là cho phép các ngắt của UART hoạt động
/*───────────────────────────────────
* Uarta_Start Function
* ───────────────────────────────────
*/
void uarta_start(void)
{
UA0TXE = 1; /* Transmit operation enabled */
UA0RXE = 1; /* Receive operation enabled */
/* Operation is enabled at least 2 x fuclk (base clock) after setting UA0TXE or UA0RXE to 1. */
/* A wait time of 2 x fuclk (base clock) or longer is required at this point. */
UA0TX = buf_tx[0]; /* Operation starts when the buf_tx value is written to UA0TX. */
return;
}
Xứ lý data truyền và nhận trong ngắt
Ngắt truyền dữ liệu : ngắt này sẽ hoạt động khi có một byte data được set vào thanh ghi truyền UA0TX, để tiến hành truyền liên tiếp thì chúng ta sẽ set lần lượt data UA0TX.Khi byte được truyền xong thì byte sau mới có thể tiến hành truyền được.
/*───────────────────────────────────
* Interrupt Function
* ───────────────────────────────────
*/
__interrupt
void uarta_int_send(void)
{
if(count_tx<TX_SIZE){
count_tx++; /* Transmit count increment */
UA0TX = buf_tx[count_tx]; /* Write transmit data to UATX */
}else{
count_tx++; /* Transmit count increment */
}
}
Ngắt nhận dữ liệu : ngắt này sẽ hoạt động khi có data được nhận về ở pin RXDA0 của VĐK.Dữ liệu từng byte nhận được sẽ được lấy từ thanh ghi nhận UA0RX và set lần lượt vào một mảng để sử dụng.
/*───────────────────────────────────
* Interrupt Function
* ───────────────────────────────────
*/
__interrupt
void uarta_int_receive(void)
{
buf_rx[count_rx] =UA0RX ; /* Store receive result register value to variable. */
count_rx++; /* Receive count increment */
}
Như vậy chúng ta đã tạp ra được tất cả những function cần thiết để điều khiển, truyền nhận data trong khối UART.Và sẽ nhiên chúng ta sẽ cần một main program để kết nối các function lại với nhau, và main program này như thế nào thì sẽ tùy mục đích sử dụng của mỗi dev cũng như của thiết bị.Hy vọng những thông tin trên hữu ích với các bạn. (Phần lý thuyêt chung tham khảo wiki và một số website khác)
All rights reserved