前一篇《UART Explained》介绍了UART的基本信息,重点分析了UART的信号。本文摘录的文章则重点介绍了波特率(Baud Rate)相关的内容,波特率越高,传输速度越快,但实际使用时波特率是越高越好吗,多少合适?文中给出了答案,具体如下。
Although the PIC32 is an elegant and powerful microcontroller, it doesn‘t stand so tall when compared against a PC in terms of raw computing power! Sometimes it makes sense to use the feasability of the microcontroller to work as a sensor or an embedded controller of some type but still be able to communicate with a more powerful computer. Sometimes you might just want a quick visual display or a printf terminal for debugging. Whatever the reason, this tutorial will provide a basic guide to PIC32 / PC communication.
UART
The module used for such communication is the PIC‘s Universal Asynchronous Receiver/Transmitter (UART) pronounced "you-art". For those familiar with computer music, the MIDI protocol uses a UART to do its serial communication. For those familiar with the Arduino, the TX/RX pins on an Arduino are the two main UART pins. In its most basic form the UART hardware consists of a transmit (TX) line and a receive (RX) line. The software configures how fast data is sent (the baud rate) and the specifics of the protocol.
Baud Rate
Since the UART module is asynchronous, there is no external clock line like the synchronous protocols SPI or I2C. Instead, both communicating devices must have their own clock sources configured to the same frequency. As long as these clocks match one another, data should be transferred smoothly. On the PIC32, the UxBRG special function register configures this rate called the baud rate. Note that the x in UxBRG is a placeholder for the reference number of the UART that is being configured. Common baud rates include 4800, 9600, 19200, 57600, and 115200 bits/s. Different baud rates can be chosen by the PIC32 but you must always make sure both devices are very stable at the selected rate. Sometimes it‘s best to select a lower baud rate to reduce the chance of errors. Since there is no shared clock, the hardware is simpler but there is an increased chance for the clocks to be out of sync causing incorrect data to be interpreted on the receiving end. For this reason, lower baud rates like 9600 are very popular.
The equation to configure the baud rate using the UxBRG register is below:
8N1
Like with most peripherals, the configuration options can be overwhelming! We‘ll be configuring our UART to use the standard 8N1 format. 8N1 meaning that each data trasfer consists of 8 bits of data, no parity bits, and 1 stop bit.
The parity bit provides an added layer of error detection. The parity bit is generated by the transmitting unit through a calculation done with the data being sent. If the receiving unit then calculates the same parity bit from the received data, it is assumed that everything is A-O-K. If a different parity bit is calculated, an error is triggered. For example, if odd parity checking is used, the transmitting unit would add up all "1" bits from the data being sent and set the parity bit to 1 if they are odd (like 01001100) or to 0 if even (like 01001101). The receiving unit would use the same calculation and compare the received parity bit to the calculated parity bit. Note that parity checking is done in hardware by the UART unit. However, once a parity error is flagged by the hardware, the programmer must deal with the error in software. Since parity checking will only take you so far (two corrupted bits is treated as no error!), you may desire something more powerful like a Cyclic Redundancy Check (CRC) which is outside the scope of this tutorial.
The stop bit signifies the end of a data transfer. There will almost always be either one or two stop bits. If the stop bits read by the receiving unit don‘t match those expected, the receiver will assume its clock drifted out of phase and a the software must deal with this error. It is also implied that a start bit is being sent as well with each transmission. The start bit allows the clock on the receiving end to do a phase lock with the data being received. Otherwise, the receiving end might end up sampling on the data transition edges instead of right in the middle of each bit. The data received would then look like utter nonsense!
So, in an 8N1 configuration, each byte of data sent is transmitted in the form of a 10-bit frame with the addition of one start bit, one stop bit, and no parity bits.
The example below configures the PIC32‘s UART1 module to an 8N1 format with a baud rate of 19200 bits/s and enables both transmit and receive functions (in full duplex mode).
int FPb = 40000000; // peripheral bus clock frequency set at max SYSCLK int desired_baud = 19200; U1MODE = 0; // disable autobaud, TX and RX enabled only, 8N1, idle=HIGH U1STA = 0x1400; // enable TX and RX U1BRG = (FPb / (16*desired_baud)) - 1 U1MODESET = 0x8000; // enable UART1 |
Note that in the example above, we are using the standard baud mode set whenUxMODE<3> = 0. The UART clock is only able to take on specific frequencies and this bit helps determine how close the desired baud rate will be to the actual baud rate. When BRGH = 1 (i.e. UxMODE<3> = 1), high-speed mode is activated and the actual baud rate will probably be closer to the desired baud rate. However, each bit received on the UxRX pin will only be sampled once. When BRGH = 0 (i.e. UxMODE<3> = 0), multiple samples are taken on the UxRX pin to determine whether a HIGH or LOW is present. Even though the high-speed mode may have a more accurate baud rate clock, in standard-mode there is less chance to make receiving errors. See the UART reference manual section 21.6 for more information.
The following table provides a set of desired baud rates, the value you would set BRGH to for this baud rate and the error.
可以看到,实际波特率和目标波特率会有一些误差,如果通信双方的误差都有点大,那就很容易导致通信错误,所以很多串口通信的协议里都会有校验码,如GPS协议,通过数据帧的校验码可以过滤掉因传输导致的错误,避免异常。
原文中还有参考代码和调试串口的神器,具体参见: http://umassamherstm5.org/tech-tutorials/pic32-tutorials/pic32mx220-tutorials/uart-to-serial-terminal
另外,有关串口通信时序错误的详细解析,可参考:http://www.robotroom.com/Asynchronous-Serial-Communication-2.html(好似被墙,pdf当在此)
波特率计算工具:http://mspgcc.sourceforge.net/baudrate.html